

# Use API Gateway Lambda authorizers
Use Lambda authorizers

Use a *Lambda authorizer* (formerly known as a *custom authorizer*) to control access to your API. When a client makes a request to your API's method, API Gateway calls your Lambda authorizer. The Lambda authorizer takes the caller's identity as the input and returns an IAM policy as the output.

Use a Lambda authorizer to implement a custom authorization scheme. Your scheme can use request parameters to determine the caller's identity or use a bearer token authentication strategy such as OAuth or SAML. Create a Lambda authorizer in the API Gateway REST API console, using the AWS CLI, or an AWS SDK.

## Lambda authorizer authorization workflow


The following diagram shows the authorization workflow for a Lambda authorizer.

![\[API Gateway Lambda authorization workflow\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/custom-auth-workflow.png)


**API Gateway Lambda authorization workflow**

1. The client calls a method on an API Gateway API, passing a bearer token or request parameters.

1. API Gateway checks if the method request is configured with a Lambda authorizer. If it is, API Gateway calls the Lambda function.

1. The Lambda function authenticates the caller. The function can authenticate in the following ways:
   + By calling out to an OAuth provider to get an OAuth access token.
   + By calling out to a SAML provider to get a SAML assertion.
   + By generating an IAM policy based on the request parameter values.
   + By retrieving credentials from a database.

1. The Lambda function returns an IAM policy and a principal identifier. If the Lambda function does not return that information, the call fails. 

1. API Gateway evaluates the IAM policy.
   + If access is denied, API Gateway returns a suitable HTTP status code, such as `403 ACCESS_DENIED`.
   + If access is allowed, API Gateway invokes the method. 

     If you enable authorization caching, API Gateway caches the policy so that the Lambda authorizer function isn’t invoked again. Ensure that your policy is applicable to all resources and methods across your API.

You can customize the `403 ACCESS_DENIED` or the `401 UNAUTHORIZED` gateway responses. To learn more, see [Gateway responses for REST APIs in API Gateway](api-gateway-gatewayResponse-definition.md).

## Choosing a type of Lambda authorizer
Choosing a type of Lambda authorizer

There are two types of Lambda authorizers:

**Request parameter-based Lambda authorizer (`REQUEST` authorizer)**  
A `REQUEST` authorizer receives the caller's identity in a combination of headers, query string parameters, [`stageVariables`](api-gateway-mapping-template-reference.md#stagevariables-template-reference), and [`$context`](api-gateway-mapping-template-reference.md#context-variable-reference) variables. You can use a `REQUEST` authorizer to create fine-grained policies based on the information from multiple identity sources, such as the `$context.path` and `$context.httpMethod` context variables.  
If you turn on authorization caching for a `REQUEST` authorizer, API Gateway verifies that all specified identity sources are present in the request. If a specified identify source is missing, null, or empty, API Gateway returns a `401 Unauthorized` HTTP response without calling the Lambda authorizer function. When multiple identity sources are defined, they are all used to derive the authorizer's cache key, with the order preserved. You can define a fine-grained cache key by using multiple identity sources.  
If you change any of the cache key parts, and redeploy your API, the authorizer discards the cached policy document and generates a new one.  
If you turn off authorization caching for a `REQUEST` authorizer, API Gateway directly passes the request to the Lambda function. 

**Token-based Lambda authorizer (`TOKEN` authorizer)**  
A `TOKEN` authorizer receives the caller's identity in a bearer token, such as a JSON Web Token (JWT) or an OAuth token.  
If you turn on authorization caching for a `TOKEN` authorizer, the header name specified in the token source becomes the cache key.   
Additionally, you can use token validation to enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the Lambda authorizer function upon successful validation. This helps reduce calls to your API.   
The `IdentityValidationExpression` property is supported for `TOKEN` authorizers only. For more information, see [x-amazon-apigateway-authorizer object](api-gateway-swagger-extensions-authorizer.md).

**Note**  
We recommend that you use a `REQUEST` authorizer to control access to your API. You can control access to your API based on multiple identity sources when using a `REQUEST` authorizer, compared to a single identity source when using a `TOKEN` authorizer. In addition, you can separate cache keys using multiple identity sources for a `REQUEST` authorizer.

## Example `REQUEST` authorizer Lambda function


The following example code creates a Lambda authorizer function that allows a request if the client-supplied `HeaderAuth1` header, `QueryString1` query parameter, and stage variable of `StageVar1` all match the specified values of `headerValue1`, `queryValue1`, and `stageValue1`, respectively. 

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

```
// A simple request-based authorizer example to demonstrate how to use request 
// parameters to allow or deny a request. In this example, a request is  
// authorized if the client-supplied HeaderAuth1 header, QueryString1
// query parameter, and stage variable of StageVar1 all match
// specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
// respectively.
    
export const handler = function(event, context, callback) {
    console.log('Received event:', JSON.stringify(event, null, 2));
    
    // Retrieve request parameters from the Lambda function input:
    var headers = event.headers;
    var queryStringParameters = event.queryStringParameters;
    var pathParameters = event.pathParameters;
    var stageVariables = event.stageVariables;
        
    // Parse the input for the parameter values
    var tmp = event.methodArn.split(':');
    var apiGatewayArnTmp = tmp[5].split('/');
    var awsAccountId = tmp[4];
    var region = tmp[3];
    var restApiId = apiGatewayArnTmp[0];
    var stage = apiGatewayArnTmp[1];
    var method = apiGatewayArnTmp[2];
    var resource = '/'; // root resource
    if (apiGatewayArnTmp[3]) {
        resource += apiGatewayArnTmp[3];
    }
        
    // Perform authorization to return the Allow policy for correct parameters and 
    // the 'Unauthorized' error, otherwise.

     
    if (headers.HeaderAuth1 === "headerValue1"
        && queryStringParameters.QueryString1 === "queryValue1"
        && stageVariables.StageVar1 === "stageValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn));
    }
}
     
// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    // Required output:
    var authResponse = {};
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
     
var generateAllow = function(principalId, resource) {
    return generatePolicy(principalId, 'Allow', resource);
}
     
var generateDeny = function(principalId, resource) {
    return generatePolicy(principalId, 'Deny', resource);
}
```

------
#### [ Python ]

```
# A simple request-based authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied headerauth1 header, QueryString1
# query parameter, and stage variable of StageVar1 all match
# specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
# respectively.

def lambda_handler(event, context):
    print(event)

    # Retrieve request parameters from the Lambda function input:
    headers = event['headers']
    queryStringParameters = event['queryStringParameters']
    pathParameters = event['pathParameters']
    stageVariables = event['stageVariables']

    # Parse the input for the parameter values
    tmp = event['methodArn'].split(':')
    apiGatewayArnTmp = tmp[5].split('/')
    awsAccountId = tmp[4]
    region = tmp[3]
    restApiId = apiGatewayArnTmp[0]
    stage = apiGatewayArnTmp[1]
    method = apiGatewayArnTmp[2]
    resource = '/'

    if (apiGatewayArnTmp[3]):
        resource += apiGatewayArnTmp[3]

    # Perform authorization to return the Allow policy for correct parameters
    # and the 'Unauthorized' error, otherwise.

    if (headers['HeaderAuth1'] == "headerValue1" and queryStringParameters['QueryString1'] == "queryValue1" and stageVariables['StageVar1'] == "stageValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return response
    else:
        print('unauthorized')
        response = generateDeny('me', event['methodArn'])
        return response
    # Help function to generate IAM policy


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument

    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }

    return authResponse


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

In this example, the Lambda authorizer function checks the input parameters and acts as follows:
+ If all the required parameter values match the expected values, the authorizer function returns a `200 OK` HTTP response and an IAM policy that looks like the following, and the method request succeeds:

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ Otherwise, the authorizer function returns a `401 Unauthorized` HTTP response, and the method request fails.

In addition to returning an IAM policy, the Lambda authorizer function must also return the caller's principal identifier. Optionally, it can return a `context` object containing additional information that can be passed into the integration backend. For more information, see [Output from an API Gateway Lambda authorizer](api-gateway-lambda-authorizer-output.md).

In production code, you might need to authenticate the user before granting authorization. You can add authentication logic in the Lambda function by calling an authentication provider as directed in the documentation for that provider.

## Example `TOKEN` authorizer Lambda function


The following example code creates a `TOKEN` Lambda authorizer function that allows a caller to invoke a method if the client-supplied token value is `allow`. The caller is not allowed to invoke the request if the token value is `deny`. If the token value is `unauthorized` or an empty string, the authorizer function returns an `401 UNAUTHORIZED` response.

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

```
// A simple token-based authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
// string, the authorizer function returns an HTTP 401 status code. For any other token value, 
// the authorizer returns an HTTP 500 status code. 
// Note that token values are case-sensitive.

export const handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); // Return a 500 Invalid token response
    }
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};
    
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
```

------
#### [ Python ]

```
# A simple token-based authorizer example to demonstrate how to use an authorization token
# to allow or deny a request. In this example, the caller named 'user' is allowed to invoke
# a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke
# the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
# string, the authorizer function returns an HTTP 401 status code. For any other token value,
# the authorizer returns an HTTP 500 status code.
# Note that token values are case-sensitive.

import json


def lambda_handler(event, context):
    token = event['authorizationToken']
    if token == 'allow':
        print('authorized')
        response = generatePolicy('user', 'Allow', event['methodArn'])
    elif token == 'deny':
        print('unauthorized')
        response = generatePolicy('user', 'Deny', event['methodArn'])
    elif token == 'unauthorized':
        print('unauthorized')
        raise Exception('Unauthorized')  # Return a 401 Unauthorized response
        return 'unauthorized'
    try:
        return json.loads(response)
    except BaseException:
        print('unauthorized')
        return 'unauthorized'  # Return a 500 error


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument
    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }
    authResponse_JSON = json.dumps(authResponse)
    return authResponse_JSON
```

------

In this example, when the API receives a method request, API Gateway passes the source token to this Lambda authorizer function in the `event.authorizationToken` attribute. The Lambda authorizer function reads the token and acts as follows:
+ If the token value is `allow`, the authorizer function returns a `200 OK` HTTP response and an IAM policy that looks like the following, and the method request succeeds:

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ If the token value is `deny`, the authorizer function returns a `200 OK` HTTP response and a `Deny` IAM policy that looks like the following, and the method request fails:

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
**Note**  
Outside of the test environment, API Gateway returns a `403 Forbidden` HTTP response and the method request fails.
+ If the token value is `unauthorized` or an empty string, the authorizer function returns a `401 Unauthorized` HTTP response, and the method call fails.
+ If the token is anything else, the client receives a `500 Invalid token` response, and the method call fails.

In addition to returning an IAM policy, the Lambda authorizer function must also return the caller's principal identifier. Optionally, it can return a `context` object containing additional information that can be passed into the integration backend. For more information, see [Output from an API Gateway Lambda authorizer](api-gateway-lambda-authorizer-output.md).

In production code, you might need to authenticate the user before granting authorization. You can add authentication logic in the Lambda function by calling an authentication provider as directed in the documentation for that provider.

## Additional examples of Lambda authorizer functions
Additional examples of Lambda authorizer functions

The following list shows additional examples of Lambda authorizer functions. You can create a Lambda function in the same account, or a different account, from where you created your API.

For the previous example Lambda functions, you can use the built-in [AWSLambdaBasicExecutionRole](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html), as these functions don't call other AWS services. If your Lambda function calls other AWS services, you'll need to assign an IAM execution role to the Lambda function. To create the role, follow the instructions in [AWS Lambda Execution Role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html).

**Additional examples of Lambda authorizer functions**
+  For an example application, see [Open Banking Brazil - Authorization Samples](https://github.com/aws-samples/openbanking-brazilian-auth-samples) on GitHub. 
+  For more example Lambda functions, see [ aws-apigateway-lambda-authorizer-blueprints](https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints) on GitHub. 
+ You can create a Lambda authorizer that authenticates users using Amazon Cognito user pools and authorizes callers based on a policy store using Verified Permissions. For more information, see [Control access based on an identity’s attributes with Verified Permissions](apigateway-lambda-authorizer-verified-permissions.md).
+ The Lambda console provides a Python blueprint, which you can use by choosing **Use a blueprint** and choosing the **api-gateway-authorizer-python** blueprint.

# Configure an API Gateway Lambda authorizer
Configure a Lambda authorizer

After you create a Lambda function, you configure the Lambda function as an authorizer for your API. You then configure your method to invoke your Lambda authorizer to determine if a caller can invoke your method. You can create a Lambda function in the same account, or a different account, from where you created your API.

You can test your Lambda authorizer using built-in tools in the API Gateway console or by using [Postman](https://www.postman.com/). For instructions for how to use Postman to test your Lambda authorizer function, see [Call an API with an API Gateway Lambda authorizer](call-api-with-api-gateway-lambda-authorization.md).

## Configure a Lambda authorizer (console)


 The following procedure shows how to create a Lambda authorizer in the API Gateway REST API console. To learn more about the different types of Lambda authorizers, see [Choosing a type of Lambda authorizer](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-choose). 

------
#### [ REQUEST authorizer ]

**To configure a `REQUEST` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Select an API, and then choose **Authorizers**. 

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**. 

1. For **Lambda function**, select the AWS Region where you created your Lambda authorizer function, and then enter the function name.

1. Keep **Lambda invoke role** blank to let the API Gateway REST API console set a resource-based policy. The policy grants API Gateway permissions to invoke the Lambda authorizer function. You can also choose to enter the name of an IAM role to allow API Gateway to invoke the Lambda authorizer function. For an example role, see [Create an assumable IAM role](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies). 

1. For **Lambda event payload**, select **Request**.

1. For **Identity source type**, select a parameter type. Supported parameter types are `Header`, `Query string`, `Stage variable`, and `Context`. To add more identity sources, choose **Add parameter**. 

1. To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can modify the **TTL** value. Setting the **TTL** to zero disables policy caching.

   If you enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce a method-specific policy, use the context variables `$context.path` and `$context.httpMethod`.

1. Choose **Create authorizer**.

------
#### [ TOKEN authorizer ]

**To configure a `TOKEN` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Select an API, and then choose **Authorizers**. 

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**. 

1. For **Lambda function**, select the AWS Region where you created your Lambda authorizer function, and then enter the function name.

1. Keep **Lambda invoke role** blank to let the API Gateway REST API console set a resource-based policy. The policy grants API Gateway permissions to invoke the Lambda authorizer function. You can also choose to enter the name of an IAM role to allow API Gateway to invoke the Lambda authorizer function. For an example role, see [Create an assumable IAM role](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies). 

1. For **Lambda event payload**, select **Token**.

1. For **Token source**, enter the header name that contains the authorization token. The caller must include a header of this name to send the authorization token to the Lambda authorizer.

1. (Optional) For **Token validation**, enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the authorizer upon successful validation.

1. To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, the header name specified in **Token source** becomes the cache key. When policy caching is enabled, you can modify the **TTL** value. Setting the **TTL** to zero disables policy caching. 

   If you enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce a method-specific policy, you can turn off **Authorization caching**.

1. Choose **Create authorizer**.

------

After your create your Lambda authorizer, you can test it. The following procedure shows how to test your Lambda authorizer.

------
#### [ REQUEST authorizer ]

**To test a `REQUEST` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Select the name of your authorizer.

1. Under **Test authorizer**, enter a value for your identity source.

   If you are using the [Example `REQUEST` authorizer Lambda function](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-request-lambda-function-create), do the following:

   1. Select **Header** and enter **headerValue1**, and then choose **Add parameter**.

   1. Under **Identity source type**, select **Query string** and enter **queryValue1**, and then choose **Add parameter**.

   1. Under **Identity source type**, select **Stage variable** and enter **stageValue1**.

   You can't modify the context variables for the test invocation, but you can modify the **API Gateway Authorizer** test event template for your Lambda function. Then, you can test your Lambda authorizer function with modified context variables. For more information, see [Testing Lambda functions in the console](https://docs.aws.amazon.com/lambda/latest/dg/testing-functions.html) in the *AWS Lambda Developer Guide*.

1. Choose **Test authorizer**.

------
#### [ TOKEN authorizer ]

**To test a `TOKEN` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Select the name of your authorizer.

1. Under **Test authorizer**, enter a value for your token.

   If you are using the [Example `TOKEN` authorizer Lambda function](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-token-lambda-function-create), do the following:

   1. For the **authorizationToken**, enter **allow**.

1. Choose **Test authorizer**.

    If your Lambda authorizer successfully denies a request in the test environment, the test responds with a `200 OK` HTTP response. However, outside of the test environment, API Gateway returns a `403 Forbidden` HTTP response and the method request fails.

------

## Configure a Lambda authorizer (AWS CLI)


The following [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) command shows to create a Lambda authorizer using the AWS CLI.

------
#### [ REQUEST authorizer ]

The following [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) command creates a `REQUEST` authorizer and uses the `Authorizer` header and `accountId` context variable as identity sources:

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Request_Custom_Authorizer' \
    --type REQUEST \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization,context.accountId' \
    --authorizer-result-ttl-in-seconds 300
```

------
#### [ TOKEN authorizer ]

The following [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) command creates a `TOKEN` authorizer and uses the `Authorization` header as the identity source:

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Token_Custom_Authorizer' \
    --type TOKEN \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization' \
    --authorizer-result-ttl-in-seconds 300
```

------

After your create your Lambda authorizer, you can test it. The following [test-invoke-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-authorizer.html) command tests a Lambda authorizer:

```
aws apigateway test-invoke-authorizer --rest-api-id 1234123412 \
   --authorizer-id efg1234 \
   --headers Authorization='Value'
```

## Configure a method to use a Lambda authorizer (console)


After you configure your Lambda authorizer, you must attach it to a method for your API. If your authorizer uses authorization caching, make sure you update the policy to control access for the additional method.

**To configure an API method to use a Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Select an API.

1. Choose **Resources**, and then choose a new method or choose an existing method.

1. On the **Method request** tab, under **Method request settings**, choose **Edit**. 

1. For **Authorizer**, from the dropdown menu, select the Lambda authorizer you just created. 

1.  (Optional) If you want to pass the authorization token to the backend, choose **HTTP request headers**. Choose **Add header**, and then add the name of the authorization header. For **Name**, enter the header name that matches the **Token source** name you specified when you created the Lambda authorizer for the API. This step does not apply to `REQUEST` authorizers. 

1. Choose **Save**.

1. Choose **Deploy API** to deploy the API to a stage. For a `REQUEST` authorizer using stage variables, you must also define the required stage variables and specify their values while on the **Stages ** page.

## Configure a method to use a Lambda authorizer (AWS CLI)


After you configure your Lambda authorizer, you must attach it to a method for your API. You can create a new method or use a patch operation to attach an authorizer to an existing method. If your authorizer uses authorization caching, make sure you update the policy to control access for the additional method.

The following [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) command creates a new method that uses an Lambda authorizer:

```
aws apigateway put-method --rest-api-id 1234123412 \
  --resource-id a1b2c3 \
  --http-method PUT \
  --authorization-type CUSTOM \
  --authorizer-id efg1234
```

The following [update-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-method.html) command update an existing method to use a Lambda authorizer:

```
aws apigateway update-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --patch-operations op="replace",path="/authorizationType",value="CUSTOM" op="replace",path="/authorizerId",value="efg1234"
```

# Input to an API Gateway Lambda authorizer
Input to a Lambda authorizer

The following section explains the format of the input from API Gateway to a Lambda authorizer.

## `TOKEN` input format


 For a Lambda authorizer (formerly known as a custom authorizer) of the `TOKEN` type, you must specify a custom header as the **Token Source** when you configure the authorizer for your API. The API client must pass the required authorization token in that header in the incoming request. Upon receiving the incoming method request, API Gateway extracts the token from the custom header. It then passes the token as the `authorizationToken` property of the `event` object of the Lambda function, in addition to the method ARN as the `methodArn` property: 

```
{
    "type":"TOKEN",
    "authorizationToken":"{caller-supplied-token}",
    "methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
```

 In this example, the `type` property specifies the authorizer type, which is a `TOKEN` authorizer. The `{caller-supplied-token}` originates from the authorization header in a client request, and can be any string value. The `methodArn` is the ARN of the incoming method request and is populated by API Gateway in accordance with the Lambda authorizer configuration. 

## `REQUEST` input format


For a Lambda authorizer of the `REQUEST` type, API Gateway passes request parameters to the authorizer Lambda function as part of the `event` object. The request parameters include headers, path parameters, query string parameters, stage variables, and some of request context variables. The API caller can set the path parameters, headers, and query string parameters. The API developer must set the stage variables during the API deployment and API Gateway provides the request context at run time. 

**Note**  
Path parameters can be passed as request parameters to the Lambda authorizer function, but they cannot be used as identity sources.

 The following example shows an input to a `REQUEST` authorizer for an API method (`GET /request`) with a proxy integration: 

```
{
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}
```

 The `requestContext` is a map of key-value pairs and corresponds to the [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) variable. Its outcome is API-dependent.

 API Gateway might add new keys to the map. For more information about Lambda function input in Lambda proxy integration, see [Input format of a Lambda function for proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format). 

# Output from an API Gateway Lambda authorizer


A Lambda authorizer function's output is a dictionary-like object, which must include the principal identifier (`principalId`) and a policy document (`policyDocument`) containing a list of policy statements. The output can also include a `context` map containing key-value pairs. If the API uses a usage plan (the [https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource) is set to `AUTHORIZER`), the Lambda authorizer function must return one of the usage plan's API keys as the `usageIdentifierKey` property value.

The following shows an example of this output. 

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

****  

```
{
  "principalId": "yyyyyyyy", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}
```

------

 Here, a policy statement specifies whether to allow or deny (`Effect`) the API Gateway execution service to invoke (`Action`) the specified API method (`Resource`). You might need to control access to multiple resources based on your authorizer. You can use a wild card (`*`) to specify a resource type (method). For information about setting valid policies for calling an API, see [Statement reference of IAM policies for executing API in API Gateway](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-calling-api-permissions). 

For an authorization-enabled method ARN, e.g., `arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]`, the maximum length is 1600 bytes. The path parameter values, the size of which are determined at run time, can cause the ARN length to exceed the limit. When this happens, the API client will receive a `414 Request URI too long` response. 

In addition, the Resource ARN, as shown in the policy statement output by the authorizer, is currently limited to 512 characters long. For this reason, you must not use URI with a JWT token of a significant length in a request URI. You can safely pass the JWT token in a request header, instead.

 You can access the `principalId` value in a mapping template using the `$context.authorizer.principalId` variable. This is useful if you want to pass the value to the backend. For more information, see [Context variables for data transformations](api-gateway-mapping-template-reference.md#context-variable-reference). 

 You can access the `stringKey`, `numberKey`, or `booleanKey` value (for example, `"value"`, `"1"`, or `"true"`) of the `context` map in a mapping template by calling `$context.authorizer.stringKey`, `$context.authorizer.numberKey`, or `$context.authorizer.booleanKey`, respectively. The returned values are all stringified. Notice that you cannot set a JSON object or array as a valid value of any key in the `context` map. 

 You can use the `context` map to return cached credentials from the authorizer to the backend, using an integration request mapping template. This enables the backend to provide an improved user experience by using the cached credentials to reduce the need to access the secret keys and open the authorization tokens for every request. 

 For the Lambda proxy integration, API Gateway passes the `context` object from a Lambda authorizer directly to the backend Lambda function as part of the input `event`. You can retrieve the `context` key-value pairs in the Lambda function by calling `$event.requestContext.authorizer.key`. 

`{api-key}` stands for an API key in the API stage's usage plan. For more information, see [Usage plans and API keys for REST APIs in API Gateway](api-gateway-api-usage-plans.md).

 The following shows example output from the example Lambda authorizer. The example output contains a policy statement to block (`Deny`) calls to the `GET` method for the `dev` stage of an API (`ymy8tbxw7b`) of an AWS account (`123456789012`).

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

****  

```
{
  "principalId": "user",
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/dev/GET/"
      }
    ]
  }
}
```

------

# Call an API with an API Gateway Lambda authorizer
Call an API with Lambda authorizers

 Having configured the Lambda authorizer (formerly known as the custom authorizer) and deployed the API, you should test the API with the Lambda authorizer enabled. For this, you need a REST client, such as cURL or [Postman](https://www.postman.com/). For the following examples, we use Postman. 

**Note**  
 When calling an authorizer-enabled method, API Gateway does not log the call to CloudWatch if the required token for the `TOKEN` authorizer is not set, is null, or is invalidated by the specified **Token validation expression**. Similarly, API Gateway does not log the call to CloudWatch if any of the required identity sources for the `REQUEST` authorizer are not set, are null, or are empty.

 In the following, we show how to use Postman to call or test an API with a Lambda `TOKEN` authorizer. The method can be applied to calling an API with a Lambda `REQUEST` authorizer, if you specify the required path, header, or query string parameters explicitly. 

**To call an API with the custom `TOKEN` authorizer**

1.  Open **Postman**, choose the **GET** method, and paste the API's **Invoke URL** into the adjacent URL field. 

    Add the Lambda authorization token header and set the value to `allow`. Choose **Send**.   
![\[Call API with Lambda authorization allow token\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/custom-auth-call-api-with-allow-token.png)

    The response shows that the API Gateway Lambda authorizer returns a **200 OK** response and successfully authorizes the call to access the HTTP endpoint (http://httpbin.org/get) integrated with the method. 

1.  Still in Postman, change the Lambda authorization token header value to `deny`. Choose **Send**.   
![\[Call API with Lambda authorization deny token\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/custom-auth-call-api-with-deny-token.png)

   The response shows that the API Gateway Lambda authorizer returns a **403 Forbidden** response without authorizing the call to access the HTTP endpoint.

1.  In Postman, change the Lambda authorization token header value to `unauthorized` and choose **Send**.   
![\[Call API with Lambda authorization unauthorized token\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/custom-auth-call-api-with-unauthorized-token.png)

    The response shows that API Gateway returns a **401 Unauthorized** response without authorizing the call to access the HTTP endpoint. 

1.  Now, change the Lambda authorization token header value to `fail`. Choose **Send**.   
![\[Call API with Lambda authorization fail token\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/custom-auth-call-api-with-fail-token.png)

    The response shows that API Gateway returns a **500 Internal Server Error** response without authorizing the call to access the HTTP endpoint. 

# Configure a cross-account API Gateway Lambda authorizer
Configure a cross-account Lambda authorizer

You can now also use an AWS Lambda function from a different AWS account as your API authorizer function. Each account can be in any region where Amazon API Gateway is available. The Lambda authorizer function can use bearer token authentication strategies such as OAuth or SAML. This makes it easy to centrally manage and share a central Lambda authorizer function across multiple API Gateway APIs.

In this section, we show how to configure a cross-account Lambda authorizer function using the Amazon API Gateway console.

These instructions assume that you already have an API Gateway API in one AWS account and a Lambda authorizer function in another account.

## Configure a cross-account Lambda authorizer using the API Gateway console


Log in to the Amazon API Gateway console in the account that has your API in it, and then do the following:

1. Choose your API, and then in the main navigation pane, choose **Authorizers**.

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**.

1. For **Lambda Function**, enter the full ARN for the Lambda authorizer function that you have in your second account.
**Note**  
In the Lambda console, you can find the ARN for your function in the upper right corner of the console window.

1. A warning with an `aws lambda add-permission` command string will appear. This policy grants API Gateway permission to invoke the authorizer Lambda function. Copy the command and save it for later. You run the command after you create the authorizer.

1. For **Lambda event payload**, select either **Token** for a `TOKEN` authorizer or **Request** for a `REQUEST` authorizer.

1. Depending on the choice of the previous step, do one of the following:

   1.  For the **Token** option, do the following: 
      + For **Token source**, enter the header name that contains the authorization token. The API client must include a header of this name to send the authorization token to the Lambda authorizer. 
      + Optionally, for **Token validation**, enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the authorizer upon successful validation. This helps reduce calls to your API. 
      + To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can choose to modify the **TTL** value. Setting the **TTL** to zero disables policy caching. When policy caching is enabled, the header name specified in **Token source** becomes the cache key. If multiple values are passed to this header in the request, all values will become the cache key, with the order preserved.
**Note**  
The default **TTL** value is 300 seconds. The maximum value is 3600 seconds; this limit cannot be increased.

   1. For the **Request** option, do the following:
      + For **Identity source type**, select a parameter type. Supported parameter types are `Header`, `Query string`, `Stage variable`, and `Context`. To add more identity sources, choose **Add parameter**. 
      + To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can choose to modify the **TTL** value. Setting the **TTL** to zero disables policy caching.

        API Gateway uses the specified identity sources as the request authorizer caching key. When caching is enabled, API Gateway calls the authorizer's Lambda function only after successfully verifying that all the specified identity sources are present at runtime. If a specified identity source is missing, null, or empty, API Gateway returns a `401 Unauthorized` response without calling the authorizer Lambda function. 

        When multiple identity sources are defined, they are all used to derive the authorizer's cache key. Changing any of the cache key parts causes the authorizer to discard the cached policy document and generate a new one. If a header with multiple values is passed in the request, then all values will be part of the cache key, with the order preserved. 
      + When caching is turned off, it is not necessary to specify an identity source.
**Note**  
 To enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce method-specific policy, you can turn off **Authorization caching**. 

1. Choose **Create authorizer**.

1. Paste the `aws lambda add-permission` command string that you copied in a previous step into an AWS CLI window that is configured for your second account. Replace `AUTHORIZER_ID` with your authorizer's ID. This will grant your first account access to your second account's Lambda authorizer function.

# Control access based on an identity’s attributes with Verified Permissions


Use Amazon Verified Permissions to control access to your API Gateway API. When you use API Gateway with Verified Permissions, Verified Permissions creates a Lambda authorizer that uses fine-grained authorization decisions to control access to your API. Verified Permissions authorizes callers based on a policy store schema and policies using the Cedar policy language to define fine-grained permissions for application users. For more information, see [Create a policy store with a connected API and identity provider](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/getting-started-api-policy-store.html) in the *Amazon Verified Permissions User Guide*.

Verified Permissions supports Amazon Cognito user pools or OpenID Connect (OIDC) identity providers as identity sources. Verified Permissions presumes that the principal has been previously identified and authenticated. Verified Permissions is only supported for Regional and edge-optimized REST APIs.

## Create a Lambda authorizer using Verified Permissions


Verified Permissions creates a Lambda authorizer to determine if a principal is allowed to perform an action on your API. You create the Cedar policy that Verified Permissions uses to perform its authorization tasks.

The following is an example Cedar policy that allows access to invoke an API based on the Amazon Cognito user pool, `us-east-1_ABC1234` for the `developer` group on the `GET /users` resource of an API. Verified Permissions determines group membership by parsing the bearer token for the caller's identity. 

```
permit(
  principal in MyAPI::UserGroup::"us-east-1_ABC1234|developer",
  action in [ MyAPI::Action::"get /users" ],
  resource
  );
```

Optionally, Verified Permissions can attach the authorizer to the methods of your API. On production stages for your API, we recommend that you don't allow Verified Permissions to attach the authorizer for you.

The following list show how to configure Verified Permissions to attach or not to attach the Lambda authorizer to the method request of your API's methods.

**Attach the authorizer for you (AWS Management Console)**  
When you choose **Create policy store** in the Verified Permissions console, on the **Deploy app integration** page, choose **Now**.

**Don't attach the authorizer for you (AWS Management Console)**  
When you choose **Create policy store** in the Verified Permissions console, on the **Deploy app integration** page, choose **Later**.  
Verified Permissions still creates a Lambda authorizer for you. The Lambda authorizer starts with `AVPAuthorizerLambda-`. For more instructions on how to attach your authorizer on a method, see [Configure a method to use a Lambda authorizer (console)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-console).

**Attach the authorizer for you (CloudFormation)**  
In the Verified Permissions-generated CloudFormation template, in the `Conditions` section, set `"Ref": "shouldAttachAuthorizer"` to `true`.

**Don't attach the authorizer for you (CloudFormation)**  
In the Verified Permissions-generated CloudFormation template, in the `Conditions` section, set `"Ref": "shouldAttachAuthorizer"` to `false`.  
Verified Permissions still creates a Lambda authorizer for you. The Lambda authorizer starts with `AVPAuthorizerLambda-`. For more instructions on how to attach your authorizer on a method, see [Configure a method to use a Lambda authorizer (AWS CLI)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-cli).

## Call a Lambda authorizer using Verified Permissions


You can call your Lambda authorizer by providing an identity or access token in the `Authorization` header. For more information, see [Call an API with an API Gateway Lambda authorizer](call-api-with-api-gateway-lambda-authorization.md).

API Gateway caches the policy that your Lambda authorizer returns for 120 seconds. You can modify the TTL in the API Gateway console or by using the AWS CLI.