AWS Security Hub · S3
S3.13: Buckets have no lifecycle rules and grow forever
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub S3.13 check?
S3.13 checks that a bucket has at least one active lifecycle configuration rule. It reports FAILED when a bucket has no lifecycle rules at all, so objects accumulate indefinitely with no transition or expiry.
Why does S3.13 matter?
A bucket with no lifecycle rules grows forever: old versions, expired temp files and incomplete multipart uploads all bill at full price. One fintech audit found 47 TB of abandoned multipart fragments costing roughly $12,000, all of it invisible in the console. Beyond cost, retaining data past its useful life widens the blast radius of any future bucket exposure.
How do I fix S3.13?
- Audit each bucket's real access pattern and storage breakdown before writing rules.
- Apply a baseline lifecycle configuration covering AbortIncompleteMultipartUpload, noncurrent-version expiry, tiering of cold data, and expiry of temp prefixes.
- Consider Intelligent-Tiering for buckets with unpredictable access patterns.
- Verify the configuration is attached with get-bucket-lifecycle-configuration.
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.13 a false positive?
Plenty of buckets are supposed to retain everything indefinitely, so the absence of a lifecycle rule is the deliberate, correct state. A compliance/legal-hold archive, a Macie/Athena evidence store, or a CloudTrail/log-replication target that must keep objects for the full retention period intentionally ships with no transition or expiry rule, yet S3.13 only checks for the presence of any active Lifecycle configuration and reports FAILED. If you leave the default parameters empty, any lifecycle config makes it pass; where indefinite retention is genuinely required, attach a rule containing only AbortIncompleteMultipartUpload (which clears stale upload fragments without expiring objects) to pass cleanly, or document the requirement and suppress the finding rather than adding an expiration that would delete data you are obligated to keep.
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.10 Versioned buckets should have lifecycle configurations
- S3.11 Buckets should have event notifications enabled
- S3.12 ACLs should not be used to manage bucket access
- S3.15 Buckets should have Object Lock enabled
- S3.17 Buckets should be encrypted at rest with KMS keys