Skip to content

Update S3 Bucket Policy to Align with AWS Recommendations #17340

@JonathanAlbarran

Description

@JonathanAlbarran

Existing documentation URL(s)

-https://developers.cloudflare.com/support/third-party-software/others/configuring-an-amazon-web-services-static-site-to-use-cloudflare/
-https://github.com/cloudflare/cloudflare-docs/blob/production/src/content/docs/support/third-party-software/others/configuring-an-amazon-web-services-static-site-to-use-cloudflare.mdx

What changes are you suggesting?

I propose updating the provided S3 bucket policy example to better align with AWS's recommended approach for similar services like CloudFront. Making it more consistent with AWS best practices and easier for users to implement correctly.

Current Cloudflare Documentation

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::www.example.com/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "192.2.0.1" (example IP address),
                        "192.2.0.2" (example IP address),
                        (add all IPs listed at https://www.cloudflare.com/ips)
                    ]
                }
            }
        }
    ]
}

AWS Recommendation for Similar Use Case

AWS recommends the following structure for their CloudFront OAI:

{
    "Version": "2012-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
    ]
}

and the following for Amazon S3 origins with CloudFront:

{
    "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>"
            }
        }
    }
}    

Proposed Update

Adapting the AWS approach for Cloudflare, an enhanced policy would look like:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudflareIPs",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::www.example.com/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "1.1.1.1" (example IPv4 address),
                        "2606:4700:4700::1111" (example IPv6 address),
                        (add all IPs listed at https://www.cloudflare.com/ips)
                    ]
                }
            }
        }
    ]
}

This maintains a structure familiar to AWS users, and uses positive IP address matching, with AWS's "allow" rather than "deny" approach, which is more intuitive.

Additional information

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions