S3 Bucket Policy Generator

Builds an S3 bucket policy JSON document with an optional deny-non-HTTPS statement, an optional deny-unencrypted-upload statement requiring KMS server-side encryption, and a custom Allow statement for a specific principal, action list, and resource. A free online tool from Staaarter, right in your browser.

Runs locallyUpdated 2026-07-26

Overview

Introduction

Two of the most commonly recommended S3 hardening steps, denying plain-HTTP access and requiring KMS encryption on upload, are also two of the easier bucket policy statements to get subtly wrong by hand, since both hinge on a Condition block with an easy-to-mistype key.

This tool generates both as ready-made, correctly-conditioned statements, plus a custom statement slot for whatever access pattern (cross-account read, a specific writer role) your bucket actually needs.

What Is S3 Bucket Policy Generator?

A generator for S3 bucket policy JSON documents, producing up to three statements: a Deny-non-HTTPS statement, a Deny-unless-KMS-encrypted-upload statement, and one custom Allow statement for a principal, action list, and resource you specify.

Any combination of the three can be enabled; the output is always a complete, valid bucket policy document ready to paste into the S3 console's Bucket Policy editor or a CloudFormation/Terraform bucket policy resource.

How S3 Bucket Policy Generator Works

The HTTPS statement denies all S3 actions from any principal on both the bucket ARN and its `/*` objects, conditioned on `Bool: { "aws:SecureTransport": "false" }`, so it only fires for genuinely insecure requests.

The KMS statement denies `s3:PutObject` on the bucket's objects, conditioned on `StringNotEquals: { "s3:x-amz-server-side-encryption": "aws:kms" }`, so uploads that already specify KMS encryption pass through untouched.

The custom statement takes your principal (wrapped as `{ "AWS": "..." }`), a parsed action list, and a resource, and adds it as a plain Allow statement.

When To Use S3 Bucket Policy Generator

Use it whenever you're setting up a new S3 bucket and want the two most common hardening statements (HTTPS-only, KMS-only uploads) without re-deriving the exact Condition syntax from memory.

It's also useful for quickly drafting a cross-account or scoped-access bucket policy statement alongside those baseline protections.

Features

Advantages

  • Produces the exact Condition key/operator pairs AWS's own documentation recommends for HTTPS and KMS enforcement, rather than relying on memory.
  • Lets you combine baseline hardening statements with a custom access statement in one document.
  • Validates the bucket name against S3's naming rules before generating the policy.

Limitations

  • The custom statement only supports one principal/action/resource combination per generation; policies needing several custom statements require adding them by hand afterward.
  • Doesn't check whether the bucket already has Block Public Access settings that would make a given statement redundant or conflicting.

Examples

HTTPS-only bucket with no custom statement

Input

bucketName: example-assets, enforceHttps: true, enforceKmsEncryption: false

Output

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnforceHttps",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::example-assets", "arn:aws:s3:::example-assets/*"],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

Only the enabled statement is included; leaving both toggles off and the custom fields empty returns an error asking you to enable at least one.

Best Practices & Notes

Best Practices

  • Enable HTTPS enforcement on every bucket that isn't purely internal test scratch space, it costs nothing and closes off a real data-exposure vector.
  • Pair KMS enforcement with a customer-managed KMS key policy, so you also control who can decrypt, not just who can upload.
  • Combine bucket policies with S3 Block Public Access at the account or bucket level rather than relying on the policy alone to prevent public exposure.

Developer Notes

Bucket and object ARNs are derived from the bucket name as `arn:aws:s3:::{bucket}` and `arn:aws:s3:::{bucket}/*`; the bucket name is checked against a simplified version of S3's naming rules (3-63 chars, lowercase letters/digits/dots/hyphens) before any statement is built. The three statement types are independent and additive, each is appended to the `Statement` array only if its corresponding inputs are present, so any subset (including all three) can be generated in one document.

S3 Bucket Policy Generator Use Cases

  • Hardening a new S3 bucket with HTTPS-only and KMS-only-upload statements as a baseline
  • Granting a specific external AWS account or role read/write access to a bucket via a custom statement
  • Producing the bucket policy JSON to embed in a Terraform `aws_s3_bucket_policy` or CloudFormation `AWS::S3::BucketPolicy` resource

Common Mistakes

  • Getting the KMS condition key backwards, using StringEquals with the wrong encryption value instead of StringNotEquals against aws:kms, which fails to actually block unencrypted uploads.
  • Forgetting to include both the bucket ARN and the `/*` object ARN in the HTTPS statement's Resource, which leaves either bucket-level or object-level requests unprotected.

Tips

  • Pair this with the IAM Policy Generator when the access you're granting is really about a specific IAM principal's permissions rather than a bucket-wide rule.

References

Frequently Asked Questions