I'm using a CloudFront with an origin-request Lambda@Edge function to switch between S3 origins in different regions, much like the "Using an origin-request trigger to change the Amazon S3 origin Region" example in the AWS CloudFront Developer Guide. This works very well with OAI (Origin Access Identity) enabled, to ensure content in S3 is only accessible through CloudFront.
A few months ago CloudFront introduced OAC (Origin Access Control), which has several advantages over OAI.
My question is: How to use an origin-request Lambda@Edge function to switch between S3 origins in different regions, with OAC enabled? (if that is currently possible)
For testing purposes, my origin-request lambda function (nodejs16) is as below. CloudFront OAC is configured to "always sign" requests. The bucket policy for both the default S3 origin bucket in eu-central-1
, and the alternative S3 origin bucket in ap-northeast-1
, is configured to allow s3:GetObject
from the cloudfront.amazonaws.com
service principle with AWS:SourceArn
of the CloudFront distribution's ARN.
Origin Request Edge Lambda:
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
request.origin.s3.region = 'ap-northeast-1';
request.origin.s3.domainName = 'bucket-in-ap-northeast-1-example-origin.s3-ap-northeast-1.amazonaws.com';
request.headers['host'] = [{
'value': request.origin.s3.domainName
}];
console.log(event);
console.log(request);
callback(null, request);
};
I see this error, which seems to indicate that the origin-request Lambda is correctly directing the request to the alternate bucket in ap-northeast-1
, however the authorization header added by OAC is still generated using the default S3 bucket's region (eu-central-1
), and so is not valid for the alternate bucket in Tokyo.
$ curl -isS https://xxxxxxxxxxxxx.cloudfront.net/
HTTP/1.1 400 Bad Request
Content-Type: application/xml
Transfer-Encoding: chunked
Connection: keep-alive
x-amz-bucket-region: ap-northeast-1
Date: Tue, 15 Nov 2022 13:38:14 GMT
Server: AmazonS3
X-Cache: Error from cloudfront
Via: 1.1 0e2886f2f2f8b98f7eaf91c8c6ee8644.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: TPE51-C1
X-Amz-Cf-Id: jMQB5Qz7D21Uh2Ew9pPHQj1ReHhSAbhRQecoPCspMB9LQAhvyFvr1g==
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthorizationHeaderMalformed</Code>
<Message>The authorization header is malformed; the region 'eu-central-1' is wrong; expecting 'ap-northeast-1'</Message>
<Region>ap-northeast-1</Region>
<RequestId>JZ26WY2ZGXPD8EH9</RequestId>
<HostId>v4iIZa5+x3J3mogFRkpGBMnUiC4nLFI1G11ijPrgPadZ9v2hjp+xSIEdbMROWembA5tevIfPyfs=</HostId>
</Error>
I'm facing this exact same issue. I wasn't aware that it might be OAC related