Can You Use Both x-api-key and Bearer Tokens in API Gateway?
It's a common question for developers building APIs with AWS API Gateway: "Can I use both an x-api-key and a Bearer token for authorization?" The answer is yes, but it's important to understand how and why you would choose this approach.
Let's break down the scenario:
Scenario: You're building an API that needs different levels of access control. Some clients should be able to access basic resources with just an API key, while others require a more secure approach with a Bearer token for higher-privileged endpoints.
Original Code (Example using AWS API Gateway):
{
"method": "GET",
"authorizationType": "CUSTOM",
"authorizerUri": "arn:aws:lambda:REGION:ACCOUNT_ID:function:MyAuthorizer",
"authorizerCredentials": "arn:aws:iam::ACCOUNT_ID:role/MyAuthorizerRole"
}
Analysis:
In this example, we're using a custom authorizer in API Gateway. Here's how to handle both x-api-key and Bearer tokens:
-
The
x-api-key
: This acts as a basic authentication mechanism. You can configure API Gateway to require thex-api-key
header for all requests. -
The Bearer Token: This is a more robust authentication method. We'll use a custom authorizer (like a Lambda function) to validate the Bearer token against your system.
How to Implement:
-
API Gateway Configuration:
- Configure API Gateway to require the
x-api-key
header. - Create a custom authorizer that extracts the Bearer token from the
Authorization
header. - In your authorizer (Lambda function), validate the Bearer token against your system and decide if the request should be authorized.
- Configure API Gateway to require the
-
Custom Authorizer (Lambda Function):
- The authorizer function will receive both the
x-api-key
and the Bearer token in the request context. - You can use the
x-api-key
to verify the client's identity and permission level. - If the
x-api-key
is valid, you can then proceed to validate the Bearer token.
- The authorizer function will receive both the
Example (Authorizer Lambda Function):
import json
import os
def lambda_handler(event, context):
# Extract x-api-key and Bearer token from event
x_api_key = event['headers']['x-api-key']
bearer_token = event['headers']['Authorization'].split()[1]
# Validate x-api-key (e.g., against a list of allowed keys)
if x_api_key not in allowed_keys:
return {
'statusCode': 401,
'body': json.dumps({'message': 'Invalid API Key'})
}
# Validate Bearer token (e.g., using your authorization service)
is_valid = validate_bearer_token(bearer_token)
if not is_valid:
return {
'statusCode': 401,
'body': json.dumps({'message': 'Invalid Bearer Token'})
}
# Authorize the request based on the Bearer token's privileges
return {
'principalId': 'user',
'policyDocument': {
'Version': '2012-10-17',
'Statement': [
{
'Effect': 'Allow',
'Action': 'execute-api:Invoke',
'Resource': event['methodArn']
}
]
}
}
Benefits of This Approach:
- Flexibility: This approach provides flexibility in managing access control. Basic access is granted through the
x-api-key
, while more sensitive operations require a stronger authentication method (Bearer token). - Security: Using a custom authorizer for Bearer token validation strengthens your API's security.
- Scalability: You can easily manage different types of clients and their access levels through this setup.
Important Considerations:
- Complexity: Implementing this approach involves setting up a custom authorizer, which can add complexity to your API.
- Security: Ensure your
x-api-key
is managed securely and properly rotated. - Authorization Service: You'll need a secure and robust authorization service to manage and validate your Bearer tokens.
Conclusion:
Using both x-api-key
and Bearer tokens in API Gateway allows for flexible and secure access control. By implementing a custom authorizer, you can leverage both authentication methods to cater to different client needs and secure your API endpoints effectively.
Further Reading: