

# Custom authentication challenge Lambda triggers
<a name="user-pool-lambda-challenge"></a>

As you build out your authentication flows for your Amazon Cognito user pool, you might find that you want to extend your authentication model beyond the built-in flows. One common use case for the custom challenge triggers is to implement additional security checks beyond username, password, and multi-factor authentication (MFA). A custom challenge is any question and response you can generate in a Lambda-supported programming language. For example, you might want to require users to solve a CAPTCHA or answer a security question before being allowed to authenticate. Another potential need is to integrate with specialized authentication factors or devices. Or you might have already developed software that authenticates users with a hardware security key or a biometric device. The definition of authentication success for a custom challenge is whatever answer your Lambda function accepts as correct: a fixed string, for example, or a satisfactory response from an external API.

You can start authentication with your custom challenge and control the authentication process entirely, or you can perform username-password authentication before your application receives your custom challenge.

The custom authentication challenge Lambda trigger:

**[Defines](user-pool-lambda-define-auth-challenge.md)**  
Initiates a challenge sequence. Determines whether you want to initiate a new challenge, mark authentication as complete, or halt the authentication attempt.

**[Creates](user-pool-lambda-create-auth-challenge.md)**  
Issues the question to your application that the user must answer. This function might present a security question or a link to a CAPTCHA that your application should display to your user.

**[Verifies](user-pool-lambda-verify-auth-challenge-response.md)**  
Knows the expected answer and compares it to the answer your application provides in the challenge response. The function might call the API of your CAPTCHA service to retrieve the expected results of your user's attempted solution.

These three Lambda functions chain together to present an authentication mechanism that is completely within your control and of your own design. Because custom authentication requires application logic in your client and in the Lambda functions, you can't process custom authentication within managed login. This authentication system requires additional developer effort. Your application must perform the authentication flow with the user pools API and handle the resulting challenge with a custom-built login interface that renders the question at the center of the custom authentication challenge.

![\[Challenge Lambda triggers\]](http://docs.aws.amazon.com/cognito/latest/developerguide/images/lambda-challenges.png)


For more information about implementing custom authentication, see [Custom authentication flow and challenges](amazon-cognito-user-pools-authentication-flow-methods.md#Custom-authentication-flow-and-challenges)

Authentication between the API operations [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) or [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html), and [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) or [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html). In this flow, a user authenticates by answering successive challenges until authentication either fails or the user is issued tokens. A challenge response might be a new challenge. In this case, your application responds as many times as necessary to new challenges. Successful authentication happens when the define auth challenge function analyzes the results so far, determines all challenges have been answered, and returns `IssueTokens`.

**Topics**
+ [SRP authentication in custom challenge flows](#user-pool-lambda-challenge-srp-authentication)
+ [Define Auth challenge Lambda trigger](user-pool-lambda-define-auth-challenge.md)
+ [Create Auth challenge Lambda trigger](user-pool-lambda-create-auth-challenge.md)
+ [Verify Auth challenge response Lambda trigger](user-pool-lambda-verify-auth-challenge-response.md)

## SRP authentication in custom challenge flows
<a name="user-pool-lambda-challenge-srp-authentication"></a>

You can have Amazon Cognito verify user passwords before it issues your custom challenges. Any Lambda triggers associated in the Authentication category of [request-rate quotas](quotas.md#category_operations.title) will run when you perform SRP authentication in a custom challenge flow. Here is an overview of the process:

1. Your app initiates sign-in by calling `InitiateAuth` or `AdminInitiateAuth` with the `AuthParameters` map. Parameters must include `CHALLENGE_NAME: SRP_A,` and values for `SRP_A` and `USERNAME`.

1. Amazon Cognito invokes your define auth challenge Lambda trigger with an initial session that contains `challengeName: SRP_A` and `challengeResult: true`.

1. After receiving those inputs, your Lambda function responds with `challengeName: PASSWORD_VERIFIER`, `issueTokens: false`, `failAuthentication: false`.

1. If the password verification succeeds, Amazon Cognito invokes your Lambda function again with a new session containing `challengeName: PASSWORD_VERIFIER` and `challengeResult: true`.

1. To initiate your custom challenges, your Lambda function responds with `challengeName: CUSTOM_CHALLENGE`, `issueTokens: false`, and `failAuthentication: false`. If you don't want to start your custom auth flow with password verification, you can initiate sign-in with the `AuthParameters` map including `CHALLENGE_NAME: CUSTOM_CHALLENGE`.

1. The challenge loop repeats until all challenges are answered.

The following is an example of a starting `InitiateAuth` request that precedes custom authentication with an SRP flow.

```
{
    "AuthFlow": "CUSTOM_AUTH",
    "ClientId": "1example23456789",
    "AuthParameters": {
        "CHALLENGE_NAME": "SRP_A",
        "USERNAME": "testuser",
        "SRP_A": "[SRP_A]",
        "SECRET_HASH": "[secret hash]"
    }
}
```

### Password reset in the custom authentication SRP flow
<a name="user-pool-lambda-challenge-force-password-change"></a>

When users are in `FORCE_CHANGE_PASSWORD` status, your custom authentication flow must integrate the password change step while maintaining the integrity of your authentication challenges. Amazon Cognito invokes your [define auth challenge](user-pool-lambda-define-auth-challenge.md) Lambda trigger during the `NEW_PASSWORD_REQUIRED` challenge. In this scenario, a user signing in with a custom challenge flow and SRP authentication can set a new password if they are in a password-reset state.

When users are in the `RESET_REQUIRED` or `FORCE_CHANGE_PASSWORD` status, they must [respond](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html#API_RespondToAuthChallenge_RequestParameters) to a `NEW_PASSWORD_REQUIRED` challenge with a `NEW_PASSWORD`. In custom authentication with SRP, Amazon Cognito returns a `NEW_PASSWORD_REQUIRED` challenge after users complete the SRP `PASSWORD_VERIFIER` challenge. Your define auth challenge trigger receives both challenge results in the `session` array, and can proceed with additional custom challenges after the user successfully changes their password.

Your define auth challenge Lambda trigger must manage the challenge sequence through SRP authentication, password reset, and subsequent custom challenges. The trigger receives an array of completed challenges in the `session` parameter, including both `PASSWORD_VERIFIER` and `NEW_PASSWORD_REQUIRED` results. For an example implementation, see [Define Auth challenge example](user-pool-lambda-define-auth-challenge.md#aws-lambda-triggers-define-auth-challenge-example).

#### Authentication flow steps
<a name="user-pool-lambda-challenge-password-flow-steps"></a>

For users who need to verify their password before custom challenges, the process follows these steps:

1. Your app initiates sign-in by calling `InitiateAuth` or `AdminInitiateAuth` with the `AuthParameters` map. Parameters must include `CHALLENGE_NAME: SRP_A`, and values for `SRP_A` and `USERNAME`.

1. Amazon Cognito invokes your define auth challenge Lambda trigger with an initial session that contains `challengeName: SRP_A` and `challengeResult: true`.

1. After receiving those inputs, your Lambda function responds with `challengeName: PASSWORD_VERIFIER`, `issueTokens: false`, `failAuthentication: false`.

1. If the password verification succeeds, one of two things happens:  
**For users in normal status:**  
Amazon Cognito invokes your Lambda function again with a new session containing `challengeName: PASSWORD_VERIFIER` and `challengeResult: true`.  
To initiate your custom challenges, your Lambda function responds with `challengeName: CUSTOM_CHALLENGE`, `issueTokens: false`, and `failAuthentication: false`.  
**For users in `RESET_REQUIRED` or `FORCE_CHANGE_PASSWORD` status:**  
Amazon Cognito invokes your Lambda function with a session containing `challengeName: PASSWORD_VERIFIER` and `challengeResult: true`.  
Your Lambda function should respond with `challengeName: NEW_PASSWORD_REQUIRED`, `issueTokens: false`, and `failAuthentication: false`.  
After successful password change, Amazon Cognito invokes your Lambda function with a session containing both the `PASSWORD_VERIFIER` and `NEW_PASSWORD_REQUIRED` results.  
To initiate your custom challenges, your Lambda function responds with `challengeName: CUSTOM_CHALLENGE`, `issueTokens: false`, and `failAuthentication: false`.

1. The challenge loop repeats until all challenges are answered.

If you don't want to start your custom auth flow with password verification, you can initiate sign-in with the `AuthParameters` map including `CHALLENGE_NAME: CUSTOM_CHALLENGE`.

#### Session management
<a name="user-pool-lambda-challenge-session-management"></a>

The authentication flow maintains session continuity through a series of session IDs and challenge results. Each challenge response generates a new session ID to prevent session reuse errors, which is particularly important for multi-factor authentication flows.

Challenge results are stored chronologically in the session array that your Lambda triggers receive. For users in `FORCE_CHANGE_PASSWORD` status, the session array contains:

1. `session[0]` - Initial `SRP_A` challenge

1. `session[1]` - `PASSWORD_VERIFIER` result

1. `session[2]` - `NEW_PASSWORD_REQUIRED` result

1. Subsequent elements - Results of additional custom challenges

#### Example authentication flow
<a name="user-pool-lambda-challenge-example-flow"></a>

The following example demonstrates a complete custom authentication flow for a user in `FORCE_CHANGE_PASSWORD` status who must complete both password change and a custom CAPTCHA challenge.

1. **InitiateAuth request**

   ```
   {
       "AuthFlow": "CUSTOM_AUTH",
       "ClientId": "1example23456789",
       "AuthParameters": {
           "CHALLENGE_NAME": "SRP_A",
           "USERNAME": "testuser",
           "SRP_A": "[SRP_A]"
       }
   }
   ```

1. **InitiateAuth response**

   ```
   {
       "ChallengeName": "PASSWORD_VERIFIER",
       "ChallengeParameters": {
           "USER_ID_FOR_SRP": "testuser"
       },
       "Session": "[session_id_1]"
   }
   ```

1. **RespondToAuthChallenge request with `PASSWORD_VERIFIER`**

   ```
   {
       "ChallengeName": "PASSWORD_VERIFIER",
       "ClientId": "1example23456789",
       "ChallengeResponses": {
           "PASSWORD_CLAIM_SIGNATURE": "[claim_signature]",
           "PASSWORD_CLAIM_SECRET_BLOCK": "[secret_block]",
           "TIMESTAMP": "[timestamp]",
           "USERNAME": "testuser"
       },
       "Session": "[session_id_1]"
   }
   ```

1. **RespondToAuthChallenge response with `NEW_PASSWORD_REQUIRED` challenge**

   ```
   {
       "ChallengeName": "NEW_PASSWORD_REQUIRED",
       "ChallengeParameters": {},
       "Session": "[session_id_2]"
   }
   ```

1. **RespondToAuthChallenge request with `NEW_PASSWORD_REQUIRED`**

   ```
   {
       "ChallengeName": "NEW_PASSWORD_REQUIRED",
       "ClientId": "1example23456789",
       "ChallengeResponses": {
           "NEW_PASSWORD": "[password]",
           "USERNAME": "testuser"
       },
       "Session": "[session_id_2]"
   }
   ```

1. **RespondToAuthChallenge response with CAPTCHA custom challenge**

   ```
   {
       "ChallengeName": "CUSTOM_CHALLENGE",
       "ChallengeParameters": {
           "captchaUrl": "url/123.jpg"
       },
       "Session": "[session_id_3]"
   }
   ```

1. **RespondToAuthChallenge request with answer to CAPTCHA custom challenge**

   ```
   {
       "ChallengeName": "CUSTOM_CHALLENGE",
       "ClientId": "1example23456789",
       "ChallengeResponses": {
           "ANSWER": "123",
           "USERNAME": "testuser"
       },
       "Session": "[session_id_3]"
   }
   ```

**6. Final success response**

```
{
    "AuthenticationResult": {
        "AccessToken": "eyJra456defEXAMPLE",
        "ExpiresIn": 3600,
        "IdToken": "eyJra789ghiEXAMPLE",
        "RefreshToken": "eyJjd123abcEXAMPLE",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}
```

# Define Auth challenge Lambda trigger
<a name="user-pool-lambda-define-auth-challenge"></a>

The define auth challenge trigger is a Lambda function that maintains the challenge sequence in a custom authentication flow. It declares success or failure of the challenge sequence, and sets the next challenge if the sequence isn't yet complete.

![\[Challenge Lambda triggers\]](http://docs.aws.amazon.com/cognito/latest/developerguide/images/lambda-challenges1.png)


**Define auth challenge**  
 Amazon Cognito invokes this trigger to initiate the [custom authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-custom-authentication-flow).

The request for this Lambda trigger contains `session`. The `session` parameter is an array that contains all of the challenges that are presented to the user in the current authentication process. The request also includes the corresponding result. The `session` array stores challenge details (`ChallengeResult`) in chronological order. The challenge `session[0]` represents the first challenge that the user receives.

**Topics**
+ [Define Auth challenge Lambda trigger parameters](#cognito-user-pools-lambda-trigger-syntax-define-auth-challenge)
+ [Define Auth challenge example](#aws-lambda-triggers-define-auth-challenge-example)

## Define Auth challenge Lambda trigger parameters
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge"></a>

The request that Amazon Cognito passes to this Lambda function is a combination of the parameters below and the [common parameters](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared) that Amazon Cognito adds to all requests.

------
#### [ JSON ]

```
{
    "request": {
        "userAttributes": {
            "string": "string",
                . . .
        },
        "session": [
            ChallengeResult,
            . . .
        ],
        "clientMetadata": {
            "string": "string",
            . . .
        },
        "userNotFound": boolean
    },
    "response": {
        "challengeName": "string",
        "issueTokens": boolean,
        "failAuthentication": boolean
    }
}
```

------

### Define Auth challenge request parameters
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge-request"></a>

 When Amazon Cognito invokes your Lambda function, Amazon Cognito provides the following parameters:

**userAttributes**  
One or more name-value pairs that represent user attributes.

**userNotFound**  
A Boolean that Amazon Cognito populates when `PreventUserExistenceErrors` is set to `ENABLED` for your user pool client. A value of `true` means that the user id (username, email address, and other details) did not match any existing users. When `PreventUserExistenceErrors` is set to `ENABLED`, the service doesn't inform the app of nonexistent users. We recommend that your Lambda functions maintain the same user experience and account for latency. This way, the caller can't detect different behavior when the user exists or doesn’t exist.

**session**  
An array of `ChallengeResult` elements. Each contains the following elements:    
**challengeName**  
One of the following challenge types: `CUSTOM_CHALLENGE`, `SRP_A`, `PASSWORD_VERIFIER`, `SMS_MFA`, `EMAIL_OTP`, `SOFTWARE_TOKEN_MFA`, `DEVICE_SRP_AUTH`, `DEVICE_PASSWORD_VERIFIER`, or `ADMIN_NO_SRP_AUTH`.  
When your define auth challenge function issues a `PASSWORD_VERIFIER` challenge for a user who has set up multifactor authentication, Amazon Cognito follows it up with an `SMS_MFA`, `EMAIL_OTP`, or `SOFTWARE_TOKEN_MFA` challenge. These are the prompts for a multi-factor authentication code. In your function, include handling for input events from `SMS_MFA`, `EMAIL_OTP`, and `SOFTWARE_TOKEN_MFA` challenges. You don't need to invoke any MFA challenges in your define auth challenge function.  
When your function is determining whether a user has successfully authenticated and you should issue them tokens, always check `challengeName` in your define auth challenge function and verify that it matches the expected value.  
**challengeResult**  
Set to `true` if the user successfully completed the challenge, or `false` otherwise.  
**challengeMetadata**  
Your name for the custom challenge. Used only if `challengeName` is `CUSTOM_CHALLENGE`.

**clientMetadata**  
One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the define auth challenge trigger. To pass this data to your Lambda function, you can use the `ClientMetadata` parameter in the [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html) and [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) API operations. The request that invokes the define auth challenge function doesn't include data passed in the ClientMetadata parameter in [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html) and [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API operations.

### Define Auth challenge response parameters
<a name="cognito-user-pools-lambda-trigger-syntax-define-auth-challenge-response"></a>

In the response, you can return the next stage of the authentication process.

**challengeName**  
A string that contains the name of the next challenge. If you want to present a new challenge to your user, specify the challenge name here.

**issueTokens**  
If you determine that the user has completed the authentication challenges sufficiently, set to `true`. If the user has not met the challenges sufficiently, set to `false`.

**failAuthentication**  
If you want to end the current authentication process, set to `true`. To continue the current authentication process, set to `false`.

## Define Auth challenge example
<a name="aws-lambda-triggers-define-auth-challenge-example"></a>

This example defines a series of challenges for authentication and issues tokens only if the user has completed all of the challenges successfully. When users complete SRP authentication with the `SRP_A` and `PASSWORD_VERIFIER` challenges, this function passes them a `CUSTOM_CHALLENGE` that invokes the create auth challenge trigger. In combination with our [create auth challenge example](user-pool-lambda-create-auth-challenge.md#aws-lambda-triggers-create-auth-challenge-example), this sequence delivers a CAPTCHA challenge for challenge three and a security question for challenge four.

After the user solves the CAPTCHA and answers the security question, this function confirms that your user pool can issue tokens. SRP authentication isn't required; you can also set the CAPTCHA and security question as challenges one & two. In the case where your define auth challenge function doesn't declare SRP challenges, your users' success is determined entirely by their responses to your custom prompts.

------
#### [ Node.js ]

```
const handler = async (event) => {
  if (
    event.request.session.length === 1 &&
    event.request.session[0].challengeName === "SRP_A"
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "PASSWORD_VERIFIER";
  } else if (
    event.request.session.length === 2 &&
    event.request.session[1].challengeName === "PASSWORD_VERIFIER" &&
    event.request.session[1].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 3 &&
    event.request.session[2].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[2].challengeResult === true
  ) {
    event.response.issueTokens = false;
    event.response.failAuthentication = false;
    event.response.challengeName = "CUSTOM_CHALLENGE";
  } else if (
    event.request.session.length === 4 &&
    event.request.session[3].challengeName === "CUSTOM_CHALLENGE" &&
    event.request.session[3].challengeResult === true
  ) {
    event.response.issueTokens = true;
    event.response.failAuthentication = false;
  } else {
    event.response.issueTokens = false;
    event.response.failAuthentication = true;
  }

  return event;
};

export { handler };
```

------

# Create Auth challenge Lambda trigger
<a name="user-pool-lambda-create-auth-challenge"></a>

The create auth challenge trigger is a Lambda function that has the details of each challenge declared by the define auth challenge trigger. It processes the challenge name declared by the define auth challenge trigger and returns a `publicChallengeParameters` that your application must present to the user. This function then provides your user pool with the answer to the challenge, `privateChallengeParameters`, that your user pool passes to the verify auth challenge trigger. Where your define auth challenge trigger manages the challenge sequence, your create auth challenge trigger manages the challenge contents.

![\[Challenge Lambda triggers\]](http://docs.aws.amazon.com/cognito/latest/developerguide/images/lambda-challenges2.png)


**Create auth challenge**  
Amazon Cognito invokes this trigger after **Define Auth Challenge** if a custom challenge has been specified as part of the **Define Auth Challenge** trigger. It creates a [custom authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-custom-authentication-flow).

This Lambda trigger is invoked to create a challenge to present to the user. The request for this Lambda trigger includes the `challengeName` and `session`. The `challengeName` is a string and is the name of the next challenge to the user. The value of this attribute is set in the Define Auth Challenge Lambda trigger.

The challenge loop will repeat until all challenges are answered.

**Topics**
+ [Create Auth challenge Lambda trigger parameters](#cognito-user-pools-lambda-trigger-syntax-create-auth-challenge)
+ [Create Auth challenge example](#aws-lambda-triggers-create-auth-challenge-example)

## Create Auth challenge Lambda trigger parameters
<a name="cognito-user-pools-lambda-trigger-syntax-create-auth-challenge"></a>

The request that Amazon Cognito passes to this Lambda function is a combination of the parameters below and the [common parameters](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared) that Amazon Cognito adds to all requests.

------
#### [ JSON ]

```
{
    "request": {
        "userAttributes": {
            "string": "string",
            . . .
        },
        "challengeName": "string",
        "session": [
            ChallengeResult,
            . . .
        ],
        "clientMetadata": {
            "string": "string",
            . . .
        },
        "userNotFound": boolean
    },
    "response": {
        "publicChallengeParameters": {
            "string": "string",
            . . .
        },
        "privateChallengeParameters": {
            "string": "string",
            . . .
        },
        "challengeMetadata": "string"
    }
}
```

------

### Create Auth challenge request parameters
<a name="cognito-user-pools-lambda-trigger-syntax-create-auth-challenge-request"></a>

**userAttributes**  
One or more name-value pairs representing user attributes.

**userNotFound**  
This boolean is populated when `PreventUserExistenceErrors` is set to `ENABLED` for your User Pool client.

**challengeName**  
The name of the new challenge.

**session**  
The session element is an array of `ChallengeResult` elements, each of which contains the following elements:    
**challengeName**  
The challenge type. One of: `"CUSTOM_CHALLENGE"`, `"PASSWORD_VERIFIER"`, `"SMS_MFA"`, `"DEVICE_SRP_AUTH"`, `"DEVICE_PASSWORD_VERIFIER"`, `"NEW_PASSWORD_REQUIRED"`, or `"ADMIN_NO_SRP_AUTH"`.   
**challengeResult**  
Set to `true` if the user successfully completed the challenge, or `false` otherwise.  
**challengeMetadata**  
Your name for the custom challenge. Used only if `challengeName` is `"CUSTOM_CHALLENGE"`.

**clientMetadata**  
One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the create auth challenge trigger. You can use the ClientMetadata parameter in the [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html) and [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) API actions to pass this data to your Lambda function. The request that invokes the create auth challenge function does not include data passed in the ClientMetadata parameter in [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html) and [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API operations.

### Create Auth challenge response parameters
<a name="cognito-user-pools-lambda-trigger-syntax-create-auth-challenge-response"></a>

**publicChallengeParameters**  
One or more key-value pairs for the client app to use in the challenge to be presented to the user. This parameter should contain all of the necessary information to present the challenge to the user accurately.

**privateChallengeParameters**  
This parameter is only used by the Verify Auth Challenge Response Lambda trigger. This parameter should contain all of the information that is required to validate the user's response to the challenge. In other words, the `publicChallengeParameters` parameter contains the question that is presented to the user and `privateChallengeParameters` contains the valid answers for the question.

**challengeMetadata**  
Your name for the custom challenge, if this is a custom challenge.

## Create Auth challenge example
<a name="aws-lambda-triggers-create-auth-challenge-example"></a>

This function has two custom challenges that correspond to the challenge sequence in our [define auth challenge example](user-pool-lambda-define-auth-challenge.md#aws-lambda-triggers-define-auth-challenge-example). The first two challenges are SRP authentication. For the third challenge, this function returns a CAPTCHA URL to your application in the challenge response. Your application renders the CAPTCHA at the given URL and returns the user's input. The URL for the CAPTCHA image is added to the public challenge parameters as "`captchaUrl`", and the expected answer is added to the private challenge parameters.

For the fourth challenge, this function returns a security question. Your application renders the question and prompts the user for their answer. After users solve both custom challenges, the define auth challenge trigger confirms that your user pool can issue tokens.

------
#### [ Node.js ]

```
const handler = async (event) => {
  if (event.request.challengeName !== "CUSTOM_CHALLENGE") {
    return event;
  }

  if (event.request.session.length === 2) {
    event.response.publicChallengeParameters = {};
    event.response.privateChallengeParameters = {};
    event.response.publicChallengeParameters.captchaUrl = "url/123.jpg";
    event.response.privateChallengeParameters.answer = "5";
  }

  if (event.request.session.length === 3) {
    event.response.publicChallengeParameters = {};
    event.response.privateChallengeParameters = {};
    event.response.publicChallengeParameters.securityQuestion =
      "Who is your favorite team mascot?";
    event.response.privateChallengeParameters.answer = "Peccy";
  }

  return event;
};

export { handler };
```

------

# Verify Auth challenge response Lambda trigger
<a name="user-pool-lambda-verify-auth-challenge-response"></a>

The verify auth challenge trigger is a Lambda function that compares a user's provided response to a known answer. This function tells your user pool whether the user answered the challenge correctly. When the verify auth challenge trigger responds with an `answerCorrect` of `true`, the authentication sequence can continue.

![\[Challenge Lambda triggers\]](http://docs.aws.amazon.com/cognito/latest/developerguide/images/lambda-challenges3.png)


**Verify auth challenge response**  
Amazon Cognito invokes this trigger to verify if the response from the user for a custom Auth Challenge is valid or not. It is part of a user pool [custom authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-custom-authentication-flow).

The request for this trigger contains the `privateChallengeParameters` and `challengeAnswer` parameters. The Create Auth Challenge Lambda trigger returns `privateChallengeParameters` values, and contains the expected response from the user. The `challengeAnswer` parameter contains the user's response for the challenge.

The response contains the `answerCorrect` attribute. If the user successfully completes the challenge, Amazon Cognito sets the attribute value to `true`. If the user doesn't successfully complete the challenge, Amazon Cognito sets the value to `false`.

The challenge loop repeats until the users answers all challenges.

**Topics**
+ [Verify Auth challenge Lambda trigger parameters](#cognito-user-pools-lambda-trigger-syntax-verify-auth-challenge)
+ [Verify Auth challenge response example](#aws-lambda-triggers-verify-auth-challenge-response-example)

## Verify Auth challenge Lambda trigger parameters
<a name="cognito-user-pools-lambda-trigger-syntax-verify-auth-challenge"></a>

The request that Amazon Cognito passes to this Lambda function is a combination of the parameters below and the [common parameters](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared) that Amazon Cognito adds to all requests.

------
#### [ JSON ]

```
{
    "request": {
        "userAttributes": {
            "string": "string",
            . . .
        },
        "privateChallengeParameters": {
            "string": "string",
            . . .
        },
        "challengeAnswer": "string",
        "clientMetadata": {
            "string": "string",
            . . .
        },
        "userNotFound": boolean
    },
    "response": {
        "answerCorrect": boolean
    }
}
```

------

### Verify Auth challenge request parameters
<a name="cognito-user-pools-lambda-trigger-syntax-verify-auth-challenge-request"></a>

**userAttributes**  
This parameter contains one or more name-value pairs that represent user attributes.

**userNotFound**  
When Amazon Cognito sets `PreventUserExistenceErrors` to `ENABLED` for your user pool client, Amazon Cognito populates this Boolean .

**privateChallengeParameters**  
This parameter comes from the Create Auth Challenge trigger. To determine whether the user passed a challenge, Amazon Cognito compares the parameters against a user’s **challengeAnswer**.  
This parameter contains all of the information that is required to validate the user's response to the challenge. That information includes the question that Amazon Cognito presents to the user (`publicChallengeParameters`), and the valid answers for the question (`privateChallengeParameters`). Only the Verify Auth Challenge Response Lambda trigger uses this parameter. 

**challengeAnswer**  
This parameter value is the answer from the user's response to the challenge.

**clientMetadata**  
This parameter contains one or more key-value pairs that you can provide as custom input to the Lambda function for the verify auth challenge trigger. To pass this data to your Lambda function, use the ClientMetadata parameter in the [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html) and [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) API operations. Amazon Cognito doesn't include data from the ClientMetadata parameter in [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html) and [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API operations in the request that it passes to the verify auth challenge function.

### Verify Auth challenge response parameters
<a name="cognito-user-pools-lambda-trigger-syntax-verify-auth-challenge-response"></a>

**answerCorrect**  
If the user successfully completes the challenge, Amazon Cognito sets this parameter to `true`. If the user doesn't successfully complete the challenge, Amazon Cognito sets the parameter to `false`. 

## Verify Auth challenge response example
<a name="aws-lambda-triggers-verify-auth-challenge-response-example"></a>

This verify auth challenge function checks whether the user's response to a challenge matches the expected response. The user's answer is defined by input from your application and the preferred answer is defined by `privateChallengeParameters.answer` in the response from the [create auth challenge trigger response](user-pool-lambda-create-auth-challenge.md#aws-lambda-triggers-create-auth-challenge-example). Both the correct answer and the given answer are part of the input event to this function.

In this example, if the user's response matches the expected response, Amazon Cognito sets the `answerCorrect` parameter to `true`.

------
#### [ Node.js ]

```
const handler = async (event) => {
  if (
    event.request.privateChallengeParameters.answer ===
    event.request.challengeAnswer
  ) {
    event.response.answerCorrect = true;
  } else {
    event.response.answerCorrect = false;
  }

  return event;
};

export { handler };
```

------