Creating an S3 bucket policy that allows access to Cloudfront but restricts access to anyone else

34,605

Solution 1

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.

Solution 2

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/*"
    }
]
}
Share:
34,605
Snowman
Author by

Snowman

Updated on October 27, 2020

Comments

  • Snowman
    Snowman over 3 years

    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.