S3 supports four encryption methods:
Server-Side Encryption (SSE)
- SSE-S3: AES-256 encryption, keys managed entirely by S3, enabled by default for new objects. Header:
x-amz-server-side-encryption: AES256
.
- SSE-KMS: Keys stored in AWS KMS, allows key usage auditing and granular permissions. Header:
x-amz-server-side-encryption: aws:kms
. Upload/download triggers KMS API calls (GenerateDataKey
,Decrypt
), counting toward KMS quotas.
- SSE-C: Keys fully managed by the customer. AWS never stores the key; must send key in headers for every request over HTTPS. Losing the key means losing the object.
Client-Side Encryption
- Encryption/decryption performed entirely on the client before/after transfer.
- Keys are fully customer-managed; AWS stores only encrypted data.
- AWS never has access to the key or plaintext.
Default Encryption vs. Bucket Policies
- Default encryption (e.g., SSE-S3 or SSE-KMS) automatically encrypts new objects in a bucket without requiring client-side configuration.
- Bucket policies can enforce encryption by denying
PUT
requests that lack specific encryption headers or algorithms.
- Policies are evaluated before default encryption settings, meaning noncompliant requests can be blocked outright.
Example – Force SSE-KMS:
- Deny
PUT
ifs3:x-amz-server-side-encryption
≠"aws:kms"
.
Example – Require encryption header:
- Deny
PUT
if no SSE-C algorithm header is provided.
Key point:
- Default encryption is passive (encrypts after acceptance), while bucket policy enforcement is proactive (rejects noncompliant uploads).
- When you use server-side encryption with Amazon S3 managed keys (SSE-S3), each object is encrypted with a unique key.
Additional Notes:
Amazon S3 Bucket Keys reduce the cost of Amazon S3 server-side encryption with AWS Key Management Service (AWS KMS) keys (SSE-KMS). Using a bucket-level key for SSE-KMS can reduce AWS KMS request costs by up to 99 percent by decreasing the request traffic from Amazon S3 to AWS KMS. Enabling S3 Bucket Keys with SSE-KMS allows S3 to generate a unique data key for each object locally using a bucket-level KMS key, which dramatically reduces the number of direct AWS KMS API calls. This approach maintains the same security and compliance properties as SSE-KMS, while reducing request-related costs—especially beneficial for workloads with frequent access or write operations.