How do I allow API Gateway REST API users to run Lambda using the execution role from an Amazon Cognito user pool group?

Last updated: 2021-10-07

My Amazon API Gateway REST API with AWS Lambda proxy integration has Amazon Cognito user pool authentication. How do I allow my API users to run my Lambda function using the AWS Identity and Access Management (IAM) role associated with their user pool group, instead of using the default Lambda execution role?

Resolution

Note: In addition to Amazon Cognito user pools, you can also configure an identity pool to authorize access to your API. For more information, see Role-based access control.

Before you set up users to run Lambda with their Amazon Cognito role, be sure that you've set up the following:

To allow users to run Lambda with their Amazon Cognito permissions, follow these steps:

  1. Use the API Gateway console to establish your Amazon Cognito user pool as an authorizer. Then, assign the Amazon Cognito user pool as the authorizer for the method of your API. For instructions, see Integrate a REST API with an Amazon Cognito user pool.
  2. Open the AWS Lambda console.
  3. Choose the Lambda function that was configured as a proxy resource for your API.
  4. Configure the Lambda function, and add the following code snippet. This code snippet gets the Amazon Cognito role from event details and then assumes the role.

Note: To run this code snippet, your Lambda IAM role must have permissions to access Amazon CloudWatch Logs and the AssumeRole API call to run the assume_role command.

import boto3
client = boto3.client('sts')
def lambda_handler(event, context):
    role=event['requestContext']['authorizer']['claims']['cognito:roles']
    response = client.assume_role(
        RoleArn=role,
        RoleSessionName='APIrole'
    )
    print(response)
    response2api = {"statusCode": 200,"headers": { },"body": "Success"}
    return response2api

A user can belong to more than one Amazon Cognito user pool group, and each group can have a different IAM role. If a user belongs to two or more groups, the cognito:roles claim returns a list of roles. The cognito:preferred_role claim in the user's ID token inherits the IAM role of the group with the highest priority (lowest precedence value). For more information, see Role-based access control.

To get the cognito:preferred_role, use the following code snippet:

role = event['requestContext']['authorizer']['claims']['cognito:preferred_role']

To verify that users can run Lambda with their Amazon Cognito role, follow these steps:

  1. Open your client application, and then log in as a user in the Amazon Cognito user pool.
  2. Make a call to your API using the ID token you receive after you log in.
    Note: Make sure that you use the id_token value from the returned tokens.
  3. Verify that you can access the same resources defined in the Amazon Cognito user pool role.
  4. Optionally, check CloudWatch Logs to verify that the assume_role command was successful.

Note: If you use an API Gateway Lambda authorizer instead of a user pool authorizer to authorize access to your API, be sure that you use the user pool token that is validated by the authorizer. You must validate the token before you assume the token's role.