User Pool
Resource Overview
A User Pool is a user directory stored in Amazon Cognito.
Implementing a User Pool in your stack gives you the ability to securely sign-up and authenticate users who intend to use your serverless applications. User Pools can be managed with the AWS SDK and accessed by Functions and Edge Functions to create, update, or delete the user profiles stored inside.
The events located in each User Pool resource allow you to offer a custom sign-up/sign-in process for your users and to better serve your application's needs. These events are covered in the User Pool Components & Implementation section below.
Event Subscription
Event subscription wires (solid line) visualize and configure event subscription integrations between two resources.
The following resources can be subscribed to a User Pool:
- Function
Service Discovery
Service discovery wires (dashed line) provide compute resources (Function, Edge Function) with the permissions and environment variables required to perform actions using cloud resources within the stack. This resource is on the receiving end of a service discovery wire originating from compute resources.
The following compute resources can use a service discovery wire to access a User Pool resource:
- Function
- Edge Function
Configurable Properties
Display Name
Human readable name for this resource that is displayed on the Stackery Dashboard and Stackery CLI output.
Logical ID
The unique identifier used to reference this resource in the stack template. Defining a custom Logical ID is recommended, as it allows you to quickly identify a resource and any associated sub-resources when working with your stack in AWS, or anywhere outside of the Stackery Dashboard. As a project grows, it becomes useful in quickly spotting this resource in template.yaml
or while viewing a stack in Template View mode.
The Logical ID of all sub-resources associated with this User Pool will be prefixed with this value.
The identifier you provide must only contain alphanumeric characters (A-Za-z0-9) and be unique within the stack.
Default Logical ID Example: UserPool2
IMPORTANT : AWS uses the Logical ID of each resource to coordinate and apply updates to the stack when deployed. On any update of a resource's logical ID (or any modification that results in one), CloudFormation will delete the currently deployed resource and create a new one in it's place when the updated stack is deployed.
Allow Public Sign-Ups
Allows non-administrative users to sign up to this User Pool.
Auto-Verify Emails
Enabling this will automatically send email verifications when a user is signed-up to this User Pool.
User Pool Components & Implementation
Configuring User Pool Clients
User Pool Client resources (app client) can be configured to generate authentication tokens used to authorize a user for an application. When a User Pool Client resource is connected (using an event subscription wire) to a User Pool and the stack is deployed, a Client ID will be generated for an application to use to access the User Pool.
When you connect a Function resource to the User Pool Client with a service discovery wire (dashed wire), the Function will populate the User Pool Client ID to reference.
This value can be used directly in the Function's handler code since they'll be automatically configured as environment variables.
The screenshot above is an example of a Function resource connected to both a User Pool and a User Pool Client. The Function's environment variables are populated with the User Pool Client's identifier as well as the User Pool's identifier, which the Function requires in order to authorize users within the User Pool.
User Pool Events
The following User Pool Events can be attached to Function resources with an event subscription wire to invoke them when specific events occur.
Pre Sign-up
Occurs just before a new user is added to the User Pool, providing you with the ability to perform custom validation to accept or deny a sign-up request.
Post Confirmation
Occurs after a new user is confirmed and added to the User Pool. This event contains the request with all the current attributes of the new user for you to perform custom messaging or logic to.
Pre Authentication
Occurs when a user attempts to sign in, providing you with the ability to perform custom validation to accept or deny a authentication request.
Post Authentication
Occurs after a user has successfully signed in, providing you with the ability to add custom logic after the user has been authenticated.
Custom Message
Occurs before the User Pool sends email or phone verification messages, or multi-factor authentication (MFA) codes, providing you with the ability to customize those verification messages.
IAM Permissions
When connected by a service discovery wire (dashed wire), a Function or Edge Function will add the following IAM policy to its role and gain permission to access this resource.
- Statement:
- Effect: Allow
Action:
- cognito-idp:Admin*
- cognito-idp:DescribeIdentityProvider
- cognito-idp:DescribeResourceServer
- cognito-idp:DescribeUserPool
- cognito-idp:DescribeUserPoolClient
- cognito-idp:DescribeUserPoolDomain
- cognito-idp:GetGroup
- cognito-idp:ListGroups
- cognito-idp:ListUserPoolClients
- cognito-idp:ListUsers
- cognito-idp:ListUsersInGroup
- cognito-idp:UpdateGroup
Resource: !GetAtt UserPool.Arn
Environment Variables
When connected by a service discovery wire (dashed wire), a Function or Edge Function will automatically populate and reference the following environment variables in order to interact with this resource.
USER_POOL_ID
The unique identifier for the User Pool in Amazon Cognito
Example: us-east-1_Iqc12345
USER_POOL
The Amazon Resource Name of the Cognito User Pool
Example: arn:aws:cognito-idp:us-east-1:123412341234:userpool/us-east-1_Iqc12345
AWS SDK Code Example
Language-specific examples of AWS SDK calls using the environment variables discussed above.
Create a new user in a User Pool
// Load AWS SDK and create a new Cognito object
const AWS = require("aws-sdk");
const cognito = new AWS.CognitoIdentityServiceProvider();
const clientId = process.env.USER_POOL_CLIENT_ID; // supplied by Function service-discovery wire
exports.handler = async message => {
// Construct parameters for the signUp call
const params = {
ClientId: clientId,
Password: 'Password$123',
Username: 'NewUser_99',
UserAttributes: [
{
Name: 'email',
Value: 'test@email.com'
}
]
};
await cognito.signUp(params).promise();
console.log('User ' + params.Username + ', created');
}
import boto3
import os
# Create an Cognito Identity Provider client
cognito = boto3.client('cognito-idp')
user_pool_client_id = os.environ['USER_POOL_CLIENT_ID'] # Supplied by Function service-discovery wire
def handler(message, context):
# Add a new user to your User Pool
response = cognito.sign_up(
ClientId=user_pool_client_id,
Username='NewUser_99',
Password='Password$123',
UserAttributes=[
{
'Name':'email',
'Value':'test@email.com'
}
]
)
return response
Related AWS Documentation
AWS Documentation: AWS::Cognito::UserPool