AWS Security Hub · S3
S3.10: Versioned buckets should have lifecycle configurations
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub S3.10 check?
S3.10 checks that a bucket with versioning enabled also has a lifecycle configuration. It reports FAILED when versioning is on but no lifecycle rule manages noncurrent versions, so every overwrite or delete silently retains the old object forever.
Why does S3.10 matter?
Versioning turns into a runaway cost trap without lifecycle rules: noncurrent versions, delete markers and incomplete multipart uploads pile up invisibly because the console hides them by default. Beyond the bill, indefinitely retained versions enlarge the data exposed if the bucket is ever breached.
How do I fix S3.10?
- Surface the hidden noncurrent storage with list-object-versions or S3 Storage Lens.
- Write a lifecycle rule that expires or tiers noncurrent versions on a schedule, and add AbortIncompleteMultipartUpload.
- Apply it with put-bucket-lifecycle-configuration and verify it is attached.
Remediation script · bash
# Find versioned S3 buckets that have no lifecycle configuration.
for b in $(aws s3api list-buckets --query 'Buckets[].Name' --output text); do
ver=$(aws s3api get-bucket-versioning --bucket "$b" --query Status --output text 2>/dev/null)
if [ "$ver" = "Enabled" ] && ! aws s3api get-bucket-lifecycle-configuration --bucket "$b" >/dev/null 2>&1; then
echo "S3.10 FAIL: $b (versioned, no lifecycle)"
fi
done
# Apply an S3 lifecycle config that tiers and expires noncurrent versions and clears failed uploads.
aws s3api put-bucket-lifecycle-configuration \
--bucket ci-build-artifacts --lifecycle-configuration file://lifecycle.json
# Preview an ECR policy before applying it, then attach it.
aws ecr start-lifecycle-policy-preview \
--repository-name services/checkout-api --lifecycle-policy-text file://ecr-policy.json
aws ecr put-lifecycle-policy \
--repository-name services/checkout-api --lifecycle-policy-text file://ecr-policy.json Full walkthrough (console steps, edge cases and verification) in the lesson Configure lifecycle and versioning policies.
Is S3.10 a false positive?
Some versioned buckets are meant to keep every version forever, so a missing lifecycle rule is the correct state, not a gap. A WORM/compliance archive backed by Object Lock in COMPLIANCE mode, or a legal-hold bucket where noncurrent versions must be retained for the full statutory period, deliberately has no expiry rule, yet S3.10 only checks for the presence of any Lifecycle configuration and reports FAILED. Confirm the retention requirement is real, then suppress the finding rather than adding an expiration rule that would defeat the bucket's purpose; if you want the control to pass cleanly, attach a lifecycle config that contains only AbortIncompleteMultipartUpload (which satisfies the check without ever expiring object versions).
More S3 controls
- S3.1 Account-level S3 public access is not fully blocked
- S3.2 Public S3 buckets expose data to anyone on the internet
- S3.3 Buckets can be written to by anyone on the internet
- S3.5 S3 is accepting unencrypted HTTP requests
- S3.6 Bucket policy grants broad access to other AWS accounts
- S3.8 Buckets can still be made public; Block Public Access is off
- S3.9 No S3 access logs, so reads and writes go unaudited
- S3.11 Buckets should have event notifications enabled
- S3.12 ACLs should not be used to manage bucket access
- S3.13 Buckets have no lifecycle rules and grow forever
- S3.15 Buckets should have Object Lock enabled
- S3.17 Buckets should be encrypted at rest with KMS keys