AWS has a large number of buckets that different users have access to. And there is a lambda function that selects data from s3 and gives it to the client via the Api Gateway. The client has the opportunity to specify in the api request from which bucket lambda should make a selection. But how to check that he is requesting exactly the bucket to which he has permission?
In the iam policies, I can only indicate that it can access a specific api resource, but the resource is shared by everyone. In lambda authorizer, I can't get information about the user's rights and permissions (or can I?).
Please tell me how you can solve this issue. Which way to move?
P.S. This should be the authorization of users in amazon, I can't give them my JWT with my data.
It would be your responsibility to code the authentication and permission requirements in your own code. The person making the request via API Gateway is not an IAM User, so AWS does not recognise them and cannot grant access based on the normal AWS permission model.
Your code would need to:
Recognise and authenticate the user
Determine what resources (buckets) that user is permitted to access
Only provide access to permitted resources
How to do this is your decision. You should start with a way of identifying and authenticating the user.
Related
I am confused about the use cases and advantages of STS. As per the documentation, it is to temporarily acquire a role to perform tasks within AWS which are not available for the IAM user or service. Please note that I am talking about programmatic access (NOT console access)
For example, an IAM user may not have S3 permissions. As per my understanding:
He can get temporary access key/token by contacting AWS STS and get access key and secret for S3.
With those temporary credentials, he can access S3.
My questions are:
To get temporary credentials from AWS STS, he still need his existing access token (permanent) and secret, right?
If his existing access token and secret are leaked, an attacker can still use it to first get temporary credentials from STS and then access S3, right? I understand that the attacker won't be able to directly access S3 using his permanent access token and secret.
I am trying to wrap my head around its correct use cases. I know that I'm confused, but maybe I'm thinking in loops.
Thanks in advance.
They don't so much "contact AWS STS and get access key and secret for S3". Rather, they call AssumeRole() on an IAM Role that has permission to access Amazon S3. Then, using the temporary credentials that are returned, they can access S3.
Your confusion seems to be mostly around the use-case for IAM Roles. I like to explain it by way of a story...
I am a Fire Warden in my office at work. If the Fire Alarm activates, I go to a cupboard, put on a red helmet, then walk around the office and direct people to the stairwell. Since the alarm is sounding and I'm wearing a red hat, people (mostly) do what I tell them. However, if it was a normal day with no alarm sounding and I wasn't wearing the red hat, and I asked them to exit the office via the stairwell, they would likely look at me strangely and ignore my request. The difference is that I assumed the role of a Fire Warden, which gave me extra permissions.
So, as a normal person, I can't order people out of the office. However, once I assume the role, I have extra permissions.
This is a good practice for IT systems, too. The Systems Administrator in your company probably has permissions in your AWS Account to do anything. However, it would be a bad practice for them to use an account with such powers on a day-to-day basis. Instead, their IAM User account should just have normal permissions but, if they want to do Admin-type stuff, they have the ability to Assume an Admin Role and then do powerful stuff. When they're finished, they should exit the role and keep being a normal user. This is much 'safer', since they can't accidentally do something powerful when they are a 'normal user'.
Amazon Security Token Service (STS) is also used to provide permissions to software running on Amazon EC2 instances. In this case, an IAM Role is assigned to the EC2 instance and the EC2 service 'assumes' the role on behalf of the instance. It then provides the temporary credentials via the EC2 Instance Metadata service. In this example, there was no IAM User that assumed the role. Instead, the EC2 service assumed it on behalf of the instance.
STS can also provide cross-account permissions. For example, an IAM User in Account A could call AssumeRole() on an IAM Role in Account B. If they have permission to do this, then they will be given temporary credentials that are associated with Account B. This is required because credentials from one Account can never be used to manage resources in another Account.
There are other reasons for using temporary credentials too, such as using MFA tokens, federated logins where there are no IAM Users, and reducing your own set of permissions.
I will try to extend and generalise the first answer. The example with the Fire Warden is good to understand, but I feel it needs some extension.
Generally the AWS STS is able to return role credentials based on other identity or role credentials (aws or other identity provider).
The original credentials can be either AWS credentials from the same account, another account, federated token (e. g. supported social networks) or even a custom identity broker.
see https://docs.aws.amazon.com/cli/latest/reference/sts/index.html
Common use cases:
privilege elevation - this is already mentioned, AssumeRole allows to become another role within the same or different aws account
authorization to aws resources for identities authenticated a other way (AD, SAML, OIDC,..), see services AssumeRoleWithSAML or AssumeRoleWithWebIdentity.
authorization to aws resources with custom authorization, see GetFederationToken.
To get temporary credentials from AWS STS, he still need his existing access token (permanent) and secret, right?
By default AssumeRole, the user needs to be authenticated and having permission to assume the role.
If his existing access token and secret are leaked, an attacker can still use it to first get temporary credentials from STS and then access S3, right?
yes
I understand that the attacker won't be able to directly access S3 using his permanent access token and secret
if you configure the S3 or IAM permissions that way
We have an external application resides outside of Amazon network and it needs to access our SQS and send message there, in order for our AWS resource to recognize the request from that application it needs to sign its request with the credentials of the IAM role we created, I'm wondering what is the best way for that external application to retrieve temp credentials from us? I have tried to implement it using Amazon Cognito but it looks like Cognito fits more in scenarios like user sign-up and sign-in with an User Interface, anyone has any suggestions? Thanks in advance.
To be able to obtain temporary credentials, you need a form of permanent credentials that can access (or generate) the temporary credentials.
Given your situation, you might consider creating an IAM User in your account and giving those credentials to the third-party. Grant the appropriate permissions to those credentials and they can use them directly with Amazon SQS.
Or, if you'd rather not give IAM credentials to third-parties, you could ask them to create an AWS account and an IAM User. You could then grant their IAM user access to the Amazon SQS queue.
Another option is that the third-party could access an application or API that you provide. Once they authenticate, you can provide temporary credentials created with the Security Token Service. Cognito would be an option for performing this authentication and it can also provide credentials for an associated IAM Role, thus giving them access to the Amazon SQS queue.
How can I let another user access to my AWS S3 bucket without having to create an IAM role for it and sending the key/secret.
I want the third-party to decide the credentials for himself.
Is this even possible?
Basically I'm searching for something similar to OAuth for S3
By default, Amazon S3 buckets are private.
Access to objects can be granted in several ways:
A Bucket Policy can make a bucket, or part of a bucket, publicly accessible (not applicable for your use-case)
The Access Control List (ACL) on an object can make it publicly accessible (not applicable for your use-case)
IAM Users can be granted permissions on an Amazon S3 bucket (but IAM Users should only be used for your staff, not for application users)
IAM Roles can be temporarily assumed, but first require authentication (more on this below)
Pre-Signed URLs can be generated to provide time-limited access to Amazon S3 objects
For your use-case, the most applicable approach would be:
Users authenticate to your application. This could use Amazon Cognito, or whatever authentication method you wish to use.
When a user wishes to access a private object, your application determines whether they are entitled to such access (done via your own code).
If they are permitted access, the application should generate a pre-signed URL. This URL can be included in tags like <a> and <img>.
When the user accesses the URL, they will be able to access the object directly from Amazon S3.
Once the expiry time passes, the pre-signed URL no longer works.
So, you are welcome to use OAuth or any other authentication method, but it is the responsibility of your application to determine whether they are entitled to access individual objects and, if so, generate and return the pre-signed URL. (It's just a couple of lines of code, no API calls required to generate it.)
See: Share an Object with Others - Amazon Simple Storage Service
Amazon Cognito has the ability to issue credentials associated with an IAM Role, and users could then use these credentials to make API calls to AWS. However, it is generic role that would be shared by many users and is not a way to grant user-specific permissions.
I am developing a web application with two mobile(Android & iOs) based applications of the same. Currently the files uploaded are open to all, which in terms means that anyone with the direct image link can open it using a web browser.
How can I protect or limit the file access to the users of my mobile applications or web application ?
NB: As a beginner, I am not sure about the configuration details to be provided along with question, If I need to give more details on my s3 config. please specify it, I can add it to the s question to make the question more meaningful, so sorry for the inconvenience.
I think an easier approach than pre-signed urls would be to use Amazon Cognito to provide access to AWS resources to your trusted applications, even to unauthenticated users.
To do this you would create an Identity Pool for your application (just need one pool for all 3 of your clients) and then configure it so that when a client provides a valid Identity Pool Id they can assume an IAM role with permissions to access AWS resources.
Then you control what S3 bucket permissions the IAM role they assume would have - you could allow unauthenticated users access to read the S3 objects, or force them to create accounts to be able to read/write to S3 buckets (this is very easy with Cognito - users can sign up with facebook, gmail, their own email, etc.)
There's a step-by-step guide here for setting up an identity pool with Cognito, and then allowing unauthenticated users to assume an IAM role that can access the contents of an S3 bucket
The above causes the same set of permissions for all guest user accounts - that have assumed an IAM role through Amazon Cognito by identifying themselves as part of an identity pool.
edit: I should point out that if you authenticate via Cognito, you'll need to access the S3 bucket through the S3 Transfer Manager from the AWS SDK
Let's say I have this usecase where the user is allowed to read from certain dynamodb table and getObject and putObject privileges in the S3.
Following items I have been able to establish-:
1. User is authenticated against cognito user pool
2. On successful auth, access token sent to API gateway
3. custom auth blueprint is used to validate and generate policy doc
Now what I am not able to understand is where and how do I mention the table/S3 permission specifics.
I went through the following documents/blogs
https://aws.amazon.com/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/
http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html
https://mobile.awsblog.com/post/Tx3JK25U7Z9EUIU/Integrating-Amazon-Cognito-User-Pools-with-API-Gateway
However, I am still confused as to how and when will the policy document, created by the custom auth lambda, be used? and a clarification on the flow would be highly appreciated.
We actually just launched native support for Cognito User Pools, which will validate the JWT vended by Cognito. However this will just do a simple ALLOW/DENY decision (allowing if the token is valid), so there is no concept of fine-grained permissions.
For custom authorizers, the policy that you generate is cached and can apply to the entire RestApi (or all methods that use the same authorizer). The policy allows you to set up fine-grained permissions just like you would with an IAM User/Role.
One use case would be a group-based permissions setup where the custom authorizer determines who the caller is and assigns a group policy (ex. admin, readonly, blocked, etc.) in the response to the first API call with that token. Those policies would set fine-grained permissions on specific resource/methods in the API. Then on subsequent API calls to any other resource/method in that share the same authorizer, the group policy would be applied.
So the benefits are:
Fine-grained permission policies associate with users, like IAM Users/Roles.
Caching the policy for the entire RestApi reduces Lambda invocations (cost and latency benefit).