Set up AWS Cognito with Terraform and Go
Choosing AWS Cognito for your user authentication and authorization needs is an excellent option. Cognito provides a lot of capabilities, and with all the flexibility comes some complexity. It is hard to wrap your head around how to set it up, you probably have questions like:
- should I use a User Pool or an Identity Pool?
- If I create a User Pool, do I need to use a federated Identity Provider?
- When the documentation says that Cognito can be used as an OIDC what does it mean?
The goal of this article is to shed some light on this topics and help you set Cognito for your project. We’ll use go for the examples, but should be able to understand the ideas behind the code an dapply them to a project using other languages.
Let’s start by discussing some basic topics, before we start creating terraform templates and writing go code.
AWS Cognito basic concepts
AWS Cognito provides a complete solution for authentication and authorization. Cognito can be used in different scenarios, for example:
- You need a complete solution to mange, sign-up, sign-in, etcetera, in your app
- Cognito can also serve as an identity provider that can return Oauth 2.0 acces tokens, this tokens contain metadata of the authenticated user so you can add authorization logic to your code based on this information
- You need access to AWS resources. With AWS Cognito you can return AWS credentials (Specified using IAM) to access those resources
- Cognito can also serve as an intermediate Service Provider to other Identity providers. For example, Facebook, Google, etc.
User Pools
User pools are, as the name suggests, a repository of users you want to keep track off. The user pool can be an independent directory, that means that all the users live in the User Pool. The user pool can also source the users from third-party providers. That means that the User user pool will be an intermediate service provider. Cognito user pools can be used as an OIDC (OpenID Connect) Identity Provider.
The simplest form is to use the user pool as an independent directory. Everything is handled inside AWS Cognito, which makes things simpler. When using the user pools as an intermidate SP to third parties, help translating all the external tokens returned by the third-party IdPs to Cognito Tokens, so everything is standardised into one format and this could simplify your code.
App Client
In Cognito creating the User Pool is only half the batlte, you still need to interact with it. While you can in certain cases just interact with the User Pool programatically using the AWS SDK, it is far easier to interact with the User Pool via an app client. The app client provides features like the following:
- Authentication Flows
- Token management. For example, token expiration.
- OAuth scope management
- Callback and logout URLs for the authentication workflow
- CORS configuration
- Security features, like Secrets.
- Hosted UI that you can customize
- Manage identity providers for the app client
In general you’ll need to set up an app client for your application to communicate with Cognito for user authentication, token retrieval and expirtation, etcetera.
Identity Pools
The identity pools are used in combination with authenticated users from User Pools, or it can use federated identities from external IdPs. When an entity has been authenticated, then we can provide AWS Credentials to access AWS resources. For example, we have an app that shows the content of a file in private S3 bucket. We can create an IAM role that grants access to the S3 bucket content. Instead of adding someone to your AWS organisation, you could use an Identity Pool to get temporary AWS credentials to assume that IAM role and be able to access the file form the private S3 bucket.
Identity Providers (IdPs)
A user pool can serve as an Identity Provider, meaning that it handles the verification of your users and can provide your app with information about them. When you use an external IdP, you can autenticate and get information about your users from a service that you don’t manage, it is also know as federated identities. You have probably seen sign in with Google, Facebook, Amazon, etcetera, they serve as Identity Providers. Their users are already registered in their service and their identity is being federated from them. You can also use an Active Directory as your identity provider, or any other service that can communicate using SAML, OAuth2.0 or OpenID Connect(OIDC).
Creating the user pool with terraform
First, we need to create our user pool. That is the easy part, the only required field is the name of the user pool:
| |
Adding the alias_attributes to include the email, means that the user would be able to login using its username or the email.
Now we need to set up our App client:
| |
We are not going to be using custom domains, so we just need a prefix for our domain:
| |