Cloudfront API Gateway Origin with IAM Authentication

0

Hi all,

I'm having an issue with a CloudFront distribution that connects to a Regional API Gateway with IAM authentication enabled. Before adding the CloudFront distribution and calling the API Gateway directly, everything was working fine.

However, now with CloudFront Distribution in front of the API Gateway , we're receiving 403/421 errors.

We also need to secure the API Gateway somehow to handle requests coming only from that specific CloudFront distribution and not directly. Does anyone have experience with this issue and could suggest a solution?

Thanks in advance for your help!

3 Answers
0
Accepted Answer

Thanks alot Francisco for the support

After hours of work and multiple testing attempts, we managed to make it work by following the steps below :

  • Create a IAM Authenticated Regional API Gateway.

  • Create a custom domain name for that API Gateway, let's say api.customdomain.eu.

  • Don't create a record on DNS/Route53 for that API Gateway Custom domain name as you will need it for the CloudFront Distribution.

  • Create a CloudFront Distribution with an alternate Domain Name, the same as the custom domain name associated with the API Gateway.

  • Add the API Gateway as an Origin to the CloudFront Distribution.

  • Disable caching on CloudFront or create a new Cache Policy that forwards Authorization headers to the Origin "as shown in the attached img". Enter image description here

  • Create a CNAME/Alias Record that maps the custom domain name "api.customdomain.eu" to the CloudFront Distribution domain name.

  • Start testing using a Python script that signs "sigv4" your requests to the CloudFront Distribution or use Postman with AWS Signature Authorization enabled. The host used should be the custom domain name "api.customdomain.eu".

profile picture
answered 5 months ago
0

I tried the suggested solution, but in this case we recieved 403 HTTP Error with the following message :

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

profile picture
answered 5 months ago
  • This is because the HTTP Host header used for CloudFront and API Gateway are different. In that case, in the python code snippet I provided you can see the "trick" of signing the request with the API Gateway URL (this is what API Gateway is expecting) and then change the host header to point to CloudFront one. Another option is using custom domain name with same value in both API Gateway and CloudFront.

0

I suggest trying this, for instance, using python to build a custom signed/authenticated CloudFront request.

Source of information: https://github.com/aws-samples/sigv4a-signing-examples/blob/main/python/sigv4a_sign.py

from sigv4a_sign import SigV4ASign

import requests

service = 'execute-api'
region = 'eu-west-1'
method = 'POST'
url = 'https://REDACTED.execute-api.eu-west-1.amazonaws.com/test/REDACTED'
data = 'REDACTED'

aws_request_config = {
    'method': 'POST',
    'url': url,
    'data': data
}

headers = SigV4ASign().get_headers(service, region, aws_request_config)

headers['host'] = 'REDACTED.cloudfront.net'

url = 'https://REDACTED.cloudfront.net/test/REDACTED'

r = requests.post(url, data=data, headers=headers)
print(f'status_code: {r.status_code}')
print(f'response: {r.text}')

The basic points I want to highlight are:

  1. Make sure you sign the request using the API Gateway URL
  2. Make sure you build the request using the HTTP Host header of your CloudFront distribution

Update: For the second point, to restrict API Gateway request processing to CloudFront I suggest using custom Lambda Authorizers as explained here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html For instance, you can include a custom HTTP Header/Value pair from CloudFront distribution and implement the logic in Lambda as authorization layer.

I hope that helps.

profile pictureAWS
answered 5 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions