Search code examples
amazon-web-servicesamazon-s3amazon-cloudfront

AWS CloudFront access to S3 bucket is denied


I am using AWS management console to setup what should be a simple scenario:

  1. Create an S3 bucket in us-west-2 using all defaults

  2. Place a single index.html file into the bucket

  3. Create a CloudFront distribution:

  • Click the “Create distribution” button
  • In “Origin domain” select your bucket in S3.
  • Nothing in the “Origin path”
  • Modify or accept the name created for you
  • Select “Origin access control settings”
  • In “Origin access control” select your bucket if available or click on the “Create control setting” button and choose “Do not sign requests” option - P.S.this was the problem, see the answer
  • Do not enable security protection
  • In “Viewer” select “Redirect HTTP to HTTPS” and “GET, HEAD, OPTIONS”
  • Under “Cache key and origin requests” make sure that the “Cache policy and origin request policy (recommended)” is selected
  • “Cache policy” → “CachingOptimized”
  • “Origin request policy” → “CORS-S3Origin”
  • “Response headers policy” → “SimpleCORS”
  • In “WAF” select “Do not enable security protections”
  • Click “Add item” under “Alternative domain name” and enter <pod_id>.skyjack.teradatalabs.net e.g. tce8415c.skyjack.labsteradata.net . No, it’s not optional
  • Add “HTTP/3” in “Supported HTTP versions”
  • Type index.html into the “Default root object”, do not include a forward slash
  • Accept defaults for everything else and click the “Create distribution” button
  • Copy “Distribution domain name”, for example, d1d*****.cloudfront.net
  • Navigate to your Distribution, select it, and click “Edit”
  • Under “Bucket policy” click “Copy policy” and click the “Go to S3 bucket permissions” link that will take you to your Mario bucket’s “Permissions” tab
  • Click “Bucket policy” → “Edit” and paste the policy you copied in the previous step

With all of this done, and after running invalidation on the distribution and waiting when trying to access the site with the distribution URL I always get this 403 Forbidden error:

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>******</RequestId>
<HostId>iY6PE****</HostId>
</Error>

To add insult to injury I was able to make it work on another AWS account (I'm using multiple accounts under the same root) with seemingly exactly the same steps. Various logs in the CloudWatch don't seem to have any clues except "Access Denied". When I look at the permissions for the index.html itself it clearly states that

This bucket has the bucket owner enforced setting applied for Object Ownership
When bucket owner enforced is applied, use bucket policies to control access.

And the policy that was generated for me in the CF distro installation is as follows:

{
        "Version": "2008-10-17",
        "Id": "PolicyForCloudFrontPrivateContent",
        "Statement": [
            {
                "Sid": "AllowCloudFrontServicePrincipal",
                "Effect": "Allow",
                "Principal": {
                    "Service": "cloudfront.amazonaws.com"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::mybucket-123/*",
                "Condition": {
                    "StringEquals": {
                      "AWS:SourceArn": "arn:aws:cloudfront::*****:distribution/*****"
                    }
                }
            }
        ]
      }

I even tried to enable public access or modify the generated policy to "allow all" but still I'm getting 403 no matter what I try. Yes, I tried all the tricks from these previous questions: AWS CloudFront access denied to S3 bucket and AWS - Cloudfront / S3 - Access Denied to no avail. AWS guys - shouldn't this just work? I'm not inventing anything I merely use your wizards and plugin stuff that is generated for me? My gut feeling is that index.html stays inaccessible somehow and I don't want to make it public. The whole idea is to access it through a CF distro.


Solution

  • First you need to check whether the origin access control is attached to Origin or not?

    Besides

    In “Origin access control” select your bucket if available or click on the “Create control setting” button and choose “Do not sign requests” option

    From docs AWS:

    To use this setting, the S3 bucket origin must be publicly accessible. If you use this setting with an S3 bucket origin that's not publicly accessible, CloudFront cannot access the origin. The S3 bucket origin returns errors to CloudFront and CloudFront passes those errors on to viewers.

    I think you should using Sign requests (recommended)

    And “Origin path” try with /