CloudFront with API Gateway authorization headers
API Gateway supports a built-in CloudFront distribution using edge-optimized endpoints. If you want more control over the CloudFront distribution you will need to create your own behind an API Gateway regional endpoint.
This comes with some small challenges when it comes to Authorization headers when they need to be forwarded to the API Gateway origin.
There is an AWS knowledge based article that explains how to do this using a cache policy.

This works, but what if you want to disable the cache? The article claims that You can't use an origin request policy to forward the Authorization header.. If you attempt to create a custom origin policy with the Authorization header you will get an error as seen below.

There is a built-in Managed-AllViewer origin request policy that will forward all headers to the origin including the Authorization header. However, this also forwards the Host header which will be denied by API Gateway and return a 403 Forbidden as it will not match the API endpoint.
There are some workarounds to this:
- Use API Gateway custom domain names to pass an expected Host header to API Gateway.
- Use Lambda@Edge to re-write the Host header.
- Use the cache and set a 0 TTL.
1. Use API Gateway custom domains
You can use API Gateway custom domains to match the custom domain used on the CloudFront distribution to avoid the Host header issue. You can then point your DNS entry to the CloudFront distribution rather than the API Gateway custom domain.
-
Create an API Gateway regional endpoint.
-
Create an AWS Certificate Manager (ACM) public certificate in the
us-east-1region (required for CloudFront). If your API Gateway is not inus-east-1then also create the same certificate in the API Gateway region e.g. eu-west-1. -
Create an API Gateway custom domain name (regional) using the created ACM certificate.
-
Map the custom domain name to the API Gateway stage.
-
Create a CloudFront distribution using the default endpoint as the origin (without the stage name in the origin path, as this has already been mapped in the custom domain name). Ensure you set the alternate domain name (CNAME) to your custom domain name.
-
Set the cache policy to
CacheDisabledand the origin request policy toAllViewer.
-
Configure your DNS to point to the new CloudFront distribution.
Now you can make a call to the CloudFront distribution using an Authorizer header.
2. Use Lambda@Edge
Another option is to forward all headers as before using the AllViewer origin request policy, but instead of using API Gateway custom domain names use Lambda@Edge to re-write the Host header.
-
Create a Lambda function in
us-east-1usingBasic Lambda@Edge permissionsIAM role template. -
Within the Lambda code re-write the Host header.
def lambda_handler(event, context):
request = event['Records'][0]['cf']['request']
request['headers']['host'] = [{'key': 'host', 'value': '<your-api-id>.execute-api.<aws-region>.amazonaws.com'}]
print('Updated host header successfully')
return request
- Add a CloudFront trigger to the Lambda function for
origin-requestand select the CloudFront distribution you created earlier.
Now you can make a call to the CloudFront distribution using an Authorizer header. Be aware that with this method Lambda is invoked on every request as the cache is disabled. This can add latency and increase costs. In my testing the average function duration for the code sample above was 1ms. Cold start (Init) duration was around 100ms.
3. Use the cache and set a 0 TTL
The third option is to create a custom cache policy and set the Minimum TTL and Default TTL to 0. This will essentially disable the cache but forward the Authorization header.
-
Create a new custom cache policy in CloudFront. Set the following TTL settings:
- Minimum TTL: 0
- Maximum TTL: 1 (cannot be 0, but will not be used unless the origin uses
Cache-Controlheaders) - Default TTL: 0
-
Set the cache key headers to include the
Authorizationheader.

- Apply the cache policy to the CloudFront distribution by modifying the behavior.
Now you can make a call to the CloudFront distribution using an Authorizer header.