What Is an S3 Bucket Policy and How Does It Control Access?
Learn what an S3 bucket policy is, its JSON structure, how it differs from IAM policies, and how to avoid accidental public exposure of bucket data.
Expected Interview Answer
An S3 bucket policy is a resource-based JSON permissions document attached directly to a bucket that specifies which principals can perform which actions on the bucket and its objects, under what conditions.
Unlike an IAM policy, which is attached to a user or role and travels with that identity, a bucket policy is attached to the bucket itself and applies to any principal accessing it, including anonymous or cross-account requests. Each statement defines an Effect (Allow/Deny), a Principal (who it applies to), an Action (like s3:GetObject or s3:PutObject), a Resource (the bucket or object ARN), and optional Conditions (like requiring HTTPS or restricting by source IP). Because bucket policies and IAM policies can both apply to the same request, AWS evaluates them together, and any explicit Deny in either one overrides an Allow elsewhere. Bucket policies are the standard mechanism for cross-account access, static website hosting permissions, and enforcing conditions like TLS-only access, and misconfigured bucket policies (like accidentally allowing a wildcard Principal) are one of the most common sources of accidental public data exposure.
- Enables fine-grained, resource-level access control on a bucket
- Supports cross-account access without creating IAM users in each account
- Can enforce conditions like requiring encrypted, HTTPS-only requests
- Works alongside IAM policies with explicit Deny always winning
- Central place to audit exactly who can access a bucket's data
AI Mentor Explanation
An S3 bucket policy is like a ground's own standing orders posted at the gate, stating exactly which types of visitors — sponsors, press, rival team staff — may enter and under what conditions, regardless of whatever pass an individual carries. If those standing orders explicitly deny entry to a group, that denial holds even if a separate gate pass would otherwise have let them in.
Step-by-Step Explanation
Step 1
Attach the policy to the bucket
A bucket policy is a JSON document set directly on the bucket resource, not on a user or role.
Step 2
Define the principal
Specify which AWS accounts, IAM roles, or '*' for public/anonymous access the statement applies to.
Step 3
Specify actions and resources
List S3 actions like s3:GetObject or s3:PutObject and the exact bucket/object ARNs they apply to.
Step 4
Add conditions for tighter control
Conditions can require HTTPS, restrict by source IP, or require specific encryption settings.
Step 5
Evaluate alongside IAM policies
AWS combines bucket policies and IAM policies for each request, and any explicit Deny overrides an Allow.
What Interviewer Expects
- Explains a bucket policy as a resource-based, JSON policy attached to the bucket itself
- Distinguishes it from identity-based IAM policies attached to users/roles
- Describes the Effect, Principal, Action, Resource, Condition structure
- Knows explicit Deny always overrides Allow across combined policies
- Mentions cross-account access and enforcing HTTPS-only as common use cases
Common Mistakes
- Confusing a bucket policy with an IAM policy attached to a user
- Accidentally setting Principal to '*' and exposing a bucket publicly
- Forgetting that explicit Deny always wins even if another policy allows access
- Not adding a condition to require secure transport (HTTPS) for sensitive buckets
Best Answer (HR Friendly)
“An S3 bucket policy is a set of rules attached directly to a storage bucket that says exactly who can read or write to it and under what conditions. It's a common source of accidental public exposure if written too broadly, so it needs careful review.”
Code Example
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::app-data", "arn:aws:s3:::app-data/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
},
{
"Sid": "AllowPartnerAccountRead",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:root" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::app-data/reports/*"
}
]
}Follow-up Questions
- How does a bucket policy differ from an IAM policy attached to a user?
- What happens when a bucket policy allows access but an IAM policy denies it?
- How would you grant cross-account access to a specific S3 prefix?
- What is S3 Block Public Access and how does it relate to bucket policies?
- How would you enforce that all uploads to a bucket are server-side encrypted?
MCQ Practice
1. Where is an S3 bucket policy attached?
A bucket policy is a resource-based policy attached to the S3 bucket itself, applying to any principal accessing it.
2. If an IAM policy allows an action but a bucket policy explicitly denies it, what happens?
AWS policy evaluation always applies an explicit Deny over any Allow, regardless of where it's defined.
3. What is a common risk of misconfigured bucket policies?
Overly broad principals, like using '*', can accidentally make bucket contents publicly accessible.
Flash Cards
What is an S3 bucket policy? — A resource-based JSON policy attached to a bucket controlling which principals can perform which actions on it.
How does it differ from an IAM policy? — IAM policies attach to users/roles; bucket policies attach to the resource and apply to any principal accessing it.
What always wins in policy evaluation? — An explicit Deny, regardless of which policy (IAM or bucket) contains it.
What's a common bucket policy risk? — Setting Principal to '*' by mistake, which can expose the bucket's contents publicly.