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.
Related
I have read about AWS cognito and I understand that User pools is an identity provider that is used to authenticate users to your mobile app, website and manage users. Then there is Identity pools that are used to authorize users to give access to your aws resources such as IAM, S3 and etc.
So my question is: Are identity pools used for the app management like by devs, dev-ops or anyone who needs to manage/update the apps? Is that the work of identity pools?
Identity pools are not (necessarily) used for app management. I can tell you about how my team used them at my last job. (There are probably other use cases, but I suspect ours was a fairly common one.)
We were building an app where users needed to upload and download files that we would store in S3. For various reasons, we wanted the client to interact directly with S3 for file transfer (as opposed to pushing files through an API layer that we would have to maintain). Identity Pools were made for exactly this sort of scenario. Basically they allow a client to exchange an identity token for a set of temporary IAM credentials (access_key_id + secret_access_key + session_token). The temporary IAM credentials are what the client needs to interact with an AWS SDK or create a signed HTTP request for one of AWS's native services.
The identity token that gets exchanged for credentials could be provided by Cognito User Pools, but it could also come from a different identity provider. We used Auth0 as an identity provider, for example. But we still wanted our client to interact directly with S3 and for that we needed Cognito Identity Pools.
One really cool feature of Identity Pools that we took advantage of was what Cognito calls Principal Tag Mapping, which is the ability to map claims (attributes) in the Auth0-provided identity token to session tags, which are kind of like environment variables that are attached to the temporary credentials' session. You can then write IAM policies that incorporate session tags to do attribute-based access control. We wrote S3 bucket policies that provided fine-grained access control where each user was only allowed to read and write to a prefix that contained their own user id.
I have to say that the distinction between User Pools and Identity Pools in Cognito confuses everyone and AWS's documentation isn't always as helpful as it could be on this point.
I am using AWS Cognito for user management. I want users of my application to store their data in DynamoDB. So I need user-scoped access (User A can write data and only read data added by User A, User B being able to only read data added by User B).
Docs suggest the ability to have row-level and column-level fine grain access: (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html).
BUT I am not using IAM, I am using Congito users (want it scoped to each user, not a Role/Group). This doc suggests you can use Cognito ID: (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_items.html).
However, according to this StackOverflow question (How to use DynamoDB fine grained access control with Cognito User Pools?), it's not what I am expecting?
Does AWS support my use-case? Lot of docs but its not clear if my use-case is supported.
You need to use Cognito identity pool. Cognito identity pool acts as an identity broker. When a Cognito user authenticates using the user pool, then Cognito provides JWT tokens. User can use ID token provided by Cognito user pool and Cognito identity pool can take the token and provide temporary IAM credentials.
I am familiar with a similar use case as of yours. In that use case, user who has written data to S3 can only modify/delete that data. In this case, you can create new S3 folders (prefixes) for each user's Identity ID (provided by Cognito identity pool) and that particular user can access data under that S3 folder only.
I am not much familiar with DynamoDB access control, hence not able provide the exact solution now. You can try a similar approach as the above one.
https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-identity-pool.html
I have an App client created for a Cognito User Pool. The client has an ID and secret generated. It is configured to use the Client credentials flow and has a custom scope defined. With that in place, I'm able to successfully exchange the creds for an Access Token, so far so good.
I would like to use AWS SDK to manage users (list, delete etc) in the User Pool with the server-side app client. Assuming I validated the granted token, how do I use it with AWS SDK to execute Actions I need? Is there a better way to manage User Pools from a server-side app?
If you look at Admin* level actions in the Cognito SDK (e.g. AdminDeleteUser), you will see it does not accept access tokens. It rather expects valid AWS developer credentials.
So what you probably want to do is to create an IAM role with appropriate permissions to manage the user pool (resource format: arn:aws:cognito-idp:REGION:ACCOUNT_ID:userpool/USER_POOL_ID) and let your server application assume that role. With correct permissions configured, you can call the AWS SDK directly.
You can find the list of available IAM actions here.
Is using an IdentityPool mandatory with AWS Cognito?
My use case:
My web app has users who can self-signup and will be added to the Cognito UserPool I have set up. I only want to provide access to my backend resources to authenticated users (ie., users belonging to an authenticatedRole IAM role). My requirement is simple enough that a single authenticated role suffices to handle my application's resource authorization requirements and I just want to deny access to all backend resources for non-authenticated users.
Is this possible with just the UserPool and if yes, how do I go about accomplishing this?
Note: I am using CDK to define my Infrastructure as code.
Using an identity pool is by no means mandatory with Cognito. It is completely on a use case basis. A few things to clarify here.
Userpool - For authentication
Identity Pool - For authorization.
Basically, if you want your end users to sign-up, sign-in, and then access AWS resources or make AWS API calls, then you would have to use an Identity pool. So let’s say you have a gaming application where the end user can sign in via FB, Google, or natively (username and password). This is authentication, and here we would be using a Cognito user pool. Now the user, is logged in and playing the game. They make a high score. This high score may need to be added to S3 or a DynamoDB table record for the user. For this, an identity pool is used. An identity pool will help you with vending temporary AWS credentials that the end user can use.
I believe in your use case the userpool should be sufficient. You can grant access to your resources by verifying the access token returned by Cognito for the end user.
Story:
I have a Cognito User Pool with Users.
This User Pool is an authentication provider in a Federated Identity Pool.
I have an S3 bucket where users are limited to uploading to a private path via a policy on the Auth Role as follows:
arn:aws:s3:::BUCKET_NAME/${cognito-identity.amazonaws.com:sub}/*
The users upload directly from the web browser via the aws javascript sdk.
Now this works great and my users are limited to where they upload. The files they upload end up with paths in the bucket looking like this:
us-east-1:0f26319c-1233-4c71-afb6-fac96a798ffb/random_file_name.txt
I then have a lambda which is triggered from this S3 bucket whenever a file is added. To clarify, the user does NOT invoke the lambda
Problem:
I would like to access the user's attributes in the user pool from the lamda. I thought that I could do this lookup using the cognito-identity sub. However, I can't seem to find a way using the SDK api's to allow this.
Using this api:
http://boto3.readthedocs.io/en/latest/reference/services/cognito-identity.html#CognitoIdentity.Client.describe_identity
I am able to get the login / the user pool but not the username associated with this Identity ID.
If I had the username, then I could use the api: http://boto3.readthedocs.io/en/latest/reference/services/cognito-idp.html?highlight=cognito#CognitoIdentityProvider.Client.admin_get_user
Any ideas how I can use the Federated Identity ID to lookup the user's attributes?
Unfortunately, I don't believe this is possible. The reason is, as far as I understand, technically the federated identity ID doesn't have to represent a user pool user. If you connected other authentication providers to the identity pool users could have completely different properties, for example.
What about storing files in
arn:aws:s3:::BUCKET_NAME/${cognito-idp.us-east-1.amazonaws.com:sub}
This will be resolved to the folder names like
f4cfd4a8-0e94-4287-8c5e-1b01538dd2a1
Using this sub of user from Cognito User Pool you can list users with that sub, for example in cli:
aws cognito-idp list-users --user-pool-id=us-east-1_ndhjGJQYE --filter "sub = 'f4cfd4a8-0e94-4287-8c5e-example'"