Cloudfront URL giving me AccessDenied error.

0

I have a CloudFront distribution that I am trying to use to serve a React application on S3. Following the AWS documentation, I have the current S3 policy:

S3 bucket policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipalReadOnly",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-s3-bucket/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::x:distribution/x"  // sanitized with x (copied from cloudfront UI panel)
                }
            }
        }
    ]
}

CloudFront distribution origin

My Cloudfront distribution has the following:

origin namedomainpathtypeshield regionaccess
myS3Originmy-s3-bucket.s3.us-east-1.amazonaws.comS3ABC

Origin Access Control (OAC)

resource "aws_cloudfront_origin_access_control" "default" {
  name                              = "DefaultAccessControl"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

Per the terraform documentation, I am using that in the cloudfront distribution resource:

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.deployment_bucket.bucket_regional_domain_name
    origin_access_control_id = aws_cloudfront_origin_access_control.default.id
    origin_id   = "myS3Origin"

Encryption

I am using the standard Server-side encryption with Amazon S3 managed keys (SSE-S3).

Result

When I navigate to my Distribution domain name at x.cloudfront.net, I see the following XML:

<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>QNQMMS43DTSYZNS3</RequestId>
  <HostId>8t3bGWPGKd/u2bWlEKkqy1BJulDigA/ewXnwLrA2A4iC+R4A7DyZE+VxeBIK+aiLICHGOA3OV5g=</HostId>
</Error>    

Attempts to troubleshoot

  1. Delete the bucket policy completely
  • no change
  1. Replace with another similar policy
  • no change

Ideas

I noticed that the distributions origin access "ID" does not match the "ID" at the end of its ARN. Maybe that's normal? Also, is the origin access intended to be listed somewhere in S3? Maybe in the bucket policy?

I'm not sure if OAC is the issue, but the documentation listed by ElectricSpice seems to suggest it is set up correctly.

In the S3 bucket Access control list (ACL), I see a table. The only accessor with any list/write/read is Bucket owner (your AWS account). All of the others have no permissions.

Possibly the way I added my React build assets to S3

I'm brand new to front-end, so I may have screwed up the way I added the assets to S3. When I run npm run build, there is a /dist folder with the following structure:

$ ls -alh ./dist
vite.svg
index.html
assets/

In the documentation from AWS for a React app in S3 it states:

Choose Add folder, and then choose the static directory. Important: Don’t choose the contents; choose the directory.

I take this as explicitly stating I need to add the dist/ directory.

I went into S3 manually (through the console) and added this dist/ dir. So if I navigate to the bucket cik-front-end, I see an object dist/. Now if I change my request to https://d3me6d4ypmjduw.cloudfront.net/dist/index.html, I see a new error:

<Error>
  <Code>AccessDenied</Code>
  <Message>
User: arn:aws:sts::856369053181:assumed-role/OriginAccessControlRole/OriginAccessSession is not authorized to perform: kms:Decrypt on the resource associated with this ciphertext because the resource does not exist in this Region, no resource-based policies allow access, or a resource-based policy explicitly denies access
  </Message>
  <RequestId>VQK7FCNQ0M6BEVQB</RequestId>
  <HostId>
QtFINcK8nLKBD9P+gEvXxZJOUyugRoqjwvVShJvNd1YDoR9Dx95gs4nveVzhzk1p3/DZp/fP4U8=
  </HostId>
</Error>

Solved

Ok so it looks like the AWS documentation is just incorrect.

Choose Add folder, and then choose the static directory. Important: Don’t choose the contents; choose the directory.

This is untrue. I deleted the contents of that bucket, and re-added them as a flattened upload (everything inside the dist/ directory. The app now serves the React SPA.

asked a month ago164 views
2 Answers
2

Some other things to check in the console:

  1. ensure that you have assigned the OAC to the distribution in question. You can do this by viewing the "origins" on the distribution, and seeing that the ID of the OAC is populated beside your S3 origin.
  2. Your bucket policy is correct, based on what I can see above, just verify the bucket names, and the distribution ARN.
  3. Ensure that your origin path is correct. For instance, if in your S3 bucket, the files you want to serve are under the /static-content/file-1 key, but you are requesting it by going to your CloudFront distribution and to https://cloudfront-doman.name/file-1 - then you need to make sure that the origin path is set to /static-content (note do not include the slash at the end).

Failing this turn on bucket access logging and turn on CloudTrail and have a look at why it is failing.

AWS
EXPERT
answered a month ago
profile picture
EXPERT
reviewed a month ago
  • @max I'm not sure how to directly reply to your response. However suggestion #1 was already a hit. My ID distribution origin access and the ARN listed in both my distribution arn and bucket policy do not match:

    • distribution origin access: ABC
    • distribution arn: arn:aws:cloudfront::339712767340:distribution/DEF
    • bucket policy arn: "AWS:SourceArn": "arn:aws:cloudfront::339712767340:distribution/DEF"

    Is that identifier supposed to match?

    My terraform has:

        condition {
          // checks if source_arn is equal to the cloudfront_distribution_arn
          test = "StringEquals"
          variable = "AWS:SourceArn"
        #   values = ["${var.cloudfront_distribution_arn}"]
          values   = [resource.aws_cloudfront_distribution.s3_distribution.arn]
        }
    

    I'm not sure why this is creating a bucket policy arn that does not match.

0

Hi, I would recommend going through this article and rule out the causes: https://repost.aws/knowledge-center/s3-rest-api-cloudfront-error-403

psp
answered a month ago
profile picture
EXPERT
reviewed a month ago
  • I've got it set up as a static S3 bucket. It's a react SPA app.

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.

Guidelines for Answering Questions