Skip to content

Access Denied for CloudFront to S3 static site

0

Hello,

I try to give access for CloudFront to an S3 bucket with a static site. Access and site work, if I make the bucket public (Permissions -> Block public access). When I remove public feature from the bucket, I see Access Denied in the internet browser through CloudFront and website endpoint, even if I added the below Bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipalReadOnly",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket>/*"
        }
    ]
}

The origin of the CloudFront distribution is the website endpoint (as recommended), not the S3 endpoint. Considering the documentation, I do not have to make other configurations:

If your origin is an Amazon S3 bucket configured as a website endpoint, you must set it up with CloudFront as a custom origin. 
That means you can't use OAC (or OAI). 
OAC doesn't support origin redirect by using Lambda@Edge.

What does custom origin means in this case ? Is it ok to use the website endpoint ?
Could you please specify why do I get Access Denied ?

Thank you,
Mihai

2 Answers
1

You should first disable static website hosting for your S3 bucket.

Next, configure your bucket policy like shown in the document article https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html, with the policy statement allowing s3:GetObjectaccess to the cloudfront.amazonaws.com service principal (like you did already) and with a Condition clause that checks that the condition key aws:SourceArn matches the ARN of your CloudFront distribution.

Then create an origin access control (OAC) in CloudFront. Configure a new origin for your S3 bucket, but using OAC to access it instead of allowing public access to the bucket via the static website.

This way, CloudFront will access your S3 bucket as an authenticated service principal and with the ARN of your specific CloudFront distribution in the aws:SourceArn condition key, ensuring that no one else's CloudFront distribution gains access to your bucket.

If your bucket is using the default S3-SSE encryption, the above will suffice. Note that static website hosting cannot be active for the bucket together with authenticated access by CloudFront; static website hosting has to be disabled for the bucket. If the objects in your bucket are encrypted with SSE-KMS, the kms:Decrypt permission must additionally be granted to the CloudFront service principal, similarly with the aws:SourceArn restriction, in the KMS key policy.

EXPERT

answered 2 years ago

EXPERT

reviewed 2 years ago

  • Thank you for your answer, Using this configuration, S3 will not act as a site, but as a storage. When accessing it with internet browser will not return HTML page but only some XML content and object files.
    The main purpose of all the configuration is to use CloudFront with S3 static site.

  • When configured in this way, the website functionality will be provided by CloudFront, and that's the generally recommended way to serve static content on the web. Static HTML pages, JavaScript, CSS, images, videos, etc. all work. There are some minor configuration differences, such as that CloudFront doesn't automatically map https://example.com/folder/ to https://example.com/folder/**index.html**, but those are configuration details.

0
Accepted Answer

The issue you're experiencing with Access Denied errors when trying to access your S3 static website through CloudFront is likely due to a mismatch between your CloudFront distribution configuration and the S3 bucket setup.

When you use an S3 bucket configured as a website endpoint (which you are doing), it is indeed considered a custom origin for CloudFront. This is correct and aligns with the documentation you've quoted. Using the website endpoint is appropriate for serving a static website.

However, the bucket policy you've provided is not sufficient when using the website endpoint as the origin. This policy is more suitable for when you're using the S3 REST API endpoint as the origin, which allows for Origin Access Identity (OAI) or Origin Access Control (OAC).

When using the S3 website endpoint as a custom origin, CloudFront doesn't use a special CloudFront service principal to access the content. Instead, it acts like any other HTTP client. This means your bucket needs to be publicly accessible, or you need to implement a different access control mechanism.

To resolve the Access Denied issue while keeping your bucket private, you have a few options:

  1. Use CloudFront Functions or Lambda@Edge to add authentication to your CloudFront distribution. This allows you to keep the bucket private while still serving content through CloudFront.

  2. If you don't need the features of the S3 website endpoint (like index documents or custom error pages), you could switch to using the S3 REST API endpoint as your origin. This would allow you to use OAC, which is the recommended approach for restricting access to S3 content through CloudFront.

  3. If you must use the website endpoint and can't implement additional authentication, you'll need to keep the bucket publicly accessible. In this case, you can use CloudFront's geo-restriction or signed URLs/cookies to control access at the CloudFront level.

The "Access Denied" error occurs because when your bucket is not public, and you're using the website endpoint, there's no mechanism for CloudFront to authenticate itself to S3. The bucket policy you've provided doesn't apply in this scenario because CloudFront is not using its service principal to access the content when using a website endpoint as the origin.

Remember, when using S3 website hosting as a custom origin, CloudFront doesn't have a built-in way to authenticate to S3, so either the bucket needs to be public, or you need to implement custom authentication at the CloudFront level.
Sources
Tutorial: Configuring a static website on Amazon S3 - Amazon Simple Storage Service
cloudfront-s3-origin-access-control-enabled - AWS Config
S3Origin - Amazon CloudFront
Troubleshooting distribution issues - Amazon CloudFront

answered 2 years ago

EXPERT

reviewed 2 years ago

EXPERT

reviewed 2 years ago

  • Thank you for your answer,
    I understood that the only possibility to use CloudFront with S3 static site is by using the website endpoint and let bucket with public access.

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.