Which parameter can be used as primary key from AWS Cognito? - amazon-web-services

I read some questions and answers about my issue, but I still don't know the answer.
Can I use the userSub in AWS Cognito as primary key?
AWS Cognito: Difference between Cognito ID and sub, what should I use as primary key?
First, I will try to describe my case.
I want to create an application with spring boot as a resource server that uses oauth2. Then to save me some time with user management, I was hoping to use AWS Cognito since it allows me to create users as admin. I can set it up that it won't let other people sign up for themselves, which is crucial for me since my app will have restricted access; the admin will manage that.
Now to my question, which field of AWS Cognito can I use as the primary key for keeping user-specific data in my DB? I read that neither usernamenor sub is correct.
username can be changed, for example, and sub is globally unique, so it can't be restored. Is there any way to create a custom field where AWS Cognito will autogenerate UUID that I can use, and if I had to restore the user pool, I would have an option to set this field?

You can still go with username. If it is ever changed, just update your database to reflect this change.
You can also create a custom attributes in user pool. You can use that to store a self generated id. As for automatically generating this, you can have a post confirmation lambda trigger that will use adminUpdateUserAttributes to assign a unique id.

Related

Using AWS Cognito UserID as partition key in DynamoDB

I am creating an application. The users can register and log in via AWS Cognito and MFA SMS Verification.
The specific user information, created in the app, will be stored in a DynamoDB table.
My idea is to use the UserID from Cognito as the Partition Key (user_ID) in DynamoDB.
My first thought is to use a Lambda function that is triggered when a user successfully registered in my app, and creates a User item in DynamoDB with the Cognito UserID as Partition Key (user_ID).
Does this make sense or is there a best practice how to set this up?
Yes this makes sense and is what most people use for Cognito as it allows you to use DynamoDB's fine grained access control, meaning users logging in can only access information belonging to them in your DynamoDB table, offering an extra layer of security.

How to Prevent identity provider attributes to be updated with UpdateUserAttributes

I am using AWS Cognito with Federated identities to manage access to my app.
The custom social identity provider that I use returns me some custom user attributes.
The attributes are correctly mapped as user attributes in my user pool.
I recently realized that my users could change their own attributes using their accessToken. (using aws cognito-idp update-user-attribute for example). Is there a way to forbid this? I basically always want to keep the value returned by the provider.
I originally thought I could mark the attributes as non-writable, but this does not work as I need the social provider to be able to write it.
Also, the doc mentions that I should keep it mutable.
Would using DeveloperOnlyAttribute work ? I did not try it so far as the doc basically says it is deprecated.

Best practice to store users "plan" and control their permission in AWS Cognito

Assume I have a web app application and I use aws cognito users-pool to manage my users. Also assume some of the users are just "Guests", some are in a "Regular" paid plan and some are under "Premium" paid plan.
Where is the best place to store the users plan information? Is it better to store it as a Cognito user attribute or in some key:value DB (e.g Dynamodb)?
How should I control what a user can do according to his plan? Should i check the user ID against his "plan type" value in Cognito user pool/DB for each http request he makes to the server? Is there a cheaper (resource wise) way to accomplish this?
Thanks
If your application is single tenant and you are using the particular Userpool only for this application, you can store the 'plan' in an custom attribute.
This would be difficult to manage if you use the same user pool for multiple applications or having multi-tenancy with different 'plans' for a single user.
To store the plan you can use either Dynamodb or Cognito Sync Storage.

AWS Cognito: Difference between Cognito ID and sub, what should I use as primary key?

Im building a serverless backend using AWS Cognito for user administration.
Cognito uses both cognitoId and sub to identify a user.
This project from the official awslabs uses the cognitoId as primary key in the database tables to link data to a user object, but the documentation about sub clearly states:
sub: the UUID of the authenticated user. This is not the same as username.
Question: What should I use as primary key, cognitoID or sub?
The naming can get confusing, I'll try to clarify.
There are typically two pools under the umbrella of Amazon Cognito:
User Pool
Identity Pool (Federated Identities)
The "sub" that you are referring to is typically expressed in IAM Policies as
${cognito-identity.amazonaws.com:sub}
and will resolve to the value found in (in the javascript sdk)
AWS.config.credentials.identityId
which will look something like
us-east-1:########-####-####-####-############
It will only exist on the credentials once the credentials have been refreshed.
So to answer you question, the sub.
sub(subject) is globally unique and hence is unique for user pool as well.
Unlike username, which can be reassigned to another user in user pool, sub is never reassigned.
Source

S3 Authenticate User without Secret Key

I have a user with read access on a bucket. Is there a way to authenticate with the users' credentials without using my secret key?
Something like (pseudo code):
auth = new S3Authentication(user, pass)
obj = S3::getObject(obj, auth)
Update
I discovered the solution to my own question. See below.
The original reason for asking this question was because I was operating under the assumption that the global access and security key needed to be use to generate the appropriate Authorization digest header.
This is not the case.
You can use Amazon's IAM to create a new key pair to use when authenticating. Here are the steps:
Create a new Group in IAM
Set the policy on the group to whatever you access you want users within this group to have. In my case, I just chose the S3 Read-Only policy template
Create a new user and put it in this group
Creating a new user will generate a new secret/access key specific to that user. You can use this pair to auth S3 transactions.
As an aside, you shouldn't need to mess with the bucket-specific permissions. In my case, I have no bucket permissions set (not even Authenticated users) and it works just fine.