On AWS, is it possible to have CloudFront proxy requests to API Gateway while maintaining the request’s query string

amazon-api-gatewayamazon-cloudfrontamazon-web-servicescachePROXY

I have a CloudFront distribution configured with multiple Origins, including an API Gateway deployment.

I'm trying to create a Behavior on CloudFront so that any requests received to a /api/* path will be redirected to the API Gateway and what I did was to simply create a new Behavior with the path pattern as /api/* and Origin as the API Gateway deployment I mentioned. This works, however any requests containing a query string in it, such as /api/data?since=2020-01-01, will result in a request to API Gateway without the query string, i.e, what will reach API GW is simply /api/data.

To solve this problem, I tried to set a Cache Policy of Managed-CachingOptimized (or even Managed-CachingDisabled) and an Origin Request Policy of Managed-AllViewer, but then CloudFront started ignoring completely that Behavior and processing the next one in line, which happens to be a S3 bucket. Once the request is sent to the S3 bucket, I get a 404 back as there's no such key in there.

I also tried to use the "Legacy Cache settings", but the same problem is happening.

Is it possible at all to have this "proxy" implemented with CloudFront and API GW? If yes, how would I do that?

Thanks

Best Answer

This caught me out too, with both the query string and headers such as Authorization.

However, the docs state that to pass the Authorization header to the origin it must be used as a cache key:

Cache key settings specify the values in viewer requests that CloudFront includes in the cache key. The values can include URL query strings, HTTP headers, and cookies. The values that you include in the cache key are automatically included in requests that CloudFront sends to the origin, known as origin requests.

and

Note: You can't use an origin request policy to forward the Authorization header. The header must be a part of the cache key to prevent the cache from satisfying unauthorized requests. CloudFront returns an HTTP 400 error if you try to create an origin request policy that forwards the Authorization header.

Additionally, note that in relation to the Origin Request Policy Managed-AllViewer, the issue looks to be the forwarding of the Host header to API Gateway; see https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/571#issuecomment-792051286 i.e. we can't use the Managed-AllViewer for API Gateway origins.

See

  1. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html
  2. https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-authorization-header/

As part of a CDK cloudfront.Distribution() construct:

const apiCachePolicy = new cloudfront.CachePolicy(this, 'ApiCachePolicy', {
        headerBehavior: cloudfront.CacheHeaderBehavior.allowList('authorization'),
        queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(),
        cookieBehavior: cloudfront.CacheCookieBehavior.none(),
        minTtl: Duration.minutes(0),
        maxTtl: Duration.minutes(1),
        defaultTtl: Duration.minutes(0),
        enableAcceptEncodingGzip: true,
        enableAcceptEncodingBrotli: true,
    });