Search code examples
authenticationamazon-cognitomulti-tenant

Multi-Tenancy with Cognito: one big user pool or one pool per tenant?


I’m aware of the various multi-tenant approaches with Cognito and I’ve mentally committed to the “one user pool per tenant” method. So, for example, our AWS account would have tenant_a_user_pool for tenant A and tenant_b_user_pool for tenant B, etc. BUT, now that I’m ready to implement this approach, I’m starting to have second thoughts and I’m wondering if I could do something more simple with one user pool while still achieving my goals, which are: security and flexibility

Regarding security, I’ve made the assumption that having users separated by user pool is inherently more secure just by the sheer nature of having users separated. So, my first questions are:

  1. Are separate user pools more secure?
  2. Or, can it be equally secure using one user pool with tenant/user relationship info stored in a database?

As for flexibility, having “one user pool per tenant” will allow for configuring SAML authentication for tenant A while tenant B might choose another authentication method, say authenticating with un/pw against their user pool. Or, tenant C can turn on MFA and tenant D might leave it off. While I don’t doubt that this approach can be flexible, I am starting to wonder if it is too complex and if I can achieve the same using one user pool?

If I go with one user pool for all users, I was thinking of an approach such as this:

enter image description here

In the model above, I’ve added an association table, tenant_users, as there might be a requirement to have users be part of multiple tenants while using one set of login credentials (similar to Slack, I’d say). But, if I go this approach, I start to wonder about flexibility. For example, can I still have tenant A use SAML and tenant B use some other authentication method? If you notice in the tenants table, I’ve added an auth_methods column which would store the tenants preferred authentication method. I’m hoping I can add the authentication logic for the various authentication methods in a lambda invoked by a Cognito trigger. But, I’m heading into unfamiliar territory so I don’t know what’s possible or not.

To recap, my questions are…

  1. Is one user pool for all tenants just as secure as one user pool per tenant?
  2. Can I maintain flexibility (e.g. allow tenants to choose different authentication methods) with one user pool if I add an auth_methods column to the tenants table that specifies each tenant's authentication preferences?

Any other comments on this overall approach would be greatly appreciated.


Solution

  • I think it's a hard question to answer without knowing what resources you are protecting and also how you are protecting them, e.g.

    • Are you whiteboxing?
    • Are all logins equal, all accessing the same app and resources?
    • Would all data in a "tenant" be equal between the users of that tenant?
    • how is authorization done, in cognito or elsewhere?

    If all logins are pretty much equal then I would say single tenant may make sense.

    Some things to keep in mind:

    • would you like to have device tracking options for a subset of users?
    • what about MFA?
    • what about paying for SMS MFA?
    • what about custom auth, e.g. passwordless?
    • what about advanced security (extra 5c per user)?

    If the answer to any of these is yes then I think you might consider multiple user pools, there is a default cap of 1000 user pools per account but you can request amazon increase this.

    Personally I have used the "big user pool" approach for authentication however we tracked authorization outside of cognito. The biggest headache is when a tenant wants advanced security (ability to see failed logins, account risks etc) or SMS MFA as they have to be enable across the user pool causing dramatically increased costs.

    Another thing you may consider is that the hosted UI does not allow you to pre-set the user name, so if you are using a form that takes the email/username and then redirect to the appropriate hosted UI (in a multi-tenant situation) for the user pool they are in then they will need to re-enter their email again.

    If you decide to not use the hosted UI and user your own (or aws amplify) then you lose all the oauth2/oidc stuff such as code flow so no SSO and it makes mobile apps harder.

    Also note custom auth cannot be mixed with MFA and if you use custom auth you also cannot use the hosted UI.