How to use AWS user pool access tokens to access AWS resources? - amazon-web-services

I have been using AWS cognito to create users and issue access tokens. I did this by setting up a custom domain (to sign in) and allowing implicit code grant etc...
Next I set up a identity pool which gives access to s3 objects through cloudfront. Then I added the user pool as a provider using the id and client ID.
I got to my oauth domain, logged in, then got my access token in the url. All well and good.
I finally sent a request to my original cloudfront domain to try and access my private s3 object. However the request was not allowed.
This lead me to have a few questions:
How do I associate the access token to IAM role? Does AWS not pick up the access token and add the IAM roles to the request automatically? Do I have to make another request to the identity pool to get another token with IAM role information?
Do I have to put custom authorizers infront of cloudfront like Authorization#Edge?
I also have an ALB and lambda functions. Do I need to add custom authorizers for each of these to tranform the access token to IAM roles for each request. Is there a common way for all?
Thanks in advance.

Related

AWS. How can I control access to s3 bucket from lambda?

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.

Authenticate s3 request based on both file and request

Let's say I want to store some files for each user which is using my website on s3. Later I want authenticate each request to s3 to make sure that user has access to the files she is requesting. I guess this can't be done using presigned URLs or signed cookies(using cloud front). So which Amazon service should I use for that? What is the simplest way to achieve this?
Lets saying I'm authenticating users using jwt and its possible to recognize wheather a user has access to a file or not by the filename and content of the jwt.
I'm sorry that I don't have enough reputation to comment so I'll post an answer here.
One solution is:
AWS Cognito (Federated Identities)
S3 (one bucket)
S3 bucket policies allow you to restrict access to "user folders" equivalent here to "identity" by the prefix like yourbucket/<cognito_identity_id>/* Each user on your webpage will have its own federated identity.
When you create and configure the identity pool in AWS define a custom authentication provider and authenticate users "by the developer" in your backend.
Also, associate the authenticated identities to one IAM Role with access to the S3 bucket where you will keep the data. The bucket policy will take care of only allowing each user to their files and not to others. (See referenced links for policy example and more)
Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket
Access to User level folders using Amazon S3 and Cognito
Developer Authenticated Identities (Identity Pools)

Best practice to retrieve IAM role temporary credentials

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.

Allow Cognito user to Write to S3

I have an embedded device that requires the ability to write to S3. I want to avoid giving the embedded device an actual AWS IAMUser. I am looking at using Cognito to gain write access to S3.
I have a user pool with a group and one user (for now). The group has an attached policy which permits access to write to a certain S3 bucket. The pool is setup so that only admins can create new users. I have managed to authenticate the cognito user and have got access to refresh tokens and the idTokens. I am looking to use these tokens to write to my s3 bucket.
I am trying to follow trying to follow the documentation but am getting confused. I think i need a federated identity pool but i have no requirement for a public provider. I just want my cognito user group to write to s3.
Is there a simple solution to allow a cognito user to write to S3 without federated identities or if not do i require a back end to serve a token for a federated identity?
I have been using warrant https://github.com/capless/warrant to authenticate as so:
from warrant.aws_srp import AWSSRP
import boto3
client = boto3.client('cognito-idp')
aws = AWSSRP(username='<username>', password='<password>', pool_id='<pool>',
client_id='<clientid>', client=client)
tokens = aws.authenticate_user()
Any tips would be greatly appreciated!
You do need a federated identity pool. In the identity provider section you choose Cognito and enter your pool ID and pool client ID. Then, you need to provide the identity pool with authenticated and unauthenticated roles. You can use these roles to provide that S3 write access.
This is the default behavior for the identity provider setup. If you want the Role to come from the group that your user is in, you will need to set the Choose role from token option in the identity provider section under where you provided your pool and client id.

Allow access to custom prefix on S3 with Cognito

I need to allow users to access files on S3 with a specific prefix -- ie username1 -- that I can't change, so I can't just use the ${cognito-identity.amazonaws.com:sub} as the prefix. My S3 bucket is already populated with content under specific prefixes - so a user logs into my app, and is then allowed to access one of those specific prefixes
Currently set up on AWS to allows users to authenticate in a Cognito role using Firebase and developer authenticated identities. Each user account (email/password) has an associated S3 prefix that they must be able to access. Some users will share this prefix (two users accessing S3-bucket/username1 for example). A user should not be able to list or access any other prefix except their associated prefix.
I'm not quite sure what the best way to go about accomplishing this -- just with Cognito roles or using a database and lambda function + api endpoint, bucket/user policies or ACLs. Is there a simple way that I'm missing?
Pretty new to AWS, any help will be greatly appreciated!
tl;dr: How to only allow a user to access files on S3 with a specific prefix, that is NOT the ${cognito-identity.amazonaws.com:sub} variable?
As mentioned in comments, Amazon Cognito does not directly support your use case today. You can implement something like the following to achieve your goals:
Use Cognito to authenticate your users as normal. The Cognito identities would have permissions to invoke an API Gateway endpoint.
Your API (running in a Lambda) uses the Cognito identity id (provided in the context) to lookup the mapping of Cognito identity to your custom S3 prefix.
Your API uses STS to generate temporary credentials to access that prefix, returning them to the client.
The client uses those credentials to make a request directly to S3.