Skip to content
AWS · S3 security

S3 Bucket Policy & Permissions Validator

Find out if a bucket is really public, who can do what, and which Security Hub controls fail — with one-click fixes and secure templates.

Last updated · public-access rules and Security Hub controls checked against AWS documentation

S3 Security Validator
S3 Bucket Policy &
Permissions Validator

Paste your bucket policy JSON and get an instant security audit — public access risks, IAM misconfigurations, compliance gaps, and remediation steps.

20+ security checks Client-side only — no data sent Mapped to AWS Security Hub S3 controls
Bucket Policy JSON
s3://
Load sample:
Security Findings
Statement Breakdown
Permission Matrix
Compliance & Best Practices

Understanding AWS S3 Bucket Policies & Security

S3 bucket policies are JSON-based resource policies that control who can access your S3 buckets and objects, and what they can do. A misconfigured policy is one of the most common causes of accidental data exposure in AWS. This validator checks your policy against AWS security best practices and the AWS Security Hub S3 controls, using Amazon S3’s own definition of a public policy — entirely in your browser.

What makes an S3 bucket policy dangerous?
The most dangerous patterns are: Principal set to "*" (allows any internet user), Action set to "s3:*" (all S3 operations), missing Condition blocks (no IP/VPC/MFA restrictions), NotPrincipal with Allow effect (accidentally allows everyone except listed principals), and AWS service principals without aws:SourceArn or aws:SourceAccount conditions (the “confused deputy” problem).
What is the difference between a bucket policy and ACLs?
Bucket policies are JSON documents attached to the bucket that use IAM policy language. ACLs (Access Control Lists) are a legacy mechanism that assigns predefined permissions to AWS accounts or groups. AWS recommends disabling ACLs (Object Ownership = Bucket owner enforced) and using bucket policies exclusively for finer-grained, auditable access control.
How does S3 Block Public Access work with bucket policies?
S3 Block Public Access (BPA) is a guardrail that overrides bucket policies and ACLs. Even if your policy allows public access, BPA will block it at the account or bucket level. There are 4 BPA settings: BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, and RestrictPublicBuckets. All four should be enabled for any bucket that doesn't need to be public.
What is the aws:SecureTransport condition and why is it important?
The aws:SecureTransport condition key evaluates to true only when the request is sent over HTTPS (TLS). Adding a Deny statement with "aws:SecureTransport": "false" forces all S3 traffic to be encrypted in transit, preventing credential interception via man-in-the-middle attacks. AWS Security Hub control S3.5 checks for it.
What S3 actions are considered high-risk?
High-risk actions: s3:DeleteObject, s3:DeleteBucket, s3:PutBucketPolicy (can replace your security policy), s3:PutBucketAcl (can make bucket public), s3:PutObject (data exfiltration risk), s3:GetObject on sensitive buckets, s3:ListBucket (reveals object keys), and s3:* wildcard. Grant them only to the principals that need them, and only on the resources they need.
How do I allow CloudFront to access a private S3 bucket securely?
Use Origin Access Control (OAC), the modern replacement for Origin Access Identity (OAI). Create an OAC in CloudFront, then add a bucket policy granting s3:GetObject to the CloudFront service principal (cloudfront.amazonaws.com) with an aws:SourceArn condition matching your CloudFront distribution ARN. Never use Principal "*" for CloudFront-backed buckets.
Practical guide

How to test an S3 bucket policy before you deploy it

A bucket policy is evaluated on every request to the bucket, so a single wrong line can expose data to the internet or lock your own applications out. This walkthrough shows how to review a policy quickly, using the samples above.

Step 1: Check who is allowed in (Principal)

Load the Public bucket sample. Its statement has "Effect": "Allow" with "Principal": "*", which means anyone on the internet. That is only correct for a deliberately public static website, and even then it should allow nothing beyond s3:GetObject. For everything else, name the principals: an account (arn:aws:iam::111122223333:root), a role, or a service such as cloudfront.amazonaws.com.

Step 2: Check what they can do (Action)

Load Wildcard actions. "Action": "s3:*" grants every S3 permission, including s3:DeleteObject, s3:PutBucketPolicy and s3:DeleteBucket. Replace it with only the actions the caller needs: usually s3:GetObject to read, plus s3:PutObject to write and s3:ListBucket to list.

Step 3: Match actions to the right resource

This is the most common reason a "correct" policy still returns AccessDenied. Bucket-level actions such as s3:ListBucket apply to the bucket ARN (arn:aws:s3:::my-bucket). Object-level actions such as s3:GetObject apply to objects (arn:aws:s3:::my-bucket/*). A statement that lists both actions against only one ARN silently grants half of what you intended.

Step 4: Add guard conditions

Load Secure policy to see the patterns worth copying:

  • Deny non-TLS access: a Deny statement with "Condition": {"Bool": {"aws:SecureTransport": "false"}}.
  • Limit to your organization: aws:PrincipalOrgID, so a leaked role in an unknown account can't use the bucket.
  • Limit by network: aws:SourceVpce for VPC endpoint access, or aws:SourceIp for fixed office ranges.

Step 5: Cross-account access needs both sides

Load Cross-account. Granting another account in the bucket policy is only half the setup: the role in the other account also needs an IAM policy that allows the same actions on your bucket. If objects are encrypted with a customer-managed KMS key, that key's policy must allow the other account too. Otherwise reads fail even with a perfect bucket policy.

Common mistakes this check catches

  • "Principal": "*" with Allow and no condition: public access.
  • s3:* or s3:Put* granted to applications that only read.
  • NotPrincipal with Allow, which grants access to everyone except the listed principals.
  • Bucket and object ARNs mixed up, as in Step 3.
  • No TLS-only Deny statement.

Is the bucket actually public?

Amazon S3 decides "public" with its own rule: an Allow to "Principal": "*" is public unless a condition limits it to fixed values of keys such as aws:PrincipalOrgID, aws:SourceVpce, aws:SourceVpc, aws:SourceArn, aws:SourceAccount or a narrow aws:SourceIp range. aws:SecureTransport does not make a statement private. The Effective access box uses that rule and the bucket settings you enter:

  • RestrictPublicBuckets on: S3 ignores public grants for anyone outside your account (AWS services still work).
  • BlockPublicPolicy on: S3 refuses to save a public policy.
  • Object Ownership = Bucket owner enforced: ACLs are off, so only policies grant access. This is the default for new buckets since April 2023.

Encryption at rest no longer needs a policy: since January 2023 Amazon S3 encrypts every new object with SSE-S3 by default. Use bucket default encryption if you need SSE-KMS.

The templates give known-good starting points (CloudFront with Origin Access Control, Amazon Connect prompts, access logs, CloudTrail, cross-account read-only, organisation-only, VPC endpoint only), and the one-click fixes add an HTTPS-only Deny, TLS 1.2, aws:SourceAccount for service principals, or the missing bucket or object ARN — with a preview before anything changes.

Before you apply it

  1. Keep S3 Block Public Access on at the account level unless the bucket must be public. It overrides public grants in bucket policies.
  2. Validate with IAM Access Analyzer policy checks, which run in the console when you edit the policy and through the ValidatePolicy API.
  3. Test with a real call from each principal: aws s3 ls s3://my-bucket and aws s3 cp.

For identity-side policies, the IAM Policy Simulator and Policy Generator cover the other half of the permission check.

Official references

Runs 100% in your browser. Your files and data never leave your machine. Nothing is uploaded or stored.

Need a hand with your AWS setup?

Get help from an AWS architect who builds and runs contact centre and AI workloads: IAM, data pipelines, Bedrock and cost reviews.