I want to store videos in an Amazon S3 bucket. I want to load them onto my website. I want to use Amazon CloudFront for the CDN/caching etc.
Ideally by the end I would like to restrict the videos to only play on the domains I set.
But initially I am having a 403 error even loading the video.
It says in console:
Failed to load resource: the server responded with a status of 403 ()
And clicking it shows this XML
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>9PW32M02SZR567DF</RequestId>
<HostId>ukPRxDlFq9TYiJcHLnnAhryAewPoAd/ijm/GxHvdB774cMwK4PdQ0yr1CQqa1msCV+CkYj+nkL0=</HostId>
</Error>
I have tried many things after much reading.
Initially, I had set up the distribution with a key and I believe using OAI.
I have now disabled the WAF part of it to try and rule out that as a variable.
I am loading the video directly in the browser. At one point a video player loaded but the video itself did not.
I created public keys
I created key groups
I selected my S3 bucket in CloudFront so I could not have made a typo.
I created an "origin access" and I have tried with both signing and not signing the request.
I set up Identities (legacy)
I have disabled encryption and bucket key.
All public access is blocked.
I copied the permissions from CloudFront and added it to the S3 bucket's permissions.
This is my bucket policy.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::tpwc-co-uk--media/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::240479180938:distribution/E17GLPD7918NNC"
}
}
}
]
}
Server side encryption is set as:
Server-side encryption with Amazon S3 managed keys (SSE-S3)
Here is my URL if that helps: https://d2tzr0xka0eqcu.cloudfront.net
By making my S3 bucket publicly available I can see the URL via S3, but the CloudFront URL still doesn't work.
I updated my policy to include getObject
. My S3 bucket policy now stands as:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::tpwc-co-uk--media/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::240479180938:distribution/E17GLPD7918NNC"
}
}
},
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::tpwc-co-uk--media/*"
}
]
}
Here are screenshots of the things I have configured. Any missing screenshots means no configuration has taken place.
Can anyone help me to understand where I have gone wrong?
The Block Public Access setting may be the problem. Suggesting to try these steps.
1 - S3 bucket which stores the video should configured as a static website, ensure block public access setting is OFF.
2 - Create a S3 bucket policy that gives S3:GetObject permission to *
3 - Test that it works first.
4 - In Cloudfront set the S3 bucket as a custom origin
5 - In Cloudfront configure an Origin Access Control - AWS will generate a Origin Access policy. Copy it.
6 - Go to the S3 Bucket and edit the policy to only allow the OAI to access (paste the policy)
7 - Back in CloudFront configure a Behaviour so that a request for the bucket is sent.
Path pattern : /*.mp4 (example) Origin : Pick the origin created in step 4.
Hope that worked for you.