Skip to content

S3 buckets should not be accessible to all authenticated users

The AuthenticatedUsers grantee (URI http://acs.amazonaws.com/groups/global/AuthenticatedUsers) does not mean "users in my account." It means every identity that authenticates to any AWS account worldwide. Granting READ to this group can expose object listings or object contents to AWS-authenticated principals across accounts. Granting WRITE lets anyone deposit objects you will pay to store.

Misunderstanding this group is one of the most common S3 data exposure vectors. Multiple public breaches trace back to developers assuming AuthenticatedUsers meant their own organization.

Retrofit consideration

Existing buckets may have legacy ACLs applied via the console or older Terraform configurations using the deprecated acl argument on aws_s3_bucket. Revoking AuthenticatedUsers grants can break workflows that unknowingly depend on cross-account public-auth access patterns.

Implementation

Choose the approach that matches how you manage Terraform.

If you use terraform-aws-modules/s3-bucket/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.

module "s3_bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = ">=5.0.0"

  bucket = "abc123"

  object_ownership = "BucketOwnerEnforced"
}

Use AWS provider resources directly. See docs for the resources involved: aws_s3_bucket_ownership_controls.

resource "aws_s3_bucket" "this" {
  bucket        = "pofix-abc123"
  force_destroy = true
}

resource "aws_s3_bucket_ownership_controls" "this" {
  bucket = "example-bucket-abc123"
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

What this control checks

The control checks ACL configuration on aws_s3_bucket_acl resources. To pass, no grant block within access_control_policy may reference a grantee with uri set to http://acs.amazonaws.com/groups/global/AuthenticatedUsers. This covers all permission types: READ, WRITE, READ_ACP, WRITE_ACP, and FULL_CONTROL.

The acl argument on aws_s3_bucket_acl must also not be set to "authenticated-read", a canned ACL that grants AuthenticatedUsers READ access.

Setting "BucketOwnerEnforced" as the object_ownership value in aws_s3_bucket_ownership_controls disables ACLs entirely and makes the bucket owner the automatic owner of every object. With ACLs disabled, this control passes by default because no ACL grants can exist.

Common pitfalls

  • Canned ACL authenticated-read applied silently

    Setting acl = "authenticated-read" on aws_s3_bucket_acl (or the deprecated acl argument on aws_s3_bucket) grants READ to the AuthenticatedUsers group. The word "authenticated" misleads teams into thinking it restricts access to their account. It does not.

  • Legacy inline acl argument on aws_s3_bucket

    When migrating from the deprecated acl argument on aws_s3_bucket to a separate aws_s3_bucket_acl resource, the old ACL grants can persist in AWS if the migration does not explicitly remove them. Terraform may show no diff while the actual bucket state still carries the grant. Run aws s3api get-bucket-acl --bucket <name> to confirm what AWS actually has.

  • Object-level ACLs still granting AuthenticatedUsers

    This control checks bucket-level ACLs only. Individual objects can carry their own ACLs granting AuthenticatedUsers access via aws s3api put-object-acl, and those won't show up here. Enable BucketOwnerEnforced on aws_s3_bucket_ownership_controls to disable all object ACLs and close that gap.

  • Cross-account tooling relying on AuthenticatedUsers

    Some legacy cross-account workflows or third-party integrations depend on AuthenticatedUsers grants, often without the owning team realizing it. Removing the grant will break them. Replace with explicit bucket policies using aws:PrincipalAccount or aws:PrincipalOrgID conditions so cross-account access is controlled and auditable.

Audit evidence

Auditors expect Config rule results (such as s3-bucket-public-read-prohibited, s3-bucket-public-write-prohibited, or a custom rule) showing compliant evaluations for all S3 buckets. Console evidence includes the bucket Permissions tab confirming "ACLs disabled" under Object Ownership, or the Access Control List section showing no grants to the "Authenticated Users group." The most direct evidence is aws s3api get-bucket-acl output for each bucket showing no Grantee with URI http://acs.amazonaws.com/groups/global/AuthenticatedUsers.

CloudTrail logs for PutBucketAcl events confirm that no ACL changes have reintroduced AuthenticatedUsers grants after remediation.

Framework-specific interpretation

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: s3_bucket_not_accessible_to_all_authenticated_user

  • AWS Config Managed Rule: S3_BUCKET_ACL_PROHIBITED

  • Checkov Check: CKV2_AWS_43

  • Powerpipe Control: aws_compliance.control.s3_bucket_not_accessible_to_all_authenticated_user

  • Prowler Checks: s3_bucket_public_access, s3_bucket_public_write_acl

  • KICS Query: 57b9893d-33b1-4419-bcea-a717ea87e139

Last reviewed: 2026-03-09