S3 buckets should have object lock enabled
Object Lock protects critical data from accidental or malicious deletion. Without it, any principal with s3:DeleteObject permissions can permanently remove objects, and even versioned buckets remain vulnerable to delete-marker floods or version-level purges. Ransomware operators routinely target backup buckets by deleting all object versions before demanding payment.
Enabling Object Lock at the bucket level establishes a baseline immutability guarantee. In governance mode, only users with s3:BypassGovernanceRetention can override retention. In compliance mode, nobody can delete protected objects, including the root account. This distinction matters when designing retention policies for regulated workloads.
Retrofit consideration
AWS now supports enabling Object Lock on existing buckets via the PutObjectLockConfiguration API, but the bucket must already have versioning enabled. The object_lock_enabled argument on aws_s3_bucket is a create-time-only setting in many provider versions, so Terraform may require an import workflow or a manual API call for pre-existing buckets. Test thoroughly in non-production before touching anything with live data.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "s3_bucket" {
source = "soc2.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "pcidss.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "hipaa.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "nistcsf.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "fedrampmoderate.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "nist800171.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "nydfs23.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "ffiec.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "cfrpart11.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "rbiitfnbfc.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "hipaasecurity2003.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
module "s3_bucket" {
source = "nist80053rev4.compliance.tf/terraform-aws-modules/s3-bucket/aws"
version = ">=5.0.0"
bucket = "abc123"
}
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_lock_enabled = true
}
Use AWS provider resources directly. See docs for the resources involved: aws_s3_bucket.
resource "aws_s3_bucket" "this" {
bucket = "pofix-abc123"
force_destroy = true
object_lock_enabled = true
}
What this control checks
This control checks that S3 buckets are created with Object Lock enabled. The aws_s3_bucket resource must have object_lock_enabled set to true. Because Object Lock requires versioning, the bucket must also have versioning enabled via a separate aws_s3_bucket_versioning resource with versioning_configuration status set to "Enabled". A default retention policy can then be configured using aws_s3_bucket_object_lock_configuration, specifying rule.default_retention with a mode of "GOVERNANCE" or "COMPLIANCE" and a days or years value.
The control passes when object_lock_enabled is true. It fails when the argument is absent, set to false, or the bucket was created without Object Lock support.
Common pitfalls
Object Lock is immutable at creation in older provider versions
In many Terraform AWS provider versions,
object_lock_enabledonaws_s3_bucketis a ForceNew argument. Changing it fromfalsetotruedestroys and recreates the bucket, which deletes all existing objects. Always check provider release notes before planning this change, and consider usingaws s3api put-object-lock-configurationfor existing buckets before importing state.Versioning must be enabled first
The API call fails if versioning isn't already enabled when Object Lock is configured. Create the
aws_s3_bucket_versioningresource with status"Enabled"before or alongsideobject_lock_enabled = true, and add an explicitdepends_onif Terraform's implicit dependency ordering isn't guaranteed. The plan won't always warn you when this is missing.Compliance mode retention cannot be shortened
Setting
modeto"COMPLIANCE"inaws_s3_bucket_object_lock_configurationmeans no one, including the root user, can delete protected objects or shorten the retention period before it expires. Get this wrong with a long retention window and you're waiting it out. Use"GOVERNANCE"mode during testing and only promote to"COMPLIANCE"once the period is validated.Object Lock does not retroactively protect existing objects
Enabling Object Lock and configuring a default retention policy only applies to objects uploaded after the policy is in place. Existing objects in the bucket are not automatically protected. Apply retention settings per-object using
aws s3api put-object-retention, or re-upload objects so they inherit the default.Lifecycle rules interact with retention
S3 lifecycle expiration rules cannot delete objects still under Object Lock retention. The lifecycle action silently fails for locked objects, which can produce unexpected storage costs if you assumed lifecycle would prune old data. Audit lifecycle rule interactions before setting long retention periods.
Audit evidence
Auditors expect AWS Config evaluation results showing compliant status across all in-scope buckets. Console evidence should show Object Lock as "Enabled" under the bucket's Properties tab, along with the configured default retention mode and period. CloudTrail logs for PutObjectLockConfiguration and CreateBucket provide a timeline of when Object Lock was enabled and by whom.
For continuous assurance, Security Hub evaluations or a third-party CSPM showing periodic scan results with passing evaluations rounds out the evidence package.
Framework-specific interpretation
SOC 2: Availability and Processing Integrity both ask whether unauthorized deletion or alteration of retained data is technically prevented. For S3 storage, Object Lock gives you a direct technical control that addresses both criteria.
PCI DSS v4.0: Requirement 3 covers protection of stored account data; Requirement 10 covers log integrity. For cardholder data or audit logs living in S3, Object Lock helps preserve that data against unauthorized deletion, which is what examiners look for under both requirements.
HIPAA Omnibus Rule 2013: 45 CFR 164.312(c)(1) requires integrity controls that guard ePHI against improper alteration or destruction. Object Lock in compliance mode helps ensure that ePHI stored in S3 cannot be removed or overwritten during the required retention window, addressing the technical safeguard specification directly.
NIST Cybersecurity Framework v2.0: PR.DS covers data protection at rest; RC.RP covers recovery planning and data availability. Object Lock contributes to both: it closes the credential-compromise path to wiping stored data, and it gives recovery procedures something reliable to work from when restoring from S3-backed backups.
FedRAMP Moderate Baseline Rev 4: SI-12 and CP-9 cover information retention and backup protection at the Moderate baseline. Object Lock provides one mechanism for the tamper-resistant storage both controls expect, particularly for backup and archival data where integrity must be demonstrable to assessors.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
s3_bucket_object_lock_enabledAWS Config Managed Rule:
S3_BUCKET_DEFAULT_LOCK_ENABLEDCheckov Check:
CKV_AWS_143Powerpipe Control:
aws_compliance.control.s3_bucket_object_lock_enabledProwler Check:
s3_bucket_object_lockAWS Security Hub Control:
S3.15
Last reviewed: 2026-03-09