S3 Bucket Policy Public Access Checker
Review an S3 bucket policy for public or cross-account grants, test trust boundaries, and prepare the live AWS checks needed before approval.| Severity | Statement | Exposure | Evidence | Next action | Copy |
|---|---|---|---|---|---|
| {{ row.severity }} | {{ row.statement }} | {{ row.exposure }} | {{ row.evidence }} | {{ row.action }} |
| Statement | Effect | Principal | Actions | Resource | Trust boundary | Priority | Decision | Copy |
|---|---|---|---|---|---|---|---|---|
| {{ row.statement }} | {{ row.effect }} | {{ row.principal }} | {{ row.actions }} | {{ row.resource }} | {{ row.trust }} | {{ row.priority }} | {{ row.decision }} |
| Priority | Change | Target | Why it matters | Copy |
|---|---|---|---|---|
| {{ row.priority }} | {{ row.change }} | {{ row.target }} | {{ row.reason }} |
{{ cliText }}
An S3 bucket policy can be valid JSON and still grant far more access than a reviewer intended. The practical question is who can reach which bucket resources, through which actions, and under what fixed trust conditions. A wildcard principal that allows object reads may be intentional for a static website; the same principal with write, delete, ACL, or policy-administration actions is a much more serious exposure.
Public access is not determined by the bucket policy alone. Amazon S3 can enforce Block Public Access at organization, account, bucket, and access-point levels, applying the most restrictive effective settings. Access control lists, access points, identity policies, organization controls, and other resource policies can also change effective access. A local policy review should therefore identify risky grants without claiming to reproduce the live AWS authorization decision.
| Signal | Why it matters | Evidence that narrows it |
|---|---|---|
| Wildcard or broad principal | May allow anonymous or broadly delegated access. | An AWS-recognized fixed organization, account, source ARN, VPC, endpoint, or narrow source-IP condition. |
| External AWS account | Creates cross-account trust outside the bucket owner's account. | An approved exact account or role recorded for the change. |
| AWS service principal | Can be correct for delivery services but may expose confused-deputy risk. | Fixed aws:SourceArn and aws:SourceAccount values where the service supports them. |
| Write or administration action | Can alter objects, ACLs, policies, or public-access controls. | An exact trusted principal, narrow resources, and conditions tied to the intended workflow. |
| Explicit Deny | May constrain related Allows but does not erase the need to compare scope. | Matching principals, actions, resources, and condition logic. |
Intent changes the review decision without changing what the policy text says. Public object read can match an intentional website model, but it should remain read-only and isolated from private prefixes and write paths. Private origins, internal buckets, partner sharing, organization sharing, and service delivery each need a different trust boundary.
Block Public Access is a guardrail, not a substitute for a scoped policy. A risky policy can become effective later if a blocking setting is removed. Unknown live posture should therefore be treated as missing evidence, while an all-on posture should be recorded as protection that still needs verification in AWS.
How to Use This Tool:
Review one proposed or current bucket policy against the access model that the change is supposed to implement.
- Paste the Bucket policy JSON or load one JSON or TXT file. Policy documents and common policy wrappers are accepted; malformed JSON or a missing
Statementstops the review. - Choose the Intended access model and the known Effective Block Public Access posture. Use Unknown when live organization, account, access-point, or bucket evidence is unavailable.
- Enter the 12-digit Bucket owner AWS account ID and list only approved external trust anchors. Leaving the owner blank makes same-account and cross-account classification less precise.
- Review Exposure findings and Remediation plan. Use AWS checks for the read-only commands and Access Analyzer handoff needed to confirm the live bucket before approval.
Interpreting Results:
Block means at least one Allow statement is public under the local rules and does not fit the narrowly accepted intentional public-read case. Anonymous write or administration access receives the highest remediation urgency.
Review covers intentional public object read, an unapproved external account, a service principal without a fixed source boundary, broad write scope, or an incomplete statement. It requires a reviewer to confirm intent and live AWS evidence rather than treating the policy as safe by default.
Clear locally means no statement crossed the bounded decision rules. It is not an AWS authorization result. Confirm the effective Block Public Access settings, bucket policy status, ACLs, access points, organization controls, and Access Analyzer findings before approval.
Technical Details:
Each policy statement is normalized to an effect, principal class, action class, resource breadth, and condition set. The decision rules are applied to the statement as a whole. Explicit Deny statements are retained as control evidence, but they are not assumed to neutralize an Allow without a scope comparison.
Rule Core:
| Order | Condition | Decision |
|---|---|---|
| 1 | Effect is Deny. | Control evidence. |
| 2 | Principal is public or uses NotPrincipal, and no recognized fixed trust value narrows it. | Public under the bounded review. |
| 3 | The public statement matches static-website intent and allows object read only. | Intentional public read; reviewer sign-off. |
| 4 | Any other public statement. | Block approval; public write or administration is called out separately. |
| 5 | An external account is not in the approved trust anchors. | Reviewer sign-off. |
| 6 | An AWS service Allow lacks a fixed source ARN, source account, or source owner boundary. | Reviewer sign-off. |
| 7 | A write or administration action reaches all resources or a wildcard bucket resource. | Reviewer sign-off. |
| 8 | No earlier rule applies and required statement fields are present. | Scoped. |
Recognized fixed trust keys include organization ID, source account, source ARN, principal ARN, fixed source IP, VPC, VPC endpoint, source owner, user ID, and S3 data-access-point boundaries. Conditions using negation, IfExists, policy variables, question-mark patterns, or unsupported wildcards do not count as fixed. An IPv4 source range must be at least a /8 and an IPv6 range at least a /32 to pass this bounded fixed-range test; that recognition does not prove the range is suitably narrow for the real risk.
The statement ledger also assigns a repository-authored review-priority score so risky factors can be compared. This score is not an AWS severity or authorization formula.
| Factor | Selected weights |
|---|---|
| Principal | Public or NotPrincipal 45; external 28; missing 20; service 10; approved external 5; specific 3. |
| Action | Write or administration 30; object read 16; bucket list 12; other specific action 8. |
| Resource | All or NotResource 10; bucket wildcard 8; object wildcard 4; specific resource 2. |
| Condition gap | 18 for an unbounded public principal; 12 for an unbounded external or service principal; otherwise 0. |
For an Allow statement, the priority is the sum of the four components, capped at 100. Deny statements receive priority 0. Missing required policy fields force reviewer sign-off even when the numeric sum is low. The final status is block if any blocking statement exists, otherwise review if any review or intentional-public-read statement exists, and otherwise clear.
Input validation allows a bucket or review label up to 128 characters, approved trust anchors up to 12,000 characters, and policy source up to 200,000 characters. A supplied owner account must contain exactly 12 digits. The policy must resolve to an object with at least one object-valued Statement.
Limitations and Privacy Notes:
The policy text and uploaded file are parsed in the browser and are not sent to AWS. The review cannot see live bucket ACLs, access points, organization policies, identity policies, KMS key policies, current Block Public Access inheritance, or Access Analyzer findings.
- The decision model is deliberately bounded and does not reproduce AWS's complete policy engine.
- Approved trust anchors are reviewer-supplied evidence; an entry in that list does not prove current authorization.
- Run the generated read-only checks and preview external access in IAM Access Analyzer before saving a production policy.
Worked Examples:
Anonymous upload path
A private bucket policy allows s3:PutObject to Principal: "*" from 0.0.0.0/0. That source range is not a fixed trust boundary under the review rules, and upload is a write action. The statement blocks approval and produces P0 remediation to remove anonymous write access.
CloudFront private origin
A CloudFront service principal receives s3:GetObject with exact distribution ARN and source-account conditions. Under a CloudFront origin access model, the fixed service boundary keeps the statement scoped. Live Block Public Access and Access Analyzer evidence are still required before approval.
References:
- Blocking public access to Amazon S3 storage, Amazon Web Services.
- Previewing access with IAM Access Analyzer, Amazon Web Services.
- Policies and permissions in Amazon S3, Amazon Web Services.
- How to create a private AWS S3 bucket, Simplified Guide.