S3 Encryption for SOC 2: Buckets, KMS, and Evidence
Configure S3 encryption for SOC 2 CC6.6. Covers SSE-S3 vs SSE-KMS, enforcing encryption in bucket policies, key management, and auditor evidence requirements.
- All S3 buckets containing sensitive or customer data must have server-side encryption enabled for CC6.6.
- SSE-KMS with a customer-managed KMS key provides stronger control and audit trail than SSE-S3.
- Bucket policies should deny PUT requests that don't specify encryption — enforcing encryption by default.
- Public access block must be enabled on all buckets not intentionally public.
- AWS Config rules provide automated, ongoing evidence of S3 encryption compliance.
In this guide
Why S3 Encryption Matters for SOC 2
S3 is the most commonly used storage service in AWS and a frequent location for sensitive data — customer documents, database backups, application logs, and evidence files. CC6.6 requires encryption of sensitive data at rest, which directly applies to S3 buckets holding such data.
S3 data exposure through misconfigured access controls is one of the most common causes of cloud data breaches. Encryption at rest ensures that even if an attacker gains access to the underlying storage media or if a bucket is briefly misconfigured to be publicly accessible, the data is still protected.
SSE-S3 vs SSE-KMS
SSE-S3 (Server-Side Encryption with S3-managed keys): S3 manages the encryption keys. Objects are encrypted using AES-256. No additional cost beyond API calls. Simplest to configure. Provides encryption at rest but limited key management audit trail.
SSE-KMS (Server-Side Encryption with AWS KMS keys): Uses AWS Key Management Service to manage encryption keys. Provides a detailed audit trail of key usage in CloudTrail (who decrypted what, when). Supports customer-managed keys (CMK) for fine-grained access control. Adds cost: $1/month per KMS key + $0.03 per 10,000 API calls.
For SOC 2, SSE-KMS with a customer-managed key is the preferred approach for buckets containing sensitive or customer data. It provides both encryption and the key usage audit trail that supports CC7.2 anomaly detection. Use SSE-S3 for non-sensitive data (build artifacts, public static files) to manage costs.
Enabling Default Encryption on Buckets
Enable default bucket encryption in S3 > Bucket > Properties > Default encryption. Select SSE-KMS, choose your KMS key (customer-managed for sensitive data, AWS managed key for lower-sensitivity data), and save.
Via AWS CLI: aws s3api put-bucket-encryption --bucket your-bucket --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"arn:aws:kms:region:account:key/key-id"},"BucketKeyEnabled":true}]}'.
Enable Bucket Key when using SSE-KMS to reduce KMS API call costs by generating a data key per-bucket rather than per-object. This reduces KMS costs by up to 99% for buckets with many objects.
Enforcing Encryption via Bucket Policy
Default bucket encryption applies to objects uploaded without encryption headers, but doesn't prevent a requester from explicitly specifying no encryption. Add a bucket policy condition to deny PutObject requests that don't use your required encryption: Condition: {"StringNotEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}}.
Also enforce TLS-in-transit with a bucket policy condition: Condition: {"Bool": {"aws:SecureTransport": "false"}} with Effect: Deny — this denies any request not made over HTTPS.
Combine both conditions in your bucket policy for comprehensive protection: deny unencrypted uploads and deny non-HTTPS access.
Blocking Public Access
Accidentally public S3 buckets are a leading cause of data breaches. Enable S3 Block Public Access at the account level (S3 > Block Public Access settings for this account) and at the bucket level. Block all four settings: BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets.
For buckets that legitimately serve public content (static websites, public documentation): document the business justification, whitelist them in an exception log, and ensure they contain no sensitive data.
AWS Config rule "s3-bucket-public-read-prohibited" and "s3-bucket-public-write-prohibited" automatically detect buckets violating the public access policy. Ensure these rules report compliant for all sensitive buckets.
S3 Evidence for SOC 2 Auditors
(1) S3 bucket inventory listing all buckets with encryption status and public access settings. (2) AWS Config findings for "s3-bucket-server-side-encryption-enabled" and "s3-bucket-public-read-prohibited" — all compliant. (3) Sample bucket encryption configuration screenshots for key buckets (production data, backups). (4) Bucket policies for key buckets showing encryption enforcement and TLS-only conditions. (5) KMS key policy screenshot for customer-managed keys. (6) Account-level S3 Block Public Access settings screenshot.
Frequently Asked Questions
Do all S3 buckets need encryption for SOC 2, or just those with customer data?
Does S3 encryption protect against a misconfigured public bucket?
We have existing buckets without encryption — can we enable encryption retroactively?
What is Macie, and should we enable it alongside S3 encryption?
Do CloudTrail data events need to be enabled to evidence S3 encryption for SOC 2?
Automate your compliance today
AuditPath runs 86+ automated checks across AWS, GitHub, Okta, and 14 more integrations. SOC 2 and DPDP Act. Free plan available.
Start for free