Managing access control in Amazon S3 continues to be a challenge for many companies. With the constant press surrounding organizations unintentionally exposing their objects in S3, It is important to highlight the fundamental access controls provided by AWS to correctly define access to your S3 buckets and the objects it stores. In this blog, we will discuss the differences between S3 ACLs, S3 bucket policies, and user-based policies as well as the order of precedence when a combination is used.
Misconfigured ACLs are a big part of why S3 has become such a hot target for malicious actors. There are two types of ACLs available when leveraging S3: Bucket and Object. Bucket ACLs allow you to control access at a bucket level, while Object ACLs allow you to control access at the object level. Below is an example of S3 ACLs in the AWS user interface.
Before AWS Identity and Access Management (IAM) gained popularity, S3 bucket and object ACLs were the only way to control access to a bucket. Today, there are still a few reasons to use ACLs. For example, you could use S3 object ACLs if you need to manage permissions on individual objects within a bucket. That said, you should not be leveraging ACLs for access to S3 resources unless you have a specific need because there are newer and cleaner methods, which we will discuss in the next sections.
Bucket policies allow users to easily grant cross-account access without having to create roles using the “Principal” IAM element. To see this in action, let's assume we want to allow s3:GetObject on foobucket to the root account 6161616161 as well as the user jason under that account. This could be implemented with the bucket policy below:
While bucket policies are a powerful and easy way to control access to your buckets, it is critical to understand how to purposefully define the Principal IAM element we have introduced in the above example. This is important because bucket policies control access to the entire S3 resource, and if you misuse a wildcard (*) when defining the Principal section of your bucket policy you could mistakenly make your bucket publicly accessible as seen in the example below:
User-based policies are frequently used to control access within the AWS ecosystem. For example, to grant a user or role access to specific S3 buckets, one can easily define a user based policy and attach it to the proper entity. For example, the user based policy below allows whatever entity that has the policy attached, to perform any action on foobucket. As a security best practice, we would take a least privilege approach and limit the actions that the user or role can perform to only what is necessary to get the job done.
Now that we have covered the fundamental ways of controlling access to S3 resources, let's look at how access control decisions are made when you make a request to S3 while leveraging ACLs, bucket policies, and user-based policies.
Staying true to the ideology of least privilege, access is only granted if no explicit deny exists and an explicit allow exists. Simply put, if you do not have any allows present you will not be granted access. And an explicit deny always beats an explicit allow.
When considering how you are implementing your organization's access controls in Amazon S3, keep in mind that it is important to constantly monitor interactions with your S3 buckets as well as any events that occur, including changes made to policies and ACLs as well as “who” made them.
The shared responsibility model dictates that managing access control configurations to Amazon S3 resources fall under the responsibility of the organization. RedLock can help you govern your S3 access controls and much more. To learn how to secure your organization’s public cloud environment: