S3 Object Lock for Data Protection
Implement S3 Object Lock for WORM storage to meet compliance requirements and protect against accidental or malicious deletion.
S3 Object Lock provides WORM (Write Once Read Many) protection for objects, essential for regulatory compliance and ransomware protection.
Object Lock Modes
Governance Mode
Allows users with special permissions to delete or modify:
import boto3
s3 = boto3.client('s3')
def upload_with_governance_lock(bucket, key, body, retention_days):
from datetime import datetime, timedelta
retain_until = datetime.now() + timedelta(days=retention_days)
s3.put_object(
Bucket=bucket,
Key=key,
Body=body,
ObjectLockMode='GOVERNANCE',
ObjectLockRetainUntilDate=retain_until
)
Compliance Mode
No one can delete or modify, not even root:
def upload_with_compliance_lock(bucket, key, body, retention_days):
from datetime import datetime, timedelta
retain_until = datetime.now() + timedelta(days=retention_days)
s3.put_object(
Bucket=bucket,
Key=key,
Body=body,
ObjectLockMode='COMPLIANCE',
ObjectLockRetainUntilDate=retain_until
)
Bucket Configuration
Enable Object Lock
ComplianceBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: compliance-data-bucket
ObjectLockEnabled: true
ObjectLockConfiguration:
ObjectLockEnabled: Enabled
Rule:
DefaultRetention:
Mode: COMPLIANCE
Years: 7
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Terraform Configuration
resource "aws_s3_bucket" "compliance" {
bucket = "compliance-data-bucket"
object_lock_enabled = true
}
resource "aws_s3_bucket_object_lock_configuration" "compliance" {
bucket = aws_s3_bucket.compliance.id
rule {
default_retention {
mode = "COMPLIANCE"
years = 7
}
}
}
resource "aws_s3_bucket_versioning" "compliance" {
bucket = aws_s3_bucket.compliance.id
versioning_configuration {
status = "Enabled"
}
}
Legal Holds
Apply Legal Hold
def apply_legal_hold(bucket, key, version_id=None):
params = {
'Bucket': bucket,
'Key': key,
'LegalHold': {'Status': 'ON'}
}
if version_id:
params['VersionId'] = version_id
s3.put_object_legal_hold(**params)
print(f"Legal hold applied to {key}")
def remove_legal_hold(bucket, key, version_id=None):
params = {
'Bucket': bucket,
'Key': key,
'LegalHold': {'Status': 'OFF'}
}
if version_id:
params['VersionId'] = version_id
s3.put_object_legal_hold(**params)
Bulk Legal Hold
def apply_legal_hold_prefix(bucket, prefix):
paginator = s3.get_paginator('list_object_versions')
for page in paginator.paginate(Bucket=bucket, Prefix=prefix):
for version in page.get('Versions', []):
apply_legal_hold(
bucket,
version['Key'],
version['VersionId']
)
Compliance Validation
Check Object Lock Status
def get_object_lock_status(bucket, key, version_id=None):
params = {'Bucket': bucket, 'Key': key}
if version_id:
params['VersionId'] = version_id
# Get retention
try:
retention = s3.get_object_retention(**params)
retention_info = {
'mode': retention['Retention']['Mode'],
'until': retention['Retention']['RetainUntilDate']
}
except s3.exceptions.ClientError:
retention_info = None
# Get legal hold
try:
legal_hold = s3.get_object_legal_hold(**params)
legal_hold_status = legal_hold['LegalHold']['Status']
except s3.exceptions.ClientError:
legal_hold_status = None
return {
'retention': retention_info,
'legal_hold': legal_hold_status
}
Audit Compliance
def audit_bucket_compliance(bucket):
results = {
'total_objects': 0,
'locked_objects': 0,
'legal_holds': 0,
'non_compliant': []
}
paginator = s3.get_paginator('list_object_versions')
for page in paginator.paginate(Bucket=bucket):
for version in page.get('Versions', []):
results['total_objects'] += 1
status = get_object_lock_status(
bucket,
version['Key'],
version['VersionId']
)
if status['retention']:
results['locked_objects'] += 1
else:
results['non_compliant'].append(version['Key'])
if status['legal_hold'] == 'ON':
results['legal_holds'] += 1
return results
Bypass Governance Mode
Users with s3:BypassGovernanceRetention permission:
def delete_governance_locked_object(bucket, key, version_id):
s3.delete_object(
Bucket=bucket,
Key=key,
VersionId=version_id,
BypassGovernanceRetention=True
)
IAM Policy for Bypass
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGovernanceBypass",
"Effect": "Allow",
"Action": [
"s3:BypassGovernanceRetention"
],
"Resource": "arn:aws:s3:::compliance-bucket/*"
}
]
}
Working with Warqline
We are a cloud engineering consultancy and an official AWS and Google Cloud partner. If you are running this in production and want a second pair of eyes, we scope work in a free 45-minute technical call: you describe what you are running and what worries you, and we tell you what we would look at first.
Conclusion
S3 Object Lock provides essential data protection for compliance and ransomware defense. Use Compliance mode for regulatory requirements and Governance mode for flexible protection with administrative override capabilities.