Serving website from Cloudfront and S3 without public bucket

When serving a website via CloudFront from an S3 bucket, I would typically apply the following Bucket Policy to allow access to my files:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow Public Access to All Objects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::somewhere.example.com/*"
        }
    ]
}

But Amazon have recently started showing this message (bold emphasis mine):

We highly recommend that you never grant any kind of public access to your S3 bucket.

The AWS documentation is very inconsistent with this advice, suggesting that only write access is an issue. I'm serving a website so obviously I'm quite happy giving public access to the files, particularly since directory listings are still not allowed.

As of November 2017, what is the recommended way of connecting CloudFront to an S3 bucket, without giving any public access?


You will want to setup Origin Access Identity. This allows you to keep your bucket private and only allow access thru CloudFront. This is very easy to setup. I have included a link to walk you thru the steps and to help you understand everything. After setting up OAI delete the policy for your S3 bucket. Your S3 bucket is private and only provides access to users thru CloudFront.

Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content

Typically, if you're using an Amazon S3 bucket as the origin for a CloudFront distribution, you grant everyone permission to read the objects in your bucket. This allows anyone to access your objects either through CloudFront or using the Amazon S3 URL. CloudFront doesn't expose Amazon S3 URLs, but your users might have those URLs if your application serves any objects directly from Amazon S3 or if anyone gives out direct links to specific objects in Amazon S3.