AWS Amplify GraphQL Schema that is linked to Cognito User Pool - amazon-web-services

I am using the AWS Amplify to create a website platform that functions mostly as a directory of its registered users with various attributes relating to the business domain. The two primary users for the platform will be registered users and normal unauthenticated users who will be able to list and filter the registered users based on their attributes such as location, age, etc. Registered users will be set all their attributes in the members area.
Some of the attributes are stored in Cognito such as name and address and were setup using Amplify Authentication. These are fields I would like to be to query and mutate through the Amplify GraphQL capabilities.
I can see there are cool authorization patterns that can be achieved with the #auth directive.
Is it possible to leverage GraphQL Transform such that I can create a model schema where some of the fields link to the Cognito User Pool and some are defined within the GraphQL schema so that they are queryable and mutable? In fact I would like to provide registered users with the facility to update all their fields except email. Or maybe there is some combination of services supported by Amplify that I can hook up together to achieve the same?
I am new to the AWS Serveless ecosystem and it has been exciting so far!

I found out the above can be achieved using the #function directive. It allows us to connect lambda resolvers to the schema. In the lambda we can do virtually anything like read and update Amazon Cognito User Pools.
https://aws-amplify.github.io/docs/cli-toolchain/graphql#function

Related

Configuring Appsync schema Auth with Dynamic user groups in cognito

We have configured graphql schema with AppSync and for authorization mode we have choose Cognito user pools. We have have added authorized groups in the schema for specific types.
Now we want to manage cognito user pools dynamically using program pattern. But we want to manage this dynamic cognito groups in AppSync schema so that whenever any user or groups in cognito modified programmatically will automatically reflect into the AppSync Schema.
Can anyone provide working solution for this problem statmententer code here

AWS Amplify/Cognito Tenant Selection at login

I am currently using AWS Cognito and it's hosted UI to manage user login. All my users sit in a single pool, which has a number of different app clients registered. Our users are grouped into different organisations and for the most part a single user (or email address) is only associated with a single organisation, so this setup works very well. A small subset of users are associated to multiple organisations. Associated to a particular organisation is managed by a backend service rather than using Cognito attributes and/or groups.
We are already using the pre token generation Lambda trigger to inject claims into our tokens to denote which organisation a user belongs to which is then used downstream in our backend services to control which database is hit when a user makes an API request (we use single tenant databases).
I need to design a mechanism that will allow the users who belong to multiple organisations to select which organisation they want to login as (ie select which tenant they want to use for that session) at auth time. I know this will be impossible to do with the Hosted Cognito UI but I'm wondering if this is something that can be done with AWS Amplify along with a custom login app and using custom auth challenges. The flow would be something like this:
Username/password provided
Custom auth challenge lambda fires which detects whether the user has a 1-1 relationship to a single organisation (in which case we can log them straight in) or a 1-many relationship to multiple orgs.
In the latter case above, the auth challenge returns a collection of organisations that a user is allowed to log in to back to the app which displays them in a picker control (drop down or similar)
User selects their tenant and this information is sent to the auth challenge response and the login continues.
A key step after this would be ensuring that the custom challenge responses make it through to the pre token generation Lambda function so it knows which organisation the user is logging into.
I'm a backend developer and have had no exposure to Amplify at all, I just need to know if this is theoretically possible before I invest too much time into it.
Can anybody with Amplify experience confirm if what I describe would be possible using Amplify and a custom auth React app?
Thanks

AWS Cognito custom static claims for all users in user pool

Context:
I am integrating AWS Cognito into an existing multi-tenant application with preconfigured tenant ids. I am currently trying to find a way to add a custom static claim to each user in a given user pool. The claim is the tenant_id. This claim would have the same immutable value for each user in a user pool.
Question:
Is there a way to add a custom static claim like this for each user in a user pool?
Reason:
I would like to provide a stateless way to interact with existing services that currently only know of the existing tenant_id.
The only solution I have found so far is by creating a lambda for the Pre Token Generation Lambda Trigger and create a crosswalk from Cognito app client id to the existing tenant_id. Then get the tenant_id from the id token in the existing stateless services.

Multi-Tenant Authentication with AWS Cognito

My current project is in AWS, using Cognito and microservices with Lambda. We have designed the microservices using DDD and are in the process of implementing basic functionality.
However, there is a business need for users of the API to be able to be categorised into the client company that they work for, and only be able to access data for that client company as well as any role-based authentication we will have.
This isn't a full multi-tenant solution as every user will be working with the same website, but their account will have been associated with a particular client.
Everything I have read about doing something like this in AWS suggests using one user role or pool per client and associating users with it when they are created, however we do not want to do this, as the clients typically consist of 2-3 users and there are many clients. This would quickly become unmaintainable in terms of number of user pools.
I tried to think of ways around this issue using "conventional" means, such as adding a domain service into the architecture which was solely designed to add client data to each request by a particular user by calling into the user microservice, but this seems overly complex. I also considered changing the architecture to include basic user and role information in each microservice, but that seems messy.
My question is are there any officially supported ways to add data into an AWS Cognito profile programmatically, and in such a way that this could be changed through a front-end website by a client admin after the account has been created? Even if it's just a clientId field in the token.
If not, then what would anybody who has experienced a similar issue recommend as an alternative to the user pools suggestion.
Thank you.
EDIT:
I have also been investigating several ways to do this using attributes on Cognito profiles, as mentioned here. It seems like this is the way to do more or less what I'm trying to achieve, but I'd still like to hear about alternatives or advice.
The solution we will use for this issue will be to use custom attributes as part of the Cognito user set-up. We will have text fields for additional attributes or groups that the user belongs to.
The way this should be implemented can be found at the following links:
Managing SaaS Identity Through Custom Attributes and Amazon Cognito
Managing SaaS Users with Amazon Cognito
SaaS identity and isolation with Amazon Cognito (Example Guide)
SaaS Storage Strategies
With this data being automatically passed into each service as part of the Cognito credentials, we will be able to check that the user has the valid credentials for accessing data specific to each client.
Examples of how to work with Cognito in a NodeJS application (sometimes with Serverless) include:
https://serverless-stack.com/chapters/login-with-aws-cognito.html
https://serverless-stack.com/chapters/add-a-create-note-api.html#configure-the-api-endpoint
This seems to be most easily achieved by using the aws-amplify package, which is primarily designed for front-end authentication, but which can be used in NodeJS for back-end authentication as specified here.

sendMessage to SQS from Browser

I am building an SPA with Django REST as the backend. Right now I am using the standard Django authentication system and User models.
I would like the JS running on the SPA to be able to insert messages into an AWS SQS (i.e. sendMessage).
AWS has these doc on calling sendMessage from JS in the browser.
They also provide these docs on how to authenticate the user. My thought right now is to use Amazon Cognito. From the FAQ:
Q: What if I register and authenticate my own users?
Amazon Cognito can integrate with your existing identity system. With
a simple API call you can retrieve a Cognito ID for your end users
based on your own unique identifier for your users. Once you have
retrieved the Cognito ID and OpenID Token Cognito provides, you can
use the Cognito client SDK to access AWS resources and synchronize
user data.
Am I correct that for this to work, I would need to:
Create an IAM user for each user in my system. Or do I just need one IAM role?
When the user logins in my site (Django backend), I would have my backend then make "a simple API call [to] retrieve a Cognito ID"
Send that Cognito ID when the user loads the SPA.
User the Cognito ID from the JS running in the browser to call sendMessage to the SQS queue
Am I missing something here? Is there someway to remove the Django User backend and just user IAM Users so that I can avoid having to keep the two users lists in sync? I found this project but it does not seem to be maintained.
UPDATE:
It seems that there might be an alternative method of doing this where I don't use Cognito at all but rather expose an endpoint that can sign requests, "Query Request Authentication". This Heroku page talks a little about building a signing service.
Is this in fact an alternative option and if so what are the pro/cons of these approaches?
Amazon Cognito does not require you to register IAM users, just the 2 IAM roles. A slight modification to what you would need to do:
Create an Amazon Cognito Identity pool, configure with your developer provider.
Update the IAM roles associated with your pool to allow access to the services you want (for instance SQS).
From your Django backend, call GetOpenIdTokenForDeveloperIdentity to get the OpenId Connect token and identity Id for this user, return this to your JS application.
Configure your CognitoCredentials in the JS SDK. In the logins map, use the key cognito-identity.amazonaws.com and the value as the token returned from your Django backend.
Use the JS SDK to call SQS or any other services you wish from your application.
While using pre-signed URLs for SQS can work, using Cognito with the JS SDK will allow you to leverage other services supported by the SDK (DynamoDB, SNS, S3, etc).