Mastodon

Understand S3 ACL

Recently you were able to read. about S3 security, and methods of avoiding common misconfiguration with the usage of standard and well-known tools.

The fact that AWS offers a set of access control mechanisms designed to protect S3 resources, including:

  • Access Control Lists (ACLs)
  • Identity and Access Management (IAM) policies
  • S3 Access Points
  • Multi-Region Access Points
  • signed URL

This article provides a comprehensive guide to understanding and implementing these mechanisms, highlighting potential misconfigurations that can lead to security vulnerabilities and offer practical guidance on using Terraform for building our secure infrastructure-as-code deployments.

Today we will cover ACLs, as IMO it will be easier to read and understand.

S3 Access Control Lists - General

Access Control Lists (ACLs) represent one of the original methods for managing access to S3 buckets and objects. They function by attaching a list of access permissions to each bucket and object, specifying which AWS accounts or pre-defined groups are granted what type of access. At the bucket level, ACLs can control permissions like the ability to list objects or manage the bucket's ACL itself. Object ACLs, on the other hand, govern actions such as reading or writing data to individual objects. AWS provides a set of pre-defined, or "Canned" ACLs, such as private, public-read, or bucket-owner-full-control, which offer common permission sets.

While ACLs provide a means to control access at a granular level, particularly for individual objects, they are now considered a legacy mechanism for most modern use cases. Managing ACLs across a large number of objects can become just very complex and challenging to audit effectively. The current best practice leans towards using IAM policies for more centralized and scalable access management.

Securing S3 with Access Control Lists

While generally not recommended for most modern scenarios, Understanding Access Control Lists is still valuable, particularly when encountering legacy systems or specific edge cases.

Understanding Bucket and Object ACLs

Permissions within S3 ACLs can be set at both the bucket and the object level. Bucket ACLs describe operations that are linked to the bucket as a whole, such as listing the objects within it or modifying the bucket's properties, including its ACL. Object ACLs, on the other hand, control access to individual objects stored in the bucket, determining who can read the object data or its metadata.

Access via ACLs is granted to grantees, which can be:

  • specific AWS accounts identified by their canonical user ID
  • predefined groups like "Everyone" (representing anonymous public access) or "Authenticated Users" (anyone with valid AWS credentials).

The permissions that can be granted include READ, WRITE, and FULL_CONTROL, and others. For convenience, AWS offers "canned ACLs," which are predefined sets of permissions that can be easily applied to buckets and objects. For instance, the private canned ACL grants the bucket and object owner full control, with no access to others. The public-read canned ACL grants the owner full control and allows anyone on the internet to read objects.

While ACLs offer the advantage of object-level granularity, which can be useful in specific situations requiring unique permissions for individual files managing these permissions across a large and dynamic The S3 environment can become operationally chaotic. Moreover, when object ownership is different from bucket ownership, managing access through ACLs can introduce even more mess.

Use Cases and Inherent Limitations of ACLs

In modern AWS environments, the use cases for ACLs are slowly limited. AWS itself recommends disabling ACLs for the majority of new applications. However, there are still some specific scenarios where ACLs might be considered.

One such case is granting write access for S3 server access logs to the AWS Log Delivery group or allowing Amazon CloudFront to access objects in a bucket using the bucket-owner-read canned ACL.

Despite these limited use cases, ACLs have several limitations compared to IAM policies. They lack the centralized management and auditing capabilities offered by IAM, where policies can be applied across multiple services and managed from a single place. Managing cross-account access with ACLs can also be less straightforward than, using bucket policies or IAM roles, which provide more explicit and manageable mechanisms for granting permissions to entities in other AWS accounts. The prevailing trend in AWS security is to favor policy-based access control due to its greater flexibility, enhanced auditing, and centralized management, aligning more effectively with modern cloud security best practices.

Common Pitfalls and Misconfigurations with ACLs

Misconfigurations involving ACLs are a significant source of security breaches in S3. A common pitfall is the accidental granting of public read or write access through ACLs, which can expose sensitive data to the internet or allow unauthorized modifications. This can occur through the direct application of canned ACLs like public-read or public-read-write, when they are not intended, or through the manual addition of permissions to the Everyone or Authenticated Users groups.

Another challenge arises from the potential for inconsistent application of ACLs across many objects within a bucket. This lack of consistency can make it difficult to understand the overall access posture of the bucket and increase the risk of making them public or overly permissive objects. Furthermore, the management of ACLs becomes more intricate when the ownership of objects differs from the ownership of the bucket, potentially leading to unexpected access behaviors. These potential misconfigurations underscore the importance of careful consideration and a preference for the more controlled and auditable approach of policy-based access management.

Implementing S3 ACLs with Terraform: Examples and Considerations

While the recommendation is generally to disable ACLs, Terraform provides, the aws_s3_bucket_acl resource to manage bucket ACLs when necessary. This resource allows setting canned ACLs using the ACL argument.

So how does it work? Below snipped will set the bucket to private (only the bucket owner and object owner have access), with enabled ACL (BucketOwnerPreferred or ObjectWriter) as ownership.

 1resource "aws_s3_bucket" "example" {
 2  bucket = "my-tf-example-bucket"
 3}
 4
 5resource "aws_s3_bucket_ownership_controls" "example" {
 6  bucket = aws_s3_bucket.example.id
 7  rule {
 8    object_ownership = "BucketOwnerPreferred"
 9  }
10}
11
12resource "aws_s3_bucket_acl" "example" {
13  depends_on = [aws_s3_bucket_ownership_controls.example]
14
15  bucket = aws_s3_bucket.example.id
16  acl    = "bucket-owner-full-control"
17}

Let's now split it into smaller parts, and start from object_ownership:

  • object_ownership - (Required) Object ownership. Valid values: BucketOwnerPreferred, ObjectWriter, or BucketOwnerEnforced
    • BucketOwnerPreferred - The bucket owner owns and has full control over new objects that other accounts write to the bucket with the bucket-owner-full-control canned ACL.
    • ObjectWriter - The AWS account that uploads an object owns the object, has full control over it and can grant other users access to it through ACLs.
    • BucketOwnerEnforced - ACLs are disabled, and the bucket owner automatically owns and has full control over every object in the bucket. ACLs no longer affect permissions to data in the S3 bucket. The bucket uses policies to define access control.

Then we have acl filed under aws_s3_bucket_acl, where AWS's documentation is much more descriptive. For example acl = "private" means:

Canned ACLApplies toPermissions added to ACL
bucket-owner-full-controlObjectBoth the object owner and the bucket owner get FULL_CONTROL over the object. If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.

Summary

Just disable ACL on your S3 bucket. It's not done via the Terraform module as you see. It seems very easy to use the BucketOwnerPreferred value, based on snipped from documentation. That is why understanding what we're doing is such important in cloud environments. Hopefully, you will find this article good enough, and useful, as I will continue this series. Even, if I'm officially a father of two! And I started experimenting with NixOS. Btw it works on my base setup, maybe I will describe it as well at some point.


  1. Canned ACL
  2. ACL Overview
  3. AWS Security Best Practices
  4. Terrafrom module