Custom app-specific permissions for RBAC on AWS - amazon-web-services

Amazon Cognito provides capabilities for Role Based Access Control (RBAC) that allows an admin to either permit or deny user access to various AWS resources. However, suppose I have a serverless webapp that runs on AWS Lambda and uses Cognito for user management. My app has its own set of app-specific actions (eg add a widget, delete a wombat, update a foo). My database objects have relationships with each other (eg every wombat owns multiple foo's). I want to have record level permissions (eg this user can only delete this foo if the user owns the wombat to which this foo belongs). These are app-specific permissions. It would be a giant pain to map each of these app-specific permissions (which I can easily understand in my head as the developer of the webapp) to the underlying AWS services. Furthermore, if I ever want to switch to a different AWS service or switch to some other cloud service provider, I would have to completely redo all my permissions. It would be much better to have a way to have the app admin/designer (eg me) create my app-specific set of semantically meaningful permissions and have a service that I can query to see if the given user has a given permission for the requested action on this object. Does AWS provide such a service, or would I have to maintain my own app-specific permission/role database tables and roll my own functionality to provide this?
Any suggestions? I'm using python for the backend language and MYSQL on Amazon RDS for the DB.

Related

How to make relationship between Amazon Cognito and other microservice?

I am new to AWS and making some large application with microservice architecture. I am using Cognito user + identity pools for authorization. Organizations have branches, branches have positions, e.g Project Manager, Financial Manager, and a user belong to one of these branches and positions. Users are stored in the Cognito User Pool. I've EC2 and RDS for organization microservice and I'm going to use AWS API gateway with IAM Role-Based Access Control to communicate between microservices but how can I make a relationship between the organization and user microservices?
I was going to use Cognito custom attributes, e.g custom:branch=branchId but if I needed to get the users of this branch that would be impossible. From Cognito docs:
Custom attributes are not searchable.
Should I use DynamoDB table, for relation cognito_user_id | branch_id, or what's the better approach?
How to get single branch users, how to get single organization users and where to write this code ? AWS lambda with DynamoDB ?
If you have no restriction to add table on RDS at organization micro-service, I will say do not use dynamodb as it is an extra component and your system supports relational better than NoSQL. Besides, one more prerequisite for dynamodb is one must be aware of data access pattern.
Create Organizations and Branchs table having one-to-many relation as seperate micro-service. User will be assigned to Branch.
You should write those shared logic to lambda as a service and that lambda will be called by both org and user services. I know that will cost extra integration effort. However, it is far better than adding new service like dynamodb.

AWS - how to separate resource of each user for an AWS Service

I am opening an AWS Service (say: AWS Rekognition) for my app's users.
The problem is: when one user (ex: user1) creates a resource (such as a collection), other users (ex: user2, user3) also see the resource that was created by user1.
I have tried to use Identity Pool, and acquired Token/Identity from my backend server for my users but things are not better (my users still see the resources of each other).
What should I do to let user1 receive user1's resource only?
I have been struggling with this problem for days, but can't seem to figure out.
Regards
There are two approaches to this architecture:
Option 1: Client/Server
In this architecture, client apps (eg on a mobile device or a web-based app) make calls to an API that is hosted by your back-end application. The back-end app then verifies the request and makes calls to AWS on behalf of the user.
The user's app never receives AWS credentials. This is very secure because the back-end app can authenticate all requests and apply business logic.
Option 2: Providing AWS credentials
In this architecture, the client apps receive temporary AWS credentials that enables them to directly call AWS services (which matches the architecture you describe).
The benefit is that the app can directly access AWS services such as Amazon S3. The downside is that they you need to very tightly limit the permissions they are given to ensure they only access the desired resources.
Some services make this easy by allowing Conditions on IAM Permissions that can limit the resources that can be accessed, such as by tag or other identifier.
However, based upon Actions, Resources, and Condition Keys for Amazon Rekognition - AWS Identity and Access Management, there is no such capability for Amazon Rekognition:
Rekognition has no service-specific context keys that can be used in the Condition element of policy statements.
I think you could limit the calls by providing a Resource string in the IAM Policy, which can limit their ability to make certain calls (eg DeleteFaces) so that it is only done against a specific collection.
However, please note that list calls such as ListCollections are either permitted fully or not at all. It is not possible to limit the list of collections returned. (This is the same as most AWS Services, such as listing EC2 instances.)
Thus, when using this method of providing credentials, you should be very careful about the permissions granted to the app.

AWS: Is there a way to make an user approve my app to do things on their behalf?

I am planning on a web page that creates an instance for an user using a specific AMI. Is there any AWS method to let the user approve my web application to do this using their credentials? (i. e. getting a secret token with certain privileges)
Similar to when you let a Facebook application have access to certain information of your profile. I am looking for a way to get a token from the user signed in so that I can create an instance for them.
I want to avoid the user the pain of doing all the manual steps of going to IAM, create a new user, get the token and then upload them to my site.
I looked into AWS Cognito but this doesn't seem to be what I am looking for.
Similar to when you let a Facebook application have access to certain information of your profile.
AWS and Facebook are not similar in any sense. Facebook is a web application. AWS something entirely different.
Facebook has users, but AWS has accounts, which in turn have users... but in AWS, don't need a user's permission to do things to resources -- what you actually need is an account's permission to do things to its resources, because resources are associated with the account, not the user.
I am looking for a way to get a token from the user signed in so that I can create an instance for them.
Users sign in to the AWS console. After this, there is no such concept as a user allowing an external application doing things under the "signed in" user's auspices.
The user has to have sufficient permissions to either create sufficiently-privileged temporary IAM credentials (such as with GetSessionToken or AssumeRole from the IAM API) and hand them over to you, or create an IAM user with sufficient privilege and hand the keys to that user over to you... or you provide them with the ARN of one of your IAM users, and your customer gives your user permission to perform the actions or assume a role in your customer's account, created for the purpose.
I want to avoid the user the pain of doing all the manual steps of going to IAM, create a new user, get the token and then upload them to my site.
That can't be avoided, by design... and, in any event, whatever exactly you are planning, your model seems flawed: it would only be a naïve user who would allow you to do this. I have accounts that are allowed to launch hundreds of instances concurrently. Does it make sense that I would allow a third party to have access to credentials that could run up a huge bill for me? (If AWS trusts a set of credentials to launch instances, then it trusts them to launch instances -- all the way up to the account's instance limits).
If you want a user to be able to launch an instance from your AMI, you can simply list it on the AWS Marketplace, or you can share the AMI with the user's account, or even just make the AMI public.

Amazon Web Services Developer User Permissions

I have an Amazon Web Services account which will be used to host the backed of an app. The backend uses PHP/MySQL and will most likely use an EC2 instance and RDS. I have my own account which has access to everything. I need to create an account for a developer to put the backend on AWS but I don't want them to have access to anything except what they need. I know how to create IAM users and Groups but I don't know which permissions to grant the developer. Under Select Policy Template there is a Power User template, is that good for a developer? Has anyone done this before?
The Power User Access template in AWS Identity and Access Management (IAM) grants permission to do ANYTHING except using IAM. A user with this permission can view, create or remove any resources in your AWS account, but they could not create new users or modify any user permissions.
It is recommended that you only give people the least amount of privilege required to use AWS, so that they do not intentional nor accidentally do something unwanted. However, if you do not have enough knowledge of AWS to know what functionality is required, you will most likely need to trust the developer to configure the system for your needs.
A few tips:
Only give them access via an IAM User -- never give them your root credentials
If you don't know what permissions are required, then "Power User" is at least safer than "Administrator" since they cannot edit IAM settings
When they have completed their work, revoke their access so they cannot create any more AWS resources
Determine whether you also wish to revoke access to the EC2 instances (you'll have to do this on the instances themselves)
You may need to define some roles that will be used with Amazon EC2 -- these are defined in IAM, so the developer will not have permission to create the roles himself
Ask the developer for documentation of what he has deployed
Turn on Detailed Billing to identify what AWS charges you are receiving and check them against the documentation
Turn on CloudTrail to activate auditing of your account (it is activated per-region)
Alternatively, you could do all the AWS configuration (launching an EC2 instance, creating the database) and only let the developer login to the EC2 instance itself. That way, they would not need access to your AWS account.

How do we provide our AWS app with access to customers' resources without requiring their secret key?

I am in the early stages of writing an AWS app for our users that will run our research algorithms using their AWS resources. For example, our code will need to spin up EC2 instances running our 'worker' app, access RDS databases, and create access SQS queues. The AWS Java SDK examples (we are writing this in Java) use a AwsCredentials.properties file to store the Access Key ID and Secret Access Key, which is fine for examples, but obviously not acceptable for our users, who are would be in essence giving us access to all their resources. What is a clean way to go about running our system on their behalf? I discovered AWS Identity and Access Management (IAM) which seems to be for this purpose (I haven't got my head around it yet), esp. Cross-account access between AWS accounts. This post makes it sound straightforward:
Use the amazon IAM service to create a set of keys that only has
permission to perform the tasks that you require for your script.
http://aws.amazon.com/iam/
However, other posts (e.g., Within IAM, can I restrict a group of users to access/launch/terminate only certain EC2 AMIs or instances?) suggest there are limitations to using IAM with EC2 in particular.
Any advice would be really helpful!
The key limitation with regards to RDS and EC2 is that while you can restrict access to certain API actions there are no resource level constraints. For example with an IAM S3 policy you can restrict a user to only being able to perform certain actions on certain buckets. You can write a policy for EC2 that says that user is allowed to stop instances, but not one that says you can only stop certain instances.
Another option is for them to provide you with temporary credentials via the Security Token Service. Another variant on that is to use the new IAM roles service. With this an instance has a set of policies associated with it. You don't need to provide an AwsCredentials.proprties file because the SDK can fetch credentials from the metadata service.
Finally one last option might be consolidated billing. If the reason you are using their AWS resources is just because of the billing, then setup a new account which is billed from their account. The accounts are isolated from each other so you can't for example delete their instances by accident. Equally you can't access their RDS snapshots and things like that (access to an RDS instance via mysql (as opposed to the AWS api) would depend on the instance's security group). You can of course combine this with the previous options - they could provide you with credentials that only allow you to perform certain actions within that isolated account.