IAM Policy to Deny Unencrypted S3 Uploads
Create an IAM policy that denies S3 PutObject requests unless server-side encryption is specified. Ensures all objects are encrypted at rest.
Detailed Explanation
Enforce Encryption on S3 Uploads
To ensure compliance with data protection requirements, this policy denies any S3 PutObject request that does not include server-side encryption. Objects uploaded without encryption headers are rejected.
Policy JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnencryptedUploads",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-secure-bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": [
"aws:kms",
"AES256"
]
}
}
},
{
"Sid": "DenyUploadWithoutEncryptionHeader",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-secure-bucket/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
Two Deny Statements
Two statements are needed because of how IAM condition evaluation works:
- Statement 1: Denies if the encryption header IS present but set to something other than
aws:kmsorAES256. - Statement 2: Denies if the encryption header is NOT present at all (
Nullcondition).
Together, they ensure that every upload must explicitly specify a supported encryption method.
Why Not Just Use Bucket Default Encryption?
S3 bucket default encryption is a good safety net, but it does not prevent unencrypted upload requests — it silently applies encryption. This IAM policy actively rejects non-compliant requests, which is important for:
- Audit trails that prove all uploads were intentionally encrypted
- Compliance frameworks that require explicit encryption headers
- Defense in depth — belt and suspenders approach
KMS-Only Variant
To enforce KMS encryption specifically (not AES256), remove "AES256" from the condition array.
Use Case
Organizations with data-at-rest encryption requirements (HIPAA, FedRAMP, PCI DSS) that need to ensure all S3 uploads use server-side encryption. Commonly used alongside bucket policies for defense in depth.