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/*"
}
]
}
Screenshots
Here are screenshots of the things I have configured. Any missing screenshots means no configuration has taken place.
Distribution Screenshots
General
Settings
Origin Settings
Bucket Screenshots
Permissions
Management
Encryption
Can anyone help me to understand where I have gone wrong?
2
Answers
I don't know if this is the right way or the best way, but someone helped me and it now works, so that is progress.
In the end I also wanted to access to the bucket remotely to upload/download/etc files within Joomla using Akeeba S3 File system. So perhaps that had an influence on why the person helped me configure it this way. I'm just leaving it here for both myself and future users in case they have this issue.
To be clear, the other answer worked which is why I marked it as correct.
My new S3 bucket settings
Rather than using the policy, I used another option which stops the policy being used.
I edited Object Ownership and changed it to ACL's enabled.
Once I had done this my policy was no longer being used and instead the access control I was using instead.
Once I had done this I then had to go to the Access Control List Settings.
I only had to enable one thing, I had to tick the box for list under "Everyone, public access group" and then save it.
Initially, it would not let me tick this box and said I didn't have access privileges to do so. To get that to work I had to change the "block public access" setting and untick everything.
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.
Here is an update with sample screenshot: