Struggling setting up permission policy for S3 bucket behind CloudFront

0

I've spent several hours reading documentation and trying different approaches, and I can't get it to work. I'm trying to keep my S3 bucket private while giving read access to public files through CloudFront and read/write access to private files as well as write access to public files to logged in users. So I wrote this:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "PublicReadForPublicFolder",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::BUCKET_NAME/public/*"
		},
		{
			"Sid": "PrivateWriteForPublicFolder",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity/THE_DISTRIBUTION_ORIGIN_ACCESS_ID"
			},
			"Action": [
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::BUCKET_NAME/public/*"
		},
		{
			"Sid": "PrivateReadWriteForPrivateFolder",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity/THE_DISTRIBUTION_ORIGIN_ACCESS_ID"
			},
			"Action": [
				"s3:GetObject",
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::BUCKET_NAME/private/*"
		}
	]
}

And when I try to save I get this error:

Unknown Error
An unexpected error occurred.
API response
Invalid principal in policy

If this is not how I'm supposed to write the policy, then how? Thanks in advance.

3 Answers
3
Accepted Answer

Please refer this re:Post Knowledge Center Article.

Under bucket policy, principal would be something like ""AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EAF5XXXXXXXXX""

Refer Example S3 bucket policy that allows read-only access to an OAI and an OAC section at Restricting access to an Amazon S3 origin

profile pictureAWS
EXPERT
answered 9 months ago
profile pictureAWS
EXPERT
iBehr
reviewed 8 months ago
  • That's what I wrote. If there's a typo, I'm not seeing it.

  • I see forward slash between CloudFront Origin Access Identity and THE_DISTRIBUTION_ORIGIN_ACCESS_ID as CloudFront Origin Access Identity/THE_DISTRIBUTION_ORIGIN_ACCESS_ID. In my answer, there is no forward slash. When you use OAI, forward slash is not needed between CloudFront Origin Access Identity and <origin access identity ID>. Refer Example S3 bucket policy that allows read-only access to an OAI and an OAC section at Restricting access to an Amazon S3 origin

  • Ah yes I see. But since the documentation was REALLY pushing for it, I switched to OAC. But I'm even more confused now as I'm not seeing how to differentiate what is public and what requires credentials. So now I have this:

    {
       "Sid": "AllowCloudFrontServicePrincipal",
       "Effect": "Allow",
       "Principal": {
           "Service": "cloudfront.amazonaws.com"
       },
       "Action": "s3:GetObject",
       "Resource": "arn:aws:s3:::BUCKET_NAME/*",
       "Condition": {
         "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::292141444811:distribution/DIST_ID"
         }
    }
    

    and I'm stuck.

  • If you look at the documentation which I mentioned here, there the bucket policy have both, cloudfront distribution and cloudfront OAI. Refer Example S3 bucket policy that allows read-only access to an OAI and an OAC, there it's mentioned that:

    After you update the S3 origin's bucket policy to allow access to both OAI and OAC, you can update the distribution configuration to use OAC instead of OAI. For more information, see Creating a new origin access control.

    After the distribution is fully deployed, you can remove the statement in the bucket policy that allows access to the OAI. For more information, see Giving the origin access control permission to access the S3 bucket.

  • I guess I'll have to call it a day and try again after a good night sleep. Right now I want to cry, and curse whoever designed this ridiculously convoluted system over 10 generations. I've been rewriting these policies and navigating through the endless labyrinth that is the documentation for the past 4 hours, and every bit of text I read raises more questions than it provides answers. There are so many cryptic acronyms, confusing names, redundant features, counter-intuitive indications... This is torture. This is a nightmare.

0

You need something like this on your policy. You dont grant public access to your bucket if you only want CloudFront to have access

{
    "Version": "2012-10-17",
    "Statement": {
        "Sid": "AllowCloudFrontServicePrincipalReadOnly",
        "Effect": "Allow",
        "Principal": {
            "Service": "cloudfront.amazonaws.com"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::<S3 bucket name>/*",
        "Condition": {
            "StringEquals": {
                "AWS:SourceArn": "arn:aws:cloudfront::<AWS account ID>:distribution/<CloudFront distribution ID>"
            }
        }
    }
}

and for your KMS Key if using one then

{
    "Sid": "AllowCloudFrontServicePrincipalSSE-KMS",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::<AWS account ID>:root",
        "Service": "cloudfront.amazonaws.com"
    },
    "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey*"
    ],
    "Resource": "*",
    "Condition": {
            "StringEquals": {
                "AWS:SourceArn": "arn:aws:cloudfront::<AWS account ID>:distribution/<CloudFront distribution ID>"
            }
        }
}

Setup OAC

To create an origin access control

  1. Sign in to the AWS Management Console and open the CloudFront console at https://console.aws.amazon.com/cloudfront/v3/home.
  2. In the navigation pane, choose Origin access.
  3. Choose Create control setting.
  4. On the Create control setting form, do the following:
  5. In the Details pane, enter a Name and (optionally) a Description for the origin access control.
  6. In the Settings pane, we recommend that you leave the default setting (Sign requests (recommended)). For more information, see Advanced settings for origin access control.
  7. Choose S3 from the Origin type dropdown.
  8. Choose Create. After the OAC is created, make note of the Name. You need this in the following procedure.

To add an origin access control to an S3 origin in a distribution Open the CloudFront console at https://console.aws.amazon.com/cloudfront/v3/home.

  1. Choose a distribution with an S3 origin that you want to add the OAC to, then choose the Origins tab.
  2. Select the S3 origin that you want to add the OAC to, then choose Edit.
  3. From the Origin access control dropdown menu, choose the OAC that you want to use.
  4. Choose Save changes.

The distribution starts deploying to all of the CloudFront edge locations. When an edge location receives the new configuration, it signs all requests that it sends to the S3 bucket origin.

profile picture
EXPERT
answered 9 months ago
  • I read the doc. But not only it does not explain how I can make the public folder publicly readable while requiring access for writing in the public folder or doing anything in the private folder, even if I stick to the most basic example, it doesn't work. If I follow every indication, then visit https://db3du3oxp0i33.cloudfront.net/public/dish_placeholder.png, which I used as a test, I still get Access Denied after doing all this.

  • You want it accessible by cloudfront. That policy makes it publicly accessible via cloudfront and not directly. That’s your requirement in your question isn’t ir?

0

Hi,

I don't think that "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity/THE_DISTRIBUTION_ORIGIN_ACCESS_ID" is a valid principal in the sense that it contains space characters, which mark a separation for IAM. So, rather try something like "AWS": "arn:aws:iam::cloudfront:user/CloudFrontOriginAccessIdentity/THE_DISTRIBUTION_ORIGIN_ACCESS_ID"

See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-names

Names of users, groups, roles, policies, instance profiles, and server certificates 
must be alphanumeric, including the following common characters: plus (+), 
equal (=), comma (,), period (.), at (@), underscore (_), and hyphen (-).

Best, Didier

profile pictureAWS
EXPERT
answered 9 months ago
  • It’s no a literal answer. It’s AWS official documentation. It’s asking for you to replace it with your own ID

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