Why I choose Keycloak over AWS Cognito
Tags: cognito, keycloak, identitymanagment, usermanagement
Published: 2021-06-02 07:54:52

I'm responsible for delivering a secure scalable multi-tenant product that is deployed on AWS. I love AWS and my preference is to use AWS managed services everywhere I can.

AWS has a Cognito service which is a fully managed service that provides authentication, authorization, and user management.

However, for a multi-tenant SaaS product, I would go for Keycloak. And in this short article, I will tell you why. I will compare AWS Cognito with Keycloak and show you why Keycloak is still a better choice for me.

## Multi-tenant setup

User pool in AWS Cognito is not multi-tenant. In order to create a multi-tenant system, you have to have a dedicated user pool per tenant. If you are a SaaS product then your tenant provisioning logic would have to be extended to automate the following actions:

1. Create user pool: [CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)
2. Create user pool client: [CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html)
3. Create user pool domain: [CreateUserPoolDomain](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolDomain.html)
4. Optional, to set up a more user-friendly domain that will host the sign-up and sign-in web pages, you need Route53 API calls as well

That's a lot. 

Now compare it with how easy it is to add a new Keycloak tenant and client from my video. Adding a new tenant and a new client are 2 really simple calls in Keycloak.

{% youtube lJlKNmAsaiE %}

## MFA setup

OK, you can set up SMS MFA very easily in AWS Cognito. When a user registers, the verification of the phone (via SMS) is provided out of the box: the web pages and verification logic is provided by AWS Cognito.

But when you actually want to use software tokens MFA (TOTP) then you have to do the following:

1. Add a special OAuth scope "aws.cognito.signin.user.admin" to the app client
2. Pass user's JWT access token to [AssociateSoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AssociateSoftwareToken.html) API call
3. Generate QR code
4. Once user sets up MFA on the phone, pass the user code to [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API call

I was surprised that SMS verification is supported out of the box, but for software token you have to write your own integration.

That's a shame really when you compare this with Keycloak MFA. You just set it up as a part of a single user journey with all the web pages, QR code generation, and verification logic provided by Keycloak.

Again, for reference see my video where I set up and test software tokens MFA in Keycloak:

{% youtube XUvaMgTdwy0 %}

## AWS Cognito limitations

AWS Cognito isn't too flexible when it comes to some of its settings. For example, these are the settings that you cannot change after you create a user pool: sign-in options, user attributes. 

AWS Cognito also has a limit of 1000 user pools per AWS account. That's actually very little for a multi-tenant applications.

## AWS Cognito strong points

Before I wrap up, I would like to say that AWS Cognito is still a great choice for many apps. Its strong points are:

1. hands-free fully managed service
2. support for many events which can trigger custom Lambda functions
3. great support for mobile apps (Android and iOS SDKs available)
4. integration with AWS STS which can exchange Cognito tokens for temporary AWS credentials 
5. integration with AWS API Gateway using Cognito User Pool Authorizer
6. great choice for single-tenant applications