HTTP no-cache access to S3 versioned objects

0

I'm surprised I haven't seen this issue online.

Currently I have an S3 bucket that is served through Cloudfront on a custom domain. e.g. An S3 bucket object is retrievable publicly via https://cdn.mywebsite.com/picture.jpeg.

The cloudfront distribution connects with the origin (S3) through an OAC, and the policy was applied to the bucket correctly.

I am able to retrieve all objects today, however there is some invisible caching and I'm unsure how to get around it.

For example, I can reach and retrieve https://cdn.mywebsite.com/picture.jpeg without issues. Then, when I go to retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=...., I get the same response as the prior call. It's cached.

How can I retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=.... without caching?

Here's what I've tried:

  • Under my origin behavior, I have used the CachingDisabled policy under "Cache key and origin requests". This does indeed disable caching, but that policy doesn't forward query string arguments, so picture.jpeg and picture.jpeg?versionId=... are retrieved equivalently.
  • I have tried creating an identical cache policy as CachingDisabled, with Query strings - All set for the cache key settings. As a result, I get a 403 error.

My interpretation is that when a request is sent via cdn.myexample.com/picture.jpeg?versionId=..., that version query string is stripped off before going to the S3 bucket. Hence, it doesn't cache picture.jpeg, but it's not retrieving the right image anymore.

asked 16 days ago242 views
1 Answer
1
Accepted Answer

Hey all, I fixed it. Since this had me pulling my hair out, here was my solution:

  • On the Cloudfront distribution, Edit the Behavior for the S3 Cloudfront bucket.
  • Find Cache key and origin requests and edit this so Headers includes the Origin, and set Query strings to All.

Finally, this is an important step. On the S3 bucket, you must give access to the Cloudfront distribution to get version tagging. I haven't narrowed down exactly which action solved it for me, but here's what worked:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        },
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        }
    ]
}
answered 16 days ago
profile picture
EXPERT
reviewed 15 days ago
profile picture
EXPERT
reviewed 16 days 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