Customizing user pool workflows with Lambda triggers - Amazon Cognito

Customizing user pool workflows with Lambda triggers

Amazon Cognito works with AWS Lambda functions to modify the authentication behavior of your user pool. You can configure your user pool to automatically invoke Lambda functions before their first sign-up, after they complete authentication, and at several stages in between. Your functions can modify the default behavior of your authentication flow, make API requests to modify your user pool or other AWS resources, and communicate with external systems. The code in your Lambda functions is your own. Amazon Cognito sends event data to your function, waits for the function to process the data, and in most cases anticipates a response event that reflects any changes you want to make to the session.

Within the system of request and response events, you can introduce your own authentication challenges, migrate users between your user pool and another identity store, customize messages, and modify JSON web tokens (JWTs).

Lambda triggers can customize the response that Amazon Cognito delivers to your user after they initiate an action in your user pool. For example, you can prevent sign-in by a user who would otherwise succeed. They can also perform runtime operations against your AWS environment, external APIs, databases, or identity stores. The migrate user trigger, for example, can combine external action with a change in Amazon Cognito: you can look up user information in an external directory, then set attributes on a new user based on that external information.

When you have a Lambda trigger assigned to your user pool, Amazon Cognito interrupts its default flow to request information from your function. Amazon Cognito generates a JSON event and passes it to your function. The event contains information about your user's request to create a user account, sign in, reset a password, or update an attribute. Your function then has an opportunity to take action, or to send the event back unmodified.

The following table summarizes some of the ways you can use Lambda triggers to customize user pool operations:

User Pool Flow Operation Description

Custom Authentication Flow

Define Auth Challenge Determines the next challenge in a custom auth flow
Create Auth Challenge Creates a challenge in a custom auth flow
Verify Auth Challenge Response Determines if a response is correct in a custom auth flow
Authentication Events Pre authentication Lambda trigger Custom validation to accept or deny the sign-in request
Post authentication Lambda trigger Logs events for custom analytics
Pre token generation Lambda trigger Augments or suppresses token claims
Sign-Up Pre sign-up Lambda trigger Performs custom validation that accepts or denies the sign-up request
Post confirmation Lambda trigger Adds custom welcome messages or event logging for custom analytics
Migrate user Lambda trigger Migrates a user from an existing user directory to user pools
Messages Custom message Lambda trigger Performs advanced customization and localization of messages
Token Creation Pre token generation Lambda trigger Adds or removes attributes in Id tokens
Email and SMS third-party providers Custom sender Lambda triggers Uses a third-party provider to send SMS and email messages

Important considerations

When you are preparing your user pools for Lambda functions, consider the following:

  • The events that Amazon Cognito sends to your Lambda triggers might change with new features. The positions of response and request elements in the JSON hierarchy might change, or element names might be added. In your Lambda function, you can expect to receive the input-element key-value pairs described in this guide, but stricter input validation can cause your functions to fail.

  • You can choose one of multiple versions of the events that Amazon Cognito sends to some triggers. Some versions might require you to accept a change to your Amazon Cognito pricing. For more information about pricing, see Amazon Cognito Pricing. To customize access tokens in a Pre token generation Lambda trigger, you must configure your user pool with advanced security features and update your Lambda trigger configuration to use event version 2.

  • Except for Custom sender Lambda triggers, Amazon Cognito invokes Lambda functions synchronously. When Amazon Cognito calls your Lambda function, it must respond within 5 seconds. If it doesn't and if the call can be retried, Amazon Cognito retries the call. After three unsuccessful attempts, the function times out. You can't change this five-second timeout value. For more information, see Lambda programming model in the AWS Lambda Developer Guide.

    Amazon Cognito doesn't retry function calls that return an Invoke error with an HTTP status code of 500-599. These codes indicate a configuration issue that leaves Lambda unable to launch the function. For more information, see Error handling and automatic retries in AWS Lambda.

  • You can't declare a function version in your Lambda trigger configuration. Amazon Cognito user pools invoke the latest version of your function by default. However, you can associate a function version with an alias and set your trigger LambdaArn to the alias ARN in a CreateUserPool or UpdateUserPool API request. This option isn't available in the AWS Management Console. For more information about aliases, see Lambda function aliases in the AWS Lambda Developer Guide.

  • If you delete a Lambda trigger, you must update the corresponding trigger in the user pool. For example, if you delete the post authentication trigger, you must set the Post authentication trigger in the corresponding user pool to none.

  • If your Lambda function doesn't return the request and response parameters to Amazon Cognito, or returns an error, the authentication event doesn't succeed. You can return an error in your function to prevent a user's sign-up, authentication, token generation, or any other stage of their authentication flow that invokes Lambda trigger.

    The Amazon Cognito hosted UI returns errors that Lambda triggers generate as error text above the sign-in prompt. The Amazon Cognito user pools API returns trigger errors in the format [trigger] failed with error [error text from response]. As a best practice, only generate errors in your Lambda functions that you want your users to see. Use output methods like print() to log any sensitive or debugging information to CloudWatch Logs. For an example, see Pre sign-up example: Deny sign-up if user name has fewer than five characters.

  • You can add a Lambda function in another AWS account as a trigger for your user pool. You must add cross-account triggers with the CreateUserPool and UpdateUserPool API operations, or their equivalents in AWS CloudFormation and the AWS CLI. You can't add cross-account functions in the AWS Management Console.

  • When you add a Lambda trigger in the Amazon Cognito console, Amazon Cognito adds a resource-based policy to your function that permits your user pool to invoke the function. When you create a Lambda trigger outside of the Amazon Cognito console, including a cross-account function, you must add permissions to the resource-based policy of the Lambda function. Your added permissions must allow Amazon Cognito to invoke the function on behalf of your user pool. You can add permissions from the Lambda Console or use the Lambda AddPermission API operation.

    Example Lambda Resource-Based Policy

    The following example Lambda resource-based policy grants Amazon Cognito a limited ability to invoke a Lambda function. Amazon Cognito can only invoke the function when it does so on behalf of both the user pool in the aws:SourceArn condition and the account in the aws:SourceAccount condition.

    { "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "lambda-allow-cognito", "Effect": "Allow", "Principal": { "Service": "cognito-idp.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "<your Lambda function ARN>", "Condition": { "StringEquals": { "AWS:SourceAccount": "<your account number>" }, "ArnLike": { "AWS:SourceArn": "<your user pool ARN>" } } } ] }

Adding a user pool Lambda trigger

To add a user pool Lambda trigger with the console
  1. Use the Lambda console to create a Lambda function. For more information on Lambda functions, see the AWS Lambda Developer Guide.

  2. Go to the Amazon Cognito console, and then choose User Pools.

  3. Choose an existing user pool from the list, or create a user pool.

  4. Choose the User pool properties tab and locate Lambda triggers.

  5. Choose Add a Lambda trigger.

  6. Select a Lambda trigger Category based on the stage of authentication that you want to customize.

  7. Select Assign Lambda function and select a function in the same AWS Region as your user pool.

    Note

    If your AWS Identity and Access Management (IAM) credentials have permission to update the Lambda function, Amazon Cognito adds a Lambda resource-based policy. With this policy, Amazon Cognito can invoke the function that you select. If the signed-in credentials do not have sufficient IAM permissions, you must update the resource-based policy separately. For more information, see Important considerations.

  8. Choose Save changes.

  9. You can use CloudWatch in the Lambda console to log your Lambda function . For more information, see Accessing CloudWatch Logs for Lambda.

User pool Lambda trigger event

Amazon Cognito passes event information to your Lambda function. The Lambda function returns the same event object back to Amazon Cognito with any changes in the response. This event shows the Lambda trigger common parameters:

JSON
{ "version": "string", "triggerSource": "string", "region": AWSRegion, "userPoolId": "string", "userName": "string", "callerContext": { "awsSdkVersion": "string", "clientId": "string" }, "request": { "userAttributes": { "string": "string", .... } }, "response": {} }

User pool Lambda trigger common parameters

version

The version number of your Lambda function.

triggerSource

The name of the event that triggered the Lambda function. For a description of each triggerSource see Connecting Lambda triggers to user pool functional operations.

region

The AWS Region as an AWSRegion instance.

userPoolId

The ID of the user pool.

userName

The current user's username.

callerContext

Metadata about the request and the code environment. It contains the fields awsSdkVersion and clientId.

awsSdkVersion

The version of the AWS SDK that generated the request.

clientId

The ID of the user pool app client.

request

Details of your user's API request. It includes the following fields, and any request parameters that are particular to the trigger. For example, an event that Amazon Cognito sends to a pre-authentication trigger will also contain a userNotFound parameter. You can process the value of this parameter to take a custom action when your user tries to sign in with an unregistered username.

userAttributes

One or more key-value pairs of user attribute names and values, for example "email": "john@example.com".

response

This parameter doesn't contain any information in the original request. Your Lambda function must return the entire event to Amazon Cognito, and add any return parameters to the response. To see what return parameters your function can include, refer to the documentation for the trigger that you want to use.

Connecting API operations to Lambda triggers

The following sections describe the Lambda triggers that Amazon Cognito invokes from the activity in your user pool.

When your app signs in users through the Amazon Cognito user pools API, hosted UI, or user pool endpoints, Amazon Cognito invokes your Lambda functions based on the session context. For more information about the Amazon Cognito user pools API and user pool endpoints, see Using the user pools API and authorization server. The tables in the sections that follow describe events that cause Amazon Cognito to invoke a function, and the triggerSource string that Amazon Cognito includes in the request.

Lambda triggers in the Amazon Cognito API

The following table describes the source strings for the Lambda triggers that Amazon Cognito can invoke when your app creates, signs in, or updates a local user.

Local user trigger sources in the Amazon Cognito API
API operation Lambda trigger Trigger source

AdminCreateUser

Pre sign-up

PreSignUp_AdminCreateUser

Pre token generation

TokenGeneration_NewPasswordChallenge

Custom message

CustomMessage_AdminCreateUser

Custom email sender

CustomEmailSender_AdminCreateUser

Custom SMS sender

CustomSMSSender_AdminCreateUser

SignUp

Pre sign-up

PreSignUp_SignUp

Custom message

CustomMessage_SignUp

Custom email sender

CustomEmailSender_SignUp

Custom SMS sender

CustomSMSSender_SignUp

ConfirmSignUp

AdminConfirmSignUp

Post confirmation

PostConfirmation_ConfirmSignUp

InitiateAuth

AdminInitiateAuth

Pre authentication

PreAuthentication_Authentication

Define auth challenge

DefineAuthChallenge_Authentication

Create auth challenge

CreateAuthChallenge_Authentication

Pre token generation

TokenGeneration_Authentication

TokenGeneration_AuthenticateDevice

TokenGeneration_RefreshTokens

Migrate user

UserMigration_Authentication

Custom message

CustomMessage_Authentication

Custom email sender

CustomEmailSender_AccountTakeOverNotification

CustomEmailSender_Authentication

Custom SMS sender

CustomSMSSender_Authentication

ForgotPassword

Migrate user

UserMigration_ForgotPassword

Custom message

CustomMessage_ForgotPassword

Custom email sender

CustomEmailSender_ForgotPassword

Custom SMS sender

CustomSMSSender_ForgotPassword

ConfirmForgotPassword

Post confirmation

PostConfirmation_ConfirmForgotPassword

UpdateUserAttributes

AdminUpdateUserAttributes

Custom message

CustomMessage_UpdateUserAttribute

Custom email sender

CustomEmailSender_UpdateUserAttribute

Custom SMS sender

CustomSMSSender_UpdateUserAttribute

VerifyUserAttributes

Custom message

CustomMessage_VerifyUserAttribute

Custom email sender

CustomEmailSender_VerifyUserAttribute

Custom SMS sender

CustomSMSSender_VerifyUserAttribute

Lambda triggers for Amazon Cognito local users in the hosted UI

The following table describes the source strings for the Lambda triggers that Amazon Cognito can invoke when a local user signs in to your user pool with the hosted UI.

Local user trigger sources in the hosted UI
Hosted UI URI Lambda trigger Trigger source
/signup Pre sign-up

PreSignUp_SignUp

Custom message

CustomMessage_SignUp

Custom email sender

CustomEmailSender_SignUp

Custom SMS sender

CustomSMSSender_SignUp

/confirmuser Post confirmation

PostConfirmation_ConfirmSignUp

/login Pre authentication

PreAuthentication_Authentication

Define auth challenge

DefineAuthChallenge_Authentication

Create auth challenge

CreateAuthChallenge_Authentication

Pre token generation

TokenGeneration_Authentication

TokenGeneration_AuthenticateDevice

TokenGeneration_RefreshTokens

Migrate user

UserMigration_Authentication

Custom message

CustomMessage_Authentication

Custom email sender

CustomEmailSender_AccountTakeOverNotification

CustomEmailSender_Authentication

Custom SMS sender

CustomSMSSender_Authentication

/forgotpassword Migrate user

UserMigration_ForgotPassword

Custom message

CustomMessage_ForgotPassword

Custom email sender

CustomEmailSender_ForgotPassword

Custom SMS sender

CustomSMSSender_ForgotPassword

/confirmforgotpassword Post confirmation

PostConfirmation_ConfirmForgotPassword

Lambda triggers for federated users

You can use the following Lambda triggers to customize your user pool workflows for users who sign in with a federated provider.

Note

Federated users can use the Amazon Cognito hosted UI to sign in, or you can generate a request to the Authorize endpoint that silently redirects them to their identity provider sign-in page. You can't sign in federated users with the Amazon Cognito user pools API.

Federated user trigger sources
Sign-in event Lambda trigger Trigger source
First sign-in Pre sign-up

PreSignUp_ExternalProvider

Post confirmation

PostConfirmation_ConfirmSignUp

Pre token generation

TokenGeneration_HostedAuth

Subsequent sign-ins Pre authentication

PreAuthentication_Authentication

Post authentication

PostAuthentication_Authentication

Pre token generation

TokenGeneration_HostedAuth

Federated sign-in does not invoke any Custom authentication challenge Lambda triggers, Migrate user Lambda trigger, Custom message Lambda trigger, or Custom sender Lambda triggers in your user pool.

Connecting Lambda triggers to user pool functional operations

Each Lambda trigger serves a functional role in your user pool. For example, a trigger can modify your sign-up flow, or add a custom authentication challenge. The event that Amazon Cognito sends to a Lambda function can reflect one of multiple actions that make up that functional role. For example, Amazon Cognito invokes a pre sign-up trigger when your user signs up, and when you create a user. Each of these different cases for the same functional role has its own triggerSource value. Your Lambda function can process incoming events differently based on the operation that invoked it.

Amazon Cognito also invokes all assigned functions when an event corresponds to a trigger source. For example, when a user signs in to a user pool where you assigned migrate user and pre authentication triggers, they activate both.

Sign-up, confirmation, and sign-in (authentication) triggers
Trigger triggerSource value Event
Pre sign-up PreSignUp_SignUp Pre sign-up.
Pre sign-up PreSignUp_AdminCreateUser Pre sign-up when an admin creates a new user.
Pre sign-up PreSignUp_ExternalProvider Pre sign-up for external identity providers.
Post confirmation PostConfirmation_ConfirmSignUp Post sign-up confirmation.
Post confirmation PostConfirmation_ConfirmForgotPassword Post Forgot Password confirmation.
Pre authentication PreAuthentication_Authentication Pre authentication.
Post authentication PostAuthentication_Authentication Post authentication.
Custom authentication challenge triggers
Trigger triggerSource value Event
Define auth challenge DefineAuthChallenge_Authentication Define Auth Challenge.
Create auth challenge CreateAuthChallenge_Authentication Create Auth Challenge.
Verify auth challenge VerifyAuthChallengeResponse_Authentication Verify Auth Challenge Response.
Pre token generation triggers
Trigger triggerSource value Event
Pre token generation TokenGeneration_HostedAuth Amazon Cognito authenticates the user from your hosted UI sign-in page.
Pre token generation TokenGeneration_Authentication User authentication flows complete.
Pre token generation TokenGeneration_NewPasswordChallenge Admin creates the user. Amazon Cognito invokes this when the user must change a temporary password.
Pre token generation TokenGeneration_AuthenticateDevice End of the authentication of a user device.
Pre token generation TokenGeneration_RefreshTokens User tries to refresh the identity and access tokens.
Migrate user triggers
Trigger triggerSource value Event
User migration UserMigration_Authentication User migration at the time of sign-in.
User migration UserMigration_ForgotPassword User migration during the forgot-password flow.
Custom message triggers
Trigger triggerSource value Event
Custom message CustomMessage_SignUp Custom message when a user signs up in your user pool.
Custom message CustomMessage_AdminCreateUser Custom message when you create a user as an administrator and Amazon Cognito sends them a temporary password.
Custom message CustomMessage_ResendCode Custom message when your existing user requests a new confirmation code.
Custom message CustomMessage_ForgotPassword Custom message when your user requests a password reset.
Custom message CustomMessage_UpdateUserAttribute Custom message when a user changes their email address or phone number and Amazon Cognito sends a verification code.
Custom message CustomMessage_VerifyUserAttribute Custom message when a user adds an email address or phone number and Amazon Cognito sends a verification code.
Custom message CustomMessage_Authentication Custom message when a user who has configured SMS MFA signs in.