AWS CloudFront access denied to S3 bucket
To assist with your question, I recreated the situation via:
- Created an Amazon S3 bucket with no Bucket Policy
- Uploaded public.jpg and make it public via "Make Public"
- Uploaded private.jpg and kept it private
- Created an Amazon CloudFront web distribution:
- Origin Domain Name: Selected my S3 bucket from the list
- Restrict Bucket Access: Yes
- Origin Access Identity: Create a New Identity
- Grant Read Permissions on Bucket: Yes, Update Bucket Policy
I checked the bucket, and CloudFront had added a Bucket Policy similar to yours.
The distribution was marked as In Progress
for a while. Once it said Enabled
, I accessed the files via the xxx.cloudfront.net
URL:
xxx.cloudfront.net/public.jpg
redirected me to the S3 URLhttp://bucketname.s3.amazonaws.com/public.jpg
. Yes, I could see the file, but it should not use a redirect.xxx.cloudfront.net/private.jpg
redirected me also, but I then receivedAccess Denied
because it is a private file in S3.
I then did some research and found that this is quite a common occurrence. Some people use a workaround by pointing their CloudFront distribution to the static hosted website URL, but this has the disadvantage that it will not work with the Origin Access Identity and I also suspect it won't receive the 'free S3 traffic to the edge' discount.
So, I waited overnight, tested it this morning and everything is working fine.
Bottom line: Even if it says ENABLED
, things might take several hours (eg overnight) to get themselves right. It will then work as documented.
I added index.html
in Default Root Object
under General tab of cloudFront Distribution Settings
and it worked for me.
As index.html was the root file for my project!
In my case I was using multiple origins with "Path Pattern" Behaviors along with an Origin Path in my S3 bucket:
Bad setup:
CloudFront Behavior:
/images/*
-> My-S3-origin
My-S3-origin:
Origin Path: /images
S3 files: /images/my-image.jpg
GET Request: /images/my-image.jpg -> 403
What was happening was the entire CloudFront GET request gets sent to the origin: /image/my-image.jpg
prefixed by Origin Path: /images
, so the request into S3 looks like /images/images/my-image.jpg
which doesn't exist.
Solution
remove Origin Path.
Instead of choosing default s3 bucket for Origin Domain Name, please enter the <bucket-name>.s3-website.<region>.amazonaws.com
as origin Domain Name(You can get this URL at Static website hosting property under S3 bucket properties).