Bypassing need for x-amz-cf-id header inclusion in S3 auth in cloudfront


I have a not completely orthodox CF->S3 setup. The relevant components here are:

  1. Cloudfront distribution with origin
  2. Lambda@Edge function (Origin Request) that adds a S3 authorisation (version 2) query string (Signed using the S3 policy the function uses).

The request returned from Lambda is completely correct. If I log the uri, host and query string I get the file I am requesting. However, if I access it through the Cloudfront link directly, the request fails because it no longer uses the AWSAccessKeyID, instead it opts to use x-amz-cf-id (but uses the same Signature, Amz-Security-Token etc). CORRECTION: it may not replace, but be required in addition to.

I know this is the case because I have returned both the
StringToSign and the SignatureProvided. These both match the Lambda response except for the AWSAccessKeyID which has been replaced with the x-amz-cf-id.

This is a very specific question obviously. I may have to look at remodelling this architecture but I would prefer not to. There are several requirements which has led me down this not completely regular setup.


So it seems like with Authentication V2 or V4, the x-amz-cf-id header that’s appended to the origin request and inaccessible by the Lambda@Edge origin request function must be included in the authentication string. This is not possible.

The simple solution is to use the built-in S3 integration in Cloudflare, use a Lambda@Edge origin request function that switches the bucket if like me, that’s your desired goal. For each bucket you want to use, add the following policy to allow your CF distribution to access the objects within the bucket.

CloudfrontID refers to the ID under Origin Access Identity, not the Amazon S3 Canonical ID.

Leave a Reply