Multi-Tenant AWS Amplify

Daniel Dantas (@dantasfiles)
2 min readDec 31, 2019

--

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 Medium post: https://medium.com/@dantasfiles/multi-tenant-aws-amplify-method-1-cognito-custom-attributes-6719d27d84cc
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 Medium Post: https://medium.com/@dantasfiles/multi-tenant-aws-amplify-method-2-cognito-groups-38b40ace2e9e
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 Medium Post: https://medium.com/@dantasfiles/creating-a-simple-multi-tenant-aws-amplify-mobile-app-e26119ab8246
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.

--

--

Daniel Dantas (@dantasfiles)

I create guides to help me fully understand the issues that I’m encountering and fixing. Web: dantasfiles.com Email: daniel@dantasfiles.com