AWS Systems Architect Professional

Amazon S3 IAM Policies, Bucket Policies, and ACLs – SAP-C02 Study Guide

Learn how S3 IAM policies, bucket policies, and ACLs control access, including policy evaluation, cross-account access, and SAP-C02 exam traps.

AWS Systems Architect ProfessionalAWS Systems Architect ProfessionalUpdated Sep 1, 2026
Study options
WatchComing later
ListenComing later
ReadAvailable
ReviewComing later

Study guide

Technical reference and lesson notes

Purpose of This Lesson

Amazon S3 supports several mechanisms for controlling access to buckets and objects. The most important distinctions are whether permissions are attached to an identity or a resource, whether they apply at the bucket or object level, and how AWS evaluates conflicting permissions.

For most modern designs, use IAM policies and S3 bucket policies. S3 access control lists (ACLs) are a legacy mechanism with a more limited permissions model.

Key Concepts

IAM policies: identity-based permissions

IAM policies are attached to IAM identities:

  • Users
  • Groups
  • Roles

A policy attached to a group applies to users who are members of that group. IAM policies define which actions an identity can perform on specified AWS resources.

For example, an IAM policy could allow a role to perform s3:GetObject against objects in a particular bucket. IAM policies can also grant permissions for services other than S3, making them useful for centrally managing permissions across a broader AWS environment.

IAM policies use JSON and the AWS policy language. They do not normally include a Principal element because the identity to which the policy is attached is already the subject of the permission.

S3 bucket policies: resource-based permissions

A bucket policy is a resource-based policy attached directly to an S3 bucket. It uses the same JSON policy language as IAM policies but describes permissions from the perspective of the bucket.

A bucket policy commonly includes:

  • Principal: the AWS account, IAM user, IAM role, or other principal receiving access
  • Action: the S3 API operation or operations allowed or denied
  • Resource: the bucket ARN and/or object ARNs
  • Effect: Allow or Deny

A bucket policy can grant access to a specific principal, an AWS account, or—where appropriate—a broader set of principals. Broad principals should be avoided unless tightly constrained by conditions and other controls.

Remember that bucket and object resources use different ARN forms:

arn:aws:s3:::example-bucket
arn:aws:s3:::example-bucket/path/to/object.txt
arn:aws:s3:::example-bucket/*

Operations on the bucket itself, such as listing the bucket, generally use the bucket ARN. Operations on objects, such as GetObject and PutObject, generally use object ARNs.

S3 ACLs: legacy access control

S3 ACLs can be attached to either:

  • A bucket
  • An individual object

ACLs predate IAM and provide a limited set of grantees and permissions compared with IAM and bucket policies. They are generally not the preferred mechanism for new architectures.

Modern S3 configurations commonly disable ACL-based access control by using Bucket owner enforced object ownership, where supported. This simplifies ownership and authorization by relying on policies instead of object ACLs. Existing workloads or integrations may still require ACL compatibility, so the design must account for application behavior and object ownership.

Policy evaluation: explicit deny wins

AWS authorization begins with an implicit deny. A request is permitted only when an applicable policy provides an allow and no applicable policy provides an explicit deny.

The simplified evaluation model is:

  1. Start with an implicit deny.
  2. Evaluate all relevant policies.
  3. If an applicable explicit deny exists, the request is denied.
  4. Otherwise, if an applicable allow exists, the request is allowed.
  5. If no applicable allow exists, the request remains denied.

An explicit Deny overrides an Allow, even when the allow comes from another policy. This makes explicit denies useful for guardrails, such as preventing access outside approved networks or blocking unencrypted uploads.

Exam-Relevant Takeaways

  • IAM policies are identity-based and attach to users, groups, or roles.
  • Bucket policies are resource-based and attach directly to S3 buckets.
  • IAM policies normally do not contain Principal; bucket policies do.
  • ACLs can apply to buckets or individual objects, but have a more limited model and are generally legacy.
  • A bucket policy is often the simplest way to grant cross-account S3 access without creating an IAM role in the other account.
  • IAM policies are useful when permissions must cover multiple AWS services or many S3 buckets.
  • A large or complex IAM policy may motivate moving S3-specific permissions into bucket policies, subject to the overall design.
  • Authorization requires an applicable allow and no applicable explicit deny.
  • The absence of an allow is an implicit deny; it is not the same as an explicit deny.
  • Bucket-level and object-level ARNs are not interchangeable. A policy that grants access to arn:aws:s3:::example-bucket does not automatically grant access to objects under that bucket.

Architecture Decision Guide

RequirementPreferred mechanismReason
Grant permissions to an IAM role used by an applicationIAM policyPermissions follow the identity wherever the role is used
Manage permissions across S3 and other AWS servicesIAM policyIAM policies can cover multiple AWS services
Give a principal access to one specific bucketBucket policy or IAM policyChoose based on whether resource- or identity-centric management is preferred
Grant access from another AWS account without assuming a roleBucket policyThe bucket can name the external account or principal directly
Control access to individual legacy objectsObject ACLACLs support object-level permissions, but should generally be avoided for new designs
Enforce organization-wide restrictions such as approved VPC endpoints or encryptionBucket policy with conditions and explicit deniesResource-based guardrails can directly protect the bucket
Simplify ownership and authorization for newly uploaded objectsPolicies with S3 Object Ownership, commonly Bucket owner enforcedReduces reliance on object ACLs

Common Exam Traps

Confusing identity-based and resource-based policies

An IAM policy is attached to an identity. A bucket policy is attached to an S3 bucket. The policy syntax is similar, so the attachment location and presence of Principal are common exam clues.

Using a bucket ARN for object operations

GetObject, PutObject, and DeleteObject require object resources. A policy that only references the bucket ARN may not authorize those operations. Use an object ARN such as arn:aws:s3:::example-bucket/* or a narrower prefix.

Assuming an Allow overrides a Deny

It does not. Any applicable explicit deny wins, regardless of where the allow was granted.

Treating no Allow as an explicit Deny

Both result in a denied request, but they are conceptually different. An explicit deny is a deliberate policy statement and overrides all allows. An implicit deny simply means that no applicable allow exists.

Choosing ACLs for a new workload by default

ACLs are not the normal first choice for new S3 designs. Prefer IAM and bucket policies unless a legacy application or integration specifically requires ACL behavior.

Forgetting cross-account authorization

A bucket policy can grant access to an external account, but the final design still needs a valid principal and appropriate permissions. For an IAM principal in another account, the resource policy in the bucket-owning account must grant access, and the identity must be allowed to use the relevant action where required by the access pattern.

Granting a bucket permission when an object permission is required

Listing a bucket and reading an object are different operations and commonly require different actions and resources, such as s3:ListBucket on the bucket ARN and s3:GetObject on object ARNs.

Real-World Engineer Notes

  • Prefer roles over long-lived IAM users for applications, workloads, and federated access.
  • Keep identity-based permissions focused on what a principal needs, and use bucket policies for resource-specific controls and cross-account sharing.
  • Avoid broad statements such as Principal: "*" unless the bucket is intentionally public and additional controls make the exposure acceptable.
  • Use conditions to narrow access by encryption requirements, source VPC endpoint, source account, principal, or other relevant context.
  • Separate bucket-level actions from object-level actions in policy statements. This makes intent clearer and avoids accidental authorization gaps.
  • When migrating away from ACLs, verify object ownership, upload behavior, replication workflows, and third-party integrations before enabling an ACL-disabled configuration.
  • Test both positive and negative cases: expected access should work, while access from an unapproved identity, network path, or encryption state should fail.

Quick Reference Summary

FeatureIAM policyS3 bucket policyS3 ACL
Policy typeIdentity-basedResource-basedLegacy access control
Attached toUser, group, or roleS3 bucketBucket or object
Uses JSON policy languageYesYesNo equivalent full policy language
Normally includes PrincipalNoYesUses predefined ACL grantees
Supports other AWS servicesYesNo, S3 bucket resource onlyNo
Useful for cross-account accessSometimes, often with rolesYes, directly on the bucketLimited and legacy
Recommended for new S3 designsYesYesGenerally no

Flashcards

1. What type of policy is an IAM policy?

An identity-based policy attached to an IAM user, group, or role.

2. What type of policy is an S3 bucket policy?

A resource-based policy attached directly to an S3 bucket.

3. Why does an IAM policy normally omit Principal?

Because the policy is attached to the identity that receives the permission.

4. Which policy element identifies the recipient in a bucket policy?

The Principal element.

5. Where can an S3 ACL be attached?

To a bucket or an individual object.

6. Why are ACLs usually avoided in new S3 architectures?

They provide fewer permissions and grantee options and complicate ownership and authorization compared with policies.

7. What happens when an explicit deny and an allow both apply?

The explicit deny wins.

8. What is an implicit deny?

The default denial that remains when no applicable allow exists.

9. Which ARN generally applies to s3:ListBucket?

The bucket ARN, such as arn:aws:s3:::example-bucket.

10. Which ARN generally applies to s3:GetObject?

An object ARN, such as arn:aws:s3:::example-bucket/* or a specific object ARN.

11. When is an IAM policy especially useful for S3 access?

When a principal needs permissions across multiple S3 buckets or other AWS services.

12. When is a bucket policy especially useful?

When access should be controlled from the bucket side, particularly for resource-specific or cross-account access.

Practice Questions

Question 1

An application running under an IAM role must read objects from three S3 buckets and publish messages to Amazon SNS. Which access-control approach is most appropriate?

A. Configure object ACLs on all S3 objects and grant SNS access through an S3 ACL.

B. Attach an IAM policy to the application role that grants the required S3 and SNS actions.

C. Attach a separate bucket policy to each bucket and configure SNS permissions in the bucket policies.

D. Make all three buckets public and restrict SNS using an S3 bucket policy.

Correct answer: B

The application uses an IAM role and needs permissions for both S3 and SNS. An IAM policy attached to the role can centrally grant the required actions across multiple services and resources.

Question 2

A company in Account A needs to allow a specific IAM role in Account B to download objects from one S3 bucket. The company does not want the role to assume a role in Account A. Which mechanism should be used to grant the S3-side permission?

A. An S3 bucket policy in Account A naming the role in Account B as the principal.

B. An object ACL that grants access to every authenticated AWS user.

C. An IAM group in Account A containing the role from Account B.

D. A security group rule attached to the S3 bucket.

Correct answer: A

A bucket policy can directly grant a principal from another AWS account access to the bucket without requiring role assumption. IAM groups cannot contain principals from another account, and security groups do not control S3 authorization.

Question 3

An S3 bucket has an identity policy allowing s3:GetObject and a bucket policy explicitly denying s3:GetObject when the request does not use an approved VPC endpoint. A user accesses the bucket from the public internet. What is the result?

A. Access is allowed because the identity policy grants s3:GetObject.

B. Access is allowed because the bucket policy applies only to anonymous users.

C. Access is denied because the explicit bucket-policy deny overrides the allow.

D. The request succeeds only if the object has a public-read ACL.

Correct answer: C

An applicable explicit deny overrides any allow from an identity policy. The request does not satisfy the approved-network condition, so S3 denies it.

Question 4

A policy allows s3:GetObject on arn:aws:s3:::reports-bucket but users still cannot download files from the bucket. What is the most likely issue?

A. s3:GetObject requires an object ARN rather than only the bucket ARN.

B. s3:GetObject can only be granted through an ACL.

C. S3 does not support IAM policies for object downloads.

D. The bucket policy must contain an Allow and an explicit Deny together.

Correct answer: A

The bucket ARN represents the bucket resource. Object operations generally require object ARNs, such as arn:aws:s3:::reports-bucket/* or a specific object path. Listing the bucket, if needed, is a separate permission using s3:ListBucket on the bucket ARN.