Best way to synchronise RDS DB and Cognito - amazon-web-services

I'm pretty new in all the AWS Tools BTW. Anyhow, I already created the Cognito User Pool and I can create and login new users but I also need those fields in my RDS database.
Yesterday I was reading docs and tutorials about the problem but looks like there is a lot of ways to synchronise two data sources. I don't know if something like AppSync has the options to do that or I need to write a two steps lambda, so I'm looking for advice for more experienced users like you guys.

You can have only the basic required attributes for authentication in the cognito user pool such as username, name, email and phone number and the rest of the meta data in some other database such as RDS or DynamoDB.
Within dynamo or RDS you can create a one to one mapping of the username in cognito and the rest of the metadata. Like for example:
*username* -> pk
employee_id
address
user_type
first_name
last_name
marital_status
gender
From implementation point of view:
Expose lambda to create and update a user. Create a user in cognito using only the required attributes earlier defined using the cognito APIs, next insert the meta data for that user in the database of your choice. Same goes for your PUT API with a slight change that you will have to update user pool and user meta data in the database.

Short answer:
You can replicate Cognito User Pool data to a SQL table by listening to Cognito events (using AWS Lambda, for example).
Long answer:
I think you can have Cognito User Pools as authentication/user data Bounded Context, in other words a single source of truth for authentication and user data.
And other BC's in need of user data (for example Sales context) can use some kind of data replication architecture to sync user data as read only, for internal complex queries, or just decoupling from Cognito.
One example of data replication in this case could be listening to Cognito events (AWS Lambda can help with that) to replicate user data to a Bounded Context (just the part of the data you need for that context).
But remember that the replicated data is read only, the original Cognito data should be the single source of truth.

You can use AWS AppSync Lambda resolvers coupled with Cognito User Pools as the AuthZ choice for an AppSync API to satisfy your use case. Essentially when the user completes auth with cognito you will have the '$context.identity.claims' which contains the user attributes, and inside your lambda resolver you can write to your RDS DB.
Some reference docs:
Lambda Resolvers: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html
AppSync Auth with User Pools: https://docs.aws.amazon.com/appsync/latest/devguide/security-authorization-use-cases.html

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.

Query database for data specific to authenticated user

I am trying to make an API using AWS api-gateway and lambda.
Requirements
I am trying to build a dashboard, The dashboard will be for multiple organisations and each organisation will have multiple users who can login and see the respective dashboard.
Example we have a dashboard for Intel and its accessible by User1, user2, user3
A user must be able to login and access the dashboard for his specific Organization and also do CRUD on his data as well
I found out that aws cognito with its user pool can be used for the auth process. After that I intend to use api-gateway with lambda function to query a sql database and populate the frontend. The place where I am stuck at is how do I link the user from cognito to corresponding data in database.
In simple applications we would have a user-table and its a simple query but I would appreciate if someone can suggest a good way to go about implementing this

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.

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.

Confused by AWS DynamoDB with UserID

I am new to AWS platform. I am trying to build a backend for a mobile app using AWS lambda, API gateway and DynamoDB using Facebook Authentication of AWS Cognito for my app.
A user are able to logged in to app and data should saved in a table with UserID (which I get from Cognito), data1, data2, data3. This only belongs to this. Let's say those are user's activities.
Again when he login to app next time, he should be able to see all his entered data.
I was looking for the example of it, I found this link which is about fine grained access control where the table is Partitioned with a particular user and permission.
https://aws.amazon.com/blogs/mobile/dynamodb-on-mobile-part-5-fine-grained-access-control/
That doesn't sound right. In a regular RDBMS centered app, the application connects to the database using a specific user in a connection string. User specific data is returned to the user using a query that is constructed on the fly with "username = user_id".
Is this above link talking about something different?
I am confused.
Thanks for your time!!
I believe the article you linked is discussing allowing an app to access DynamoDB directly, by calling the AWS API directly instead of going through a backend application layer. It is using variables in the IAM policy to only allow a user to execute queries against the table that contain their ID as the primary key.
In your case the AWS Lambda function is your backend application layer. You could simply assign an IAM role to the Lambda function that allows it to query all records in the DynamoDB table, and build queries in the Lambda function using the UserID as the query key.