Multi-Tenant AWS Amplify
In this series of posts, we explore three methods for creating multi-tenant AWS Amplify mobile apps in React Native.
In this series of posts, we explore three methods for creating multi-tenant AWS Amplify mobile apps in React Native. This series is based on the various user posts at Group Authorization Limited by Cognito 25 Groups Per Userpool Limit.
Method 1: Custom Attributes
Full post:
Github: https://github.com/dantasfiles/AmplifyMultiTenant1
The first method stores the tenant information in an AWS Cognito User Pool Custom Attribute.
However, the access control system for AWS Amplify is driven by GraphQL resolvers which are normally passed the access token, which do not contain AWS Cognito User Pool attributes, so the GraphQL resolvers generated by AWS Amplify cannot see AWS Cognito User Pool custom attributes.
However, you can override the default behavior of AWS Amplify to pass the ID token, instead of the access token, to the API in order to use the new tenant
custom attribute in access control.
Method 2: Cognito Groups
Full post:
Github: https://github.com/dantasfiles/AmplifyMultiTenant2
Access tokens does not contain user attribute information, but they do contain AWS Cognito group information, which can be used to specify the tenant. The second method uses a Post Confirmation Lambda Trigger to assign each user to the proper AWS Cognito group associated with their tenant.
Method 3: Virtual Cognito Groups
Full post:
Github: https://github.com/dantasfiles/AmplifyMultiTenant3
The third method uses a Pre Token Generation Lambda Trigger to add the tenant information as a virtual AWS Cognito group to the access token. This gets around the hard limit of 500 real AWS Cognito groups.
Since this post was written, AWS raised the Cognito group limit to 10k. So Method 3 is probably no longer necessary for most multi-tenant use cases.
Initial instructions common to all three methods
Create a new React Native project > npx react-native init AmplifyMultiTenant
Add AWS Amplify to the project> amplify init
Add the AWS Amplify libraries to the project> npm install aws-amplify aws-amplify-react-native amazon-cognito-identity-js
Configure AWS Amplify inindex.js
// index.js
import Amplify from 'aws-amplify';
import config from './aws-exports';
Amplify.configure(config);
Issues
One major issue is that AWS Amplify joins multiple @auth
rules with an implicit OR operator — there is no AND operator for @auth
rules.
For example, here is an implicit OR in the final access control check generated by AWS Amplify for the getTodo
GraphQL operation:
#if( !($isStaticGroupAuthorized == true || $isDynamicGroupAuthorized == true || $isOwnerAuthorized == true) )
$util.unauthorized()
#end
As a result, making a more complex access control policy with tenants is difficult. Until such an AND operator is added, complex access control policies can be created by manually adding to the GraphQL resolvers that are automatically generated by AWS Amplify.