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.

Advanced Patterns

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:

  1. Statement 1: Denies if the encryption header IS present but set to something other than aws:kms or AES256.
  2. Statement 2: Denies if the encryption header is NOT present at all (Null condition).

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.

Try It — AWS IAM Policy Generator

Open full tool