RCP should prevent S3 buckets from using ACLs

Description

A Resource Control Policy (RCP) should prevent S3 buckets from using ACLs. S3 ACLs are a legacy access control mechanism that can lead to unintended public or cross-account access. AWS recommends disabling ACLs by setting object ownership to BucketOwnerEnforced.

This rule verifies that an RCP meets at least one of the following criteria:

  • Denies both s3:PutBucketAcl and s3:PutObjectAcl (these can be in separate deny statements)
  • Denies s3:CreateBucket with a condition requiring s3:x-amz-object-ownership to be BucketOwnerEnforced
  • Uses a wildcard deny (s3:* or *)

Denying only s3:PutBucketAcl without s3:PutObjectAcl (or vice versa) is insufficient — an attacker could still set ACLs at the object level to grant external access to individual objects.

Note: All new S3 buckets created after April 2023 have ACLs disabled by default. This RCP ensures existing buckets cannot re-enable ACLs and new buckets maintain the secure default.

Remediation

Create a Resource Control Policy that explicitly prevents ACL usage using Action (not NotAction) on S3 buckets and attach it to the organization root. Remove any NotAction-based deny statements that exempt S3 actions. The RCP should deny s3:PutBucketAcl and s3:PutObjectAcl operations, or require s3:x-amz-object-ownership to be BucketOwnerEnforced for bucket creation. Refer to the Controlling ownership of objects and RCP syntax documentation for guidance.