AWS Security Blog

IAM Policies and Bucket Policies and ACLs! Oh, My! (Controlling Access to S3 Resources)

September 11, 2023: This post has been updated.

Updated on July 6, 2023: This post has been updated to reflect the current guidance around the usage of S3 ACL and to include S3 Access Points and the Block Public Access for accounts and S3 buckets.

Updated on April 27, 2023: Amazon S3 now automatically enables S3 Block Public Access and disables S3 access control lists (ACLs) for all new S3 buckets in all AWS Regions.

Updated on January 8, 2019: Based on customer feedback, we updated the third paragraph in the “What about S3 ACLs?” section to clarify permission management.


In this post, we’ll discuss Amazon Simple Storage Service (Amazon S3) bucket policies and AWS Identity and Access Management (IAM) policies and their different use cases. This post will assist you in distinguishing between the uses of these two types of policies. We’ll also discuss how these policies integrate with some default S3 bucket security settings, like automatically enabling the S3 Block Public Access feature and disabling S3 access control lists (ACLs).

IAM policies vs. S3 bucket policies

To manage AWS access, you set IAM policies and link them to IAM identities (users, groups of users, or roles) or AWS resources. A policy is an object in AWS that, when associated with an identity or resource, defines permissions for that identity or resource. IAM policies specify which actions are allowed or denied on which AWS resources (for example, user Alice can read objects from the “Production” bucket but can’t write objects in the “Dev” bucket, whereas user Bob can have full access to S3).

S3 bucket policies, on the other hand, are resource-based policies that you can use to grant access permissions to your Amazon S3 buckets and the objects in them. S3 bucket policies can allow or deny requests based on the elements in the policy. (For example, allow user Alice to PUT but not DELETE objects in the bucket.)

Note: You attach S3 bucket policies at the bucket level (that is, you can’t attach a bucket policy to an S3 object), but the permissions specified in the bucket policy apply to all of the objects in the bucket. You can also specify permissions at the object level by putting an object as the resource in the bucket policy.

IAM policies and S3 bucket policies are both used for access control and they’re both written in JSON using the AWS access policy language. Let’s look at an example policy of each type.

Sample S3 bucket policy

This S3 bucket policy enables any IAM principal (user or role) in account 111122223333 to use the Amazon S3 GET Bucket (ListObjects) operation.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::111122223333:root"]
      },
      "Action": "s3:ListBucket",
      "Resource": ["arn:aws:s3:::my_bucket"]
    }
  ]
}

This S3 bucket policy enables the IAM role Role-name under account 111122223333 to use the Amazon S3 GET Bucket (ListObjects) operation.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/Role-name"
      },
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::my_bucket"
    }
  ]
}

Sample IAM policy

The following IAM policy grants the IAM principal it is attached to permission to perform S3 operations on the contents of the bucket named my_bucket.

{
  "Version": "2012-10-17",
  "Statement":[{
    "Effect": "Allow",
    "Action": "s3:*",
    "Resource": ["arn:aws:s3:::my_bucket/*"]
    }
  ]
}

Note that the S3 bucket policy includes a Principal element, which lists the principals that bucket policy controls access for. The Principal element is unnecessary in an IAM policy because the principal is by default the entity to which the IAM policy attaches.

S3 bucket policies (as the name would imply) only control access to S3 resources for the bucket they’re attached to, whereas IAM policies can specify nearly any AWS action. One of the neat things about AWS is that you can actually apply both IAM policies and S3 bucket policies simultaneously, with the ultimate authorization being the least-privilege union of all the permissions (more on this in the section below titled How does authorization work with multiple access control mechanisms?).

When to use IAM policies vs. S3 policies

Use IAM policies if:

  • You need to control access to AWS services other than S3. IAM policies will be simpler to manage since you can centrally manage your permissions in IAM, instead of spreading them between IAM and S3.
  • You have numerous S3 buckets, each with different permissions requirements. IAM policies will be simpler to manage since you don’t have to define a large number of S3 bucket policies and can instead rely on fewer, more detailed IAM policies.
  • You prefer to keep access control policies in the IAM environment.

Use S3 bucket policies if:

  • You want a simple way to grant cross-account access to your S3 environment, without using IAM roles.
  • Your IAM policies bump up against the size limit (up to 2 KB for users, 5 KB for groups, and 10 KB for roles). S3 supports bucket policies of up to 20 KB.
  • You prefer to keep access control policies in the S3 environment.
  • You want to apply common security controls to the principals who interact with S3 buckets, such as restricting the IP addresses or VPC a bucket can be accessed from.

    If you’re still unsure of which to use, consider which audit question is most important to you:

  • If you’re more interested in “What can this user do in AWS?”, then IAM policies are probably the way to go. You can answer this question by looking up an IAM user and then examining their IAM policies to see what rights they have.
  • If you’re more interested in “Who can access this S3 bucket?”, then S3 bucket policies will likely suit you better. You can answer this question by looking up a bucket and examining the bucket policy.

Whichever method you choose, we recommend staying as consistent as possible. Auditing permissions becomes more challenging as the number of IAM policies and S3 bucket policies grows.

What about S3 ACLs?

An S3 ACL is a sub-resource that’s attached to every S3 bucket and object. It defines which AWS accounts or groups are granted access and the type of access. You can attach S3 ACLs to both buckets and individual objects within a bucket to manage permissions for those objects. As a general rule, AWS recommends that you use S3 bucket policies or IAM policies for access control. S3 ACLs are a legacy access control mechanism that predates IAM. By default, object ownership is set to the bucket owner enforced setting, and all ACLs are disabled, as can be seen in Figure 1.

Figure 1: Object Ownership

Figure 1: Object Ownership

A majority of modern use cases in Amazon S3 no longer require the use of ACLs, and we recommend that you keep ACLs disabled by applying the bucket owner enforced setting. This approach simplifies permissions management; you can use policies to more simply control access to every object in your bucket, regardless of who uploaded the objects in your bucket. When ACLs are disabled, the bucket owner owns the objects in the bucket and manages access to data exclusively by using access management policies.

S3 bucket policies and IAM policies define object-level permissions by providing those objects in the Resource element in your policy statements. The statement will apply to those objects in the bucket. Consolidating object-specific permissions into one policy (as opposed to multiple S3 ACLs) makes it simpler for you to determine effective permissions for your users and roles.

You can disable ACLs on both newly created and already existing buckets. For newly created buckets, ACLs are disabled by default. In the case of an existing bucket that already has objects in it, after you disable ACLs, the object and bucket ACLs are no longer part of an access evaluation, and access is granted or denied on the basis of policies.

S3 access points and S3 access

In some cases, customers have use cases with complex entitlement: Amazon S3 is used to store shared datasets where data is aggregated and accessed by different applications, individuals, or teams for different use cases. Managing access to this shared bucket requires a single bucket policy that controls access for dozens to hundreds of applications with different permission levels. As an application set grows, the bucket policy becomes more complex, time-consuming to manage, and needs to be audited to make sure that changes don’t have an unexpected impact on another application.

These customers may need additional policy space for access to their data and buckets. To support these use cases, Amazon S3 provides a feature called Amazon S3 access points. S3 access points simplify data access for AWS services or customer applications that store data in S3.

Access points are named network endpoints that are attached to buckets. You can use these access points to perform S3 object operations, such as GetObject and PutObject. Each access point has distinct permissions and network controls that S3 applies for requests that are made through that access point. Each access point enforces a customized access point policy that works in conjunction with the bucket policy that is attached to the underlying bucket.

S3 access points support IAM resource policies that allow you to control the use of the access point by resource, user, or other conditions. For an application or user to be able to access objects through an access point, both the access point and the underlying bucket must permit the request.

Note that adding an S3 access point to a bucket doesn’t change the bucket’s behavior when the bucket is accessed directly through the bucket’s name or Amazon Resource Name (ARN). All existing operations against the bucket will continue to work as before. Restrictions that you include in an access point policy apply only to requests made through that access point.

Sample access point policy

The following access point policy grants the IAM user Alice permissions to GET and PUT objects through the access point my-access-point in account 111122223333.

{
  “Version”: “2012-10-17”,
  “Statement”:[{
    “Effect”: “Allow”,
    “Principal”: { “AWS”: “arn:aws:iam::111122223333:user/Alice” },
    “Action”: [“s3:GetObject”, “s3:PutObject”],
    “Resource”: “arn:aws:s3:us-west-2:111122223333:accesspoint/my-access-point/object/*”
    }
  ]
}

Blocking public access for accounts and buckets

You can grant public access to buckets and objects through ACLs, bucket policies, or access point policies. In order to block public access to a bucket and its objects, you can turn on Block all public on either the bucket level or the account level.

The Amazon S3 Block Public Access feature provides settings for access points, buckets, and accounts to help you manage public access to S3 resources. By default, new buckets, access points, and objects don’t allow public access. However, users can modify bucket policies, access point policies, or object permissions to allow public access. S3 Block Public Access settings override these policies and permissions so that you can limit public access to these resources.

With S3 Block Public Access, account administrators and bucket owners can set up centralized controls to limit public access to their S3 resources. The S3 Block Public Access enforces these centralized controls regardless of how the S3 resources are created.

If you apply a setting to an account, it applies to the buckets and access points that are owned by that account. Similarly, if you apply a setting to a bucket, it applies to the access points associated with that bucket.

Block public access for buckets

The Block all public access setting is on by default at account creation, as you can see in Figure 2 (using the S3 console). Amazon S3 Block Public Access (bucket settings) settings apply only to this bucket and its access points. AWS recommends that you turn on Block all public access, but before you apply any of these settings, you should make sure that your applications will work correctly without public access. If you require some level of public access to this bucket or the objects within, you can customize the individual settings shown in Figure 2 to suit your specific storage use cases.

You can use the S3 console, AWS CLI, AWS SDKs, and the REST API to grant public access to one or more buckets.

Figure 2:Block Public Access Settings for Bucket

Figure 2:Block Public Access Settings for Bucket

Turning off this setting will create a warning in the account, as shown in Figure 3, because AWS recommends this setting to be turned on unless public access is required for specific and verified use cases, such as static website hosting.

Figure 3: Warning

Figure 3: Warning

You can also turn on this setting for existing buckets, as follows.

To turn on Block public access settings for existing buckets

  1. In the AWS Management Console, open the Amazon S3 console.
  2. Choose the name of the bucket, and then choose the Permissions tab.
  3. Choose Edit to change the public access settings for the bucket.

Block public access for accounts

To block public access to your S3 buckets and objects, turn on Block all public access for the account. This setting applies account-wide for current and future buckets and access points. AWS recommends that you turn on Block all public access, but before you apply any of these settings, you should make sure that your applications will work correctly without public access. If you require some level of public access to your buckets or objects, you can customize the individual settings shown in Figure 4 to suit your specific storage use cases.

You can use the S3 console, AWS CLI, AWS SDKs, and REST API to configure S3 Block Public Access settings for the buckets in your account. This setting can be turned on in the AWS Management Console as follows.

To turn on Block public access settings for an account

  1. Open the Amazon S3 console.
  2. In the left navigation pane, choose Block Public Access setting for this account.
  3. Choose Edit to change the public access settings for the bucket.
    Figure 4: Block Public Access Settings for Account

    Figure 4: Block Public Access Settings for Account

When you work with AWS Organizations, you can prevent people from modifying the S3 Block Public Access settings on the account level by adding a service control policy (SCP) that denies permission to edit these settings. An example of such an SCP is shown following.

{
  “Version”: “2012-10-17”,
  “Statement”:[{
    “Sid”: “DenyTurningOffBlockPublicAccessForThisAccount”,
    “Effect”: “Deny”,
    “Action”: “s3:PutAccountPublicAccessBlock”,
    “Resource”: “arn:aws:s3:::*”
    }
  ]
}

How does authorization work with multiple access control mechanisms?

Whenever an AWS principal issues a request to S3, the authorization decision depends on the union of all the IAM policies, S3 bucket policies, and S3 ACLs that apply, as well as on whether S3 Block Public Access is enabled on the account, bucket, or access point.

In accordance with the principle of least privilege, decisions default to DENY and an explicit DENY always trumps an ALLOW. For example, if an IAM policy grants access to an object, the S3 bucket policies deny access to that object, and there is no S3 ACL, then access will be denied. Similarly, if no method specifies an ALLOW, then the request will be denied by default. Only if no method specifies a DENY and one or more methods specify an ALLOW will the request be allowed.

When Amazon S3 receives a request to access a bucket or an object, it determines whether the bucket or the bucket owner’s account has an S3 Block Public Access setting applied. If the request was made through an access point, Amazon S3 also checks for S3 Block Public Access settings for the access point. If there is an existing S3 Block Public Access setting that prohibits the requested access, Amazon S3 rejects the request.

Figure 5 illustrates the authorization process.

Figure 5: Authorization Process

Figure 5: Authorization Process

We hope that this post clarifies some of your questions regarding the various ways you can control access to your S3 environment.

Use IAM Access Analyzer for S3 to review bucket access

Another interesting feature that you can use is IAM Access Analyzer for S3 to review bucket access. You can use IAM Access Analyzer for S3 to review buckets with bucket ACLs, bucket policies, or access point policies that grant public access. IAM Access Analyzer for S3 alerts you to buckets that are configured to allow access to anyone on the internet or other AWS accounts, including AWS accounts outside of your organization. For each public or shared bucket, you receive findings that report the source and level of public or shared access.

In IAM Access Analyzer for S3, you can block all public access to a bucket with a single click. You can also drill down into bucket-level permission settings to configure granular levels of access. For specific and verified use cases that require public or shared access, you can acknowledge and record your intent for the bucket to remain public or shared by archiving the findings for the bucket.

Additional resources

If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, contact AWS Support.

Want more AWS Security news? Follow us on Twitter.

Laura Verghote

Laura Verghote

Laura is a Territory Solutions Architect for Public Sector customers in the Benelux. She works together with customers to design and build solutions in the AWS cloud. She joined AWS as a technical trainer through a graduate program and has wide experience delivering training content to developers, administrators, architects, and partners in EMEA.

Gautam Kumar

Gautam Kumar

Gautam is a Solution Architect at AWS. Gautam helps various Enterprise customers to design and architect innovative solutions on AWS and specifically passionate about building secure workloads on AWS. Outside work, he enjoys traveling and spending time with family.