S3 Bucket Policy Public Access Checker
Check an S3 bucket policy for public, cross-account, and service-principal exposure with severity findings and remediation cues.| {{ header }} | Copy |
|---|---|
| {{ cell.value }} {{ cell.value }} |
{{ cliOutput }}
Introduction:
Amazon S3 bucket policies are small JSON documents with large consequences. A single Allow statement can make objects readable by the public, let another AWS account list or write into a bucket, or give an AWS service permission that is too broad for the intended delivery path. The policy may look tidy in a pull request while still depending on a wildcard principal, a bucket-wide ARN, or a condition that does not actually pin access to the right organization, account, VPC endpoint, source ARN, or CloudFront distribution.
Public access in S3 is not limited to a website-style bucket. AWS treats some wildcard principals, broad network ranges, public ACL grants, and public bucket or access point policies as public access signals. Conditions can make a grant safer only when they contain fixed trust values. A condition that names a broad CIDR range, a wildcard VPC, or a loose principal pattern can still leave the policy public or difficult to defend in review.
Block Public Access is an important guardrail, but it is not a substitute for understanding the policy. The four settings act at organization, account, access point, and bucket levels, and S3 uses the most restrictive applicable setting. That means a risky policy can be rejected, restricted, or left active depending on where the guardrail is configured. It also means a local JSON review should be paired with the live bucket policy status before a change is approved.
Good S3 policy review separates intent from syntax. A private internal bucket should not contain anonymous object reads. A CloudFront private origin should rely on the CloudFront service principal plus fixed source conditions, not a public read statement. A partner share should name the expected account or role. An organization-wide share should use a fixed organization ID or equivalent boundary. The same JSON shape can be acceptable in one access model and dangerous in another.
| Term | Review meaning | Common mistake |
|---|---|---|
| Principal | The account, role, service, or public actor receiving permission. | Using * when only a service or partner account should be trusted. |
| Action | The S3 operation family, such as read, list, write, or policy administration. | Treating public read and public write as similar risk. |
| Resource | The bucket ARN, object ARN, or wildcard surface affected by the statement. | Granting arn:aws:s3:::* or a bucket wildcard when one object prefix was intended. |
| Condition | The trust boundary that can pin a broad principal to a fixed source. | Relying on loose patterns, broad IP ranges, or missing confused-deputy checks. |
How to Use This Tool:
Use the checker as a pre-approval review aid for pasted bucket policy JSON, Terraform-generated policy output, or a saved get-bucket-policy response. The scan runs in the browser and produces a ranked review queue rather than changing AWS resources.
- Set Bucket label to the bucket name, resource label, change ticket, or pull request identifier you want to carry into exports.
- Choose the Intended access model. Private, CloudFront origin, public website, partner, service delivery, and organization-sharing models change which findings are expected and which should block approval.
- Select the known Effective Block Public Access posture. Leave it as unknown when you do not have live account, access point, and bucket evidence; unknown posture does not reduce the exposure score.
- Enter the Bucket owner account and any Trust anchors such as approved account IDs, organization IDs, role ARNs, source ARNs, CloudFront distribution ARNs, or VPC endpoint IDs.
- Paste, browse, or drop the Bucket policy JSON. Use Format JSON if the document parses but is hard to read.
- Open Exposure Findings first, then confirm statement-by-statement details in Statement Review and the proposed fixes in Remediation Plan.
- Use AWS CLI Snippets after local review to check live policy status and trigger or inspect AWS-side findings.
If parsing fails, fix the JSON shape before interpreting any result. If the owner account is blank, same-account and cross-account separation is weaker, so treat partner and external-account findings as less certain until live account data is checked.
Interpreting Results:
The Public Access Review summary gives the fastest read: critical and high-risk rows should stop approval, medium rows need reviewer sign-off, and a 0 blockers result means no local finding crossed the selected threshold. It does not prove that the live bucket is private, because ACLs, access points, account settings, organization settings, and IAM Access Analyzer findings are outside the pasted JSON.
- Exposure Findings is the approval queue. Read the severity, statement ID, evidence, remediation, and Block Public Access effect together.
- Statement Review is the audit ledger. It keeps Allow and Deny statements visible, including condition trust and numeric exposure score.
- Remediation Plan turns repeated findings into changes such as replacing
Principal "*", adding source boundaries, or enabling all Block Public Access settings. - Public Exposure Map shows which statements get most of their score from principal, action, resource, or condition gaps.
Do not overread a low score when Effective Block Public Access posture is unknown or when a public policy is intentional. Verify the live bucket with AWS tooling and keep the selected access model in the change record.
Technical Details:
An S3 bucket policy statement is evaluated from several pieces that interact. The principal decides who receives the permission. The action decides whether the grant is read-only, list-capable, write-capable, or administrative. The resource decides whether the grant reaches one object prefix, one bucket, or a wider S3 surface. The condition decides whether a broad grant is tied to a fixed trust boundary.
The local exposure score is intentionally conservative. Public principals, AuthenticatedUsers, NotPrincipal Allows, unapproved external accounts, service principals without fixed source conditions, write/admin actions, wildcard resources, and missing or weak conditions all add weight. The selected access intent, Block Public Access posture, and review mode then adjust the score.
Formula Core:
The score is a bounded risk score, not an AWS authorization decision.
| Symbol | Meaning | Examples |
|---|---|---|
P |
Principal risk | Public, AuthenticatedUsers, service, cross-account, trusted external. |
A |
Action class risk | Read, list, write, admin, NotAction. |
R |
Resource scope risk | Exact bucket, object wildcard, bucket wildcard, all S3 resources. |
C |
Condition gap | Missing condition, partial condition, fixed source boundary, weak wildcard. |
I, B, M |
Intent, Block Public Access, and review-mode factors | Static website public read lowers only read-only exposure; BPA off raises residual risk. |
Severity Bands:
| Band | Score range | Typical meaning |
|---|---|---|
| Critical | 82 to 100 | Public or unapproved external access should be removed before deployment. |
| High | 58 to 81 | Approval blocker until principal, action, resource, or condition scope is tightened. |
| Medium | 32 to 57 | Needs reviewer sign-off and stronger evidence for the access intent. |
| Low | 1 to 31 | Scoped finding worth documenting, especially for future drift review. |
| Control | 0 | Deny statement or no exposure signal crossed the local threshold. |
The checker also recognizes several policy wrappers, including raw policy documents, AWS CLI policy strings, and PolicyDocument objects. Unsupported or malformed statement shapes are surfaced as review errors because missing Effect, Action, Principal, or Resource fields can hide the real authorization intent.
Limitations and Privacy Notes:
The pasted policy is reviewed in the browser. The checker does not call AWS, change settings, read bucket ACLs, inspect access points, or know the effective organization and account Block Public Access state unless you supply that context.
- Use AWS CLI Snippets or the S3 console to verify live
get-bucket-policy-statusand Block Public Access settings. - Run IAM Access Analyzer for S3 when the change needs account-aware public or cross-account findings.
- Treat static website access, CloudFront origins, service writers, and partner sharing as separate access models; a low score in the wrong model can mislead.
Worked Examples:
Public write in a private bucket
A policy with Principal "*", s3:PutObject, and arn:aws:s3:::prod-assets-bucket/* under Private internal bucket should produce a critical or high-risk Exposure Findings row. The Remediation Plan should point to removing public write/admin actions and replacing the principal with exact account, role, or service trust.
CloudFront origin access
A CloudFront service principal can be reasonable for a private origin when Intended access model is CloudFront OAC/OAI private origin and the statement includes fixed aws:SourceArn and aws:SourceAccount conditions. The same service principal without those conditions should show a service boundary gap.
Unknown Block Public Access posture
If the JSON looks scoped but Effective Block Public Access posture is Unknown or not supplied, the summary warning is expected. Keep the finding in the change record, then verify the live bucket and account settings before treating the review as clean.
FAQ:
Does a clean result prove the bucket is private?
No. A clean result means the pasted policy did not cross the local exposure threshold for the selected settings. Live ACLs, access points, IAM Access Analyzer findings, account posture, and organization posture still need AWS-side verification.
Why does the access model change the result?
The same statement has different meaning when the bucket is a public website, a CloudFront private origin, a partner share, or an internal bucket. The checker lowers risk only for narrow cases that match the selected access model.
Why is a service principal flagged?
AWS service principals often need aws:SourceArn and aws:SourceAccount conditions to prevent confused-deputy access. A service grant without a fixed source boundary should be reviewed before approval.
What should I fix first?
Start with P0 and P1 rows in Remediation Plan. Public write/admin actions, wildcard principals on private buckets, missing service source conditions, and off or unknown Block Public Access posture usually deserve attention before lower-severity cleanup.
Glossary:
- Block Public Access
- S3 guardrail settings that can reject or restrict public access from bucket policies, access point policies, and ACLs.
- Trust anchor
- An approved account, organization ID, source ARN, VPC endpoint, or role ARN used to decide whether a broad-looking grant is expected.
- Public principal
- A principal such as
*,AllUsers, orAuthenticatedUsersthat can include actors outside the bucket owner's account. - Confused deputy
- A cross-service risk where a trusted AWS service can be used by the wrong source unless conditions pin the source account or resource.
References:
- Blocking public access to your Amazon S3 storage, Amazon Web Services.
- Reviewing bucket access using IAM Access Analyzer for S3, Amazon Web Services.
- Preview access, Amazon Web Services.
- Policies and permissions in Amazon S3, Amazon Web Services.