S3 bucket policy vs access control list
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
S3 bucket policies and ACLs both control access, but they do it at different layers and with very different levels of expressiveness. In modern S3 usage, bucket policies and IAM policies usually do the real work, while ACLs are either minimized or disabled unless you have a specific compatibility reason to keep them.
What a Bucket Policy Is
A bucket policy is a JSON resource policy attached to a bucket. It can allow or deny actions for specific principals, resources, and conditions.
Example bucket policy statement:
The important point is that policies are expressive. They can target specific actions, specific prefixes, and optional conditions such as source IPs or TLS requirements.
What an ACL Is
An ACL is an older access-control mechanism attached to a bucket or object. It grants a small set of coarse permissions such as read or write to predefined grantees or specific AWS accounts.
ACLs are much less expressive than policies. They do not give you the same condition logic or fine-grained control that bucket policies provide.
So the practical difference is:
- Bucket policy: flexible, JSON-based, condition-aware access rules.
- ACL: older, coarse-grained allow list.
Why Policies Usually Win
Bucket policies are preferred for most new designs because they are easier to reason about in a central place and work well with IAM-based access management.
They are better for cases such as:
- Granting cross-account access to a bucket prefix.
- Requiring transport security.
- Allowing only specific actions.
- Restricting access by source conditions.
ACLs can still exist, but they are rarely the best primary control plane when a bucket policy can express the requirement clearly.
Example Use Case Comparison
Suppose you want to let another AWS account read objects under reports/ and deny everything else by default. A bucket policy handles that cleanly.
By contrast, trying to model nuanced prefix-based access with ACLs is awkward because ACLs do not express the same rich conditions.
That is why ACLs feel simple at first but become limiting quickly.
Object-Level Ownership and Legacy Compatibility
ACLs historically mattered more when object ownership and cross-account uploads were common pain points. In older workflows, object ACLs were used to make sure another account could read or manage uploaded objects.
Modern S3 setups often reduce this complexity by preferring policy-based controls and ownership settings that minimize ACL dependence.
So while ACLs are not mythical or obsolete in every edge case, they are no longer the default design tool for ordinary bucket authorization.
Use the Smallest Number of Mechanisms You Can Explain
S3 access becomes confusing when multiple layers overlap:
- IAM identity policy.
- Bucket policy.
- ACL.
- Block Public Access settings.
The more overlapping controls you use, the harder debugging becomes. A good operational principle is to keep the model as simple as the security requirement allows.
Common Pitfalls
- Reaching for ACLs first when a bucket policy would express the requirement more clearly.
- Forgetting that explicit denies in policy logic still matter even if an ACL seems permissive.
- Debugging an ACL issue when the real blocker is Block Public Access or IAM policy.
- Using both ACLs and policies without a clear reason, which makes access behavior harder to explain.
- Treating ACLs as fine-grained authorization tools when they are fundamentally coarse-grained.
Summary
- Bucket policies and ACLs both control S3 access, but policies are far more expressive.
- Bucket policies are usually the better default for modern S3 authorization.
- ACLs are older and more limited, and they should generally be used only when you have a specific need.
- Keep IAM, bucket policy, ACL, and public-block settings aligned or debugging becomes painful.
- In most new designs, policy-driven access control is easier to manage and audit than ACL-heavy access control.
Related reading

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.