31

I have the following policy:

{
        "Version": "2008-10-17",
        "Id": "PolicyForCloudFrontPrivateContent",
        "Statement": [
            {
                "Sid": "Stmt1395852960432",
                "Action": "s3:*",
                "Effect": "Deny",
                "Resource": "arn:aws:s3:::my-bucket/*",
                "Principal": {
                    "AWS": [
                        "*"
                    ]
                }
            },
            {
                "Sid": "1",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1IYJC432545JN"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::my-bucket/*"
            }
        ]
    }

However, this is denying requests from all requestors, even Cloudfront. What is the correct way to do this?

The problem is that objects are created by the client with public read. I currently do not have immediate control of the client to change this setting. So what I want is to have a policy that overrides individual object ACL. So default deny here does not work.

Snowman
  • 31,411
  • 46
  • 180
  • 303

3 Answers3

39

The S3 policy will look like something like this:

{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
    {
        "Sid": "1",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXX"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::YYYYYYYYYYYYY.com/*"
    }
 ]
}

But, I didnt manually generate this. When you add an origin (S3) in cloudfront, you have an option to "Restrict Bucket Access" - tell "Yes" here and move forward. Cloudfront configuration will do the rest automatically for you.

Details here: Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content - Amazon CloudFront.

Sony Kadavan
  • 3,982
  • 2
  • 19
  • 26
  • 7
    I had the same issue. The AWS man pages are terrible to read. For me I missed the `Origins` tab and the `Yes, Update Bucket Policy` after adding an Identity. – Dan Tappin Apr 19 '16 at 21:43
15

This is what you're looking for. Replace XXXXXXXXXXXXXX with you origin access id

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "AddPerm",
        "Effect": "Deny",
        "NotPrincipal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::your.bucket.com/*"
    },
    {
        "Sid": "2",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::your.bucket.com/*"
    }
]
}
  • 6
    If you still get an XML based AccessDenied error, make sure to specify your default root object in the CloudFront Distribution, under the General Tab. – Andreas Nov 22 '19 at 15:23
  • 3
    After adding the policy to S3 Bucket, I'm still getting access denied when visiting my S3 Bucket via CloudFront Domain. – Tommy Leong Apr 23 '20 at 07:10
  • 1
    Where do I find the OAI of my cloudfront distribution? – DarkTrick Sep 24 '22 at 13:11
5

For people having trouble finding their OAI, this might be an easy workaround (Source: Amazon)

  • Configure your Bucket like:
    • Block public access: Off
    • Bucket Policy: ↓
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<YOUR_BUCKET_NAME>/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::<YOUR_AMAZON_ACCOUNT_ID>:distribution/<CLOUDFRONT_DISTRIBUTION_ID>"
                }
            }
        }
    ]
}
  • The Amazon account ID should be no problem to find, as it's part of your credentials
  • Cloutfront distribution ID can be found in the listing of all your cloud front distributions: enter image description here
DarkTrick
  • 2,447
  • 1
  • 21
  • 39