Encrypt AWS data at rest and in transit: This is non-negotiable
Encryption does not prevent breaches but it determines whether a breach results in a disclosure. Unencrypted data exposed in a misconfigured S3 bucket or an attacker who gains database access is a confirmed data breach. Encrypted data in the same scenario is an access to ciphertext: still serious, but a different compliance outcome.
UK GDPR, PCI DSS, FCA, and ISO 27001 all require encryption of data at rest and in transit for regulated data categories. This guide covers how to implement both correctly in AWS, including the key management choices that determine who actually controls the data.
Encryption at rest: the three approaches
AWS provides three encryption models for data at rest, differing in who controls the encryption key:
SSE-S3 (Amazon-managed keys): AWS generates, manages, and rotates the encryption key entirely. You enable it; AWS handles everything else. The key is an AWS-owned key in AWS's key management infrastructure. You cannot audit key usage, rotate manually, or revoke access via the key. This is the minimum acceptable configuration for non-sensitive data.
SSE-KMS (customer-managed KMS keys): You create and manage a key in AWS Key Management Service. AWS uses your key to encrypt and decrypt the data, but the key itself is under your control. You can audit every use of the key in CloudTrail, set expiry dates, control who can use the key via key policy, and revoke access by disabling or deleting the key. For GDPR personal data, PCI cardholder data, and other regulated data categories, SSE-KMS with a customer-managed key provides the control that regulators expect when asking "who controls the encryption of this data?"
SSE-C (customer-provided keys): You provide the encryption key on each request. AWS never stores the key; it is applied to the data and discarded. This gives you complete key control but requires your application to manage key storage and delivery, which is operationally complex. Relevant for organisations with regulatory requirements to maintain key material outside AWS.
Enable S3 server-side encryption by default
S3 buckets should have default encryption enabled so every object uploaded without an explicit encryption setting is encrypted automatically.
Enable default encryption on a bucket:
aws s3api put-bucket-encryption \
--bucket your-bucket-name \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:eu-west-2:ACCOUNT:key/your-key-id"
},
"BucketKeyEnabled": true
}]
}'
BucketKeyEnabled: true reduces KMS API calls (and associated costs) by using a bucket-level key that wraps per-object keys, rather than calling KMS for every single object operation.
Enforce encryption with a bucket policy that denies uploads without encryption:
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::your-bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}
This policy prevents unencrypted uploads even if the default encryption is accidentally removed or bypassed.
Enable encryption for RDS and Aurora
RDS and Aurora support encryption at rest using KMS. Encryption must be enabled at database creation time: you cannot enable encryption on an existing unencrypted database. To encrypt an existing unencrypted database, you must take a snapshot, copy the snapshot with encryption enabled, and restore from the encrypted copy.
The RDS encryption setting covers the database storage, automated backups, read replicas, and snapshots. All are encrypted with the same KMS key. Use a customer-managed KMS key rather than the default AWS-managed RDS key to maintain key control.
For database connections, enforce TLS by:
- Setting rds.force_ssl = 1 for PostgreSQL in the parameter group
- Setting require_secure_transport = ON for MySQL/Aurora MySQL
- Using the AWS-provided SSL/TLS certificate bundle for your application's database connection configuration
Encrypt EBS volumes
EBS volumes support encryption at the volume level, applied at creation. All data written to an encrypted EBS volume, including all snapshots, is encrypted with the associated KMS key.
Enable account-level EBS encryption by default so all new volumes created in the account are encrypted automatically:
aws ec2 enable-ebs-encryption-by-default \
--region eu-west-2
For existing unencrypted volumes, the migration path is: create a snapshot, copy the snapshot with encryption, create a new volume from the encrypted snapshot, detach the unencrypted volume, and attach the encrypted one. This requires a brief downtime window for attached volumes.
Enforce encryption in transit with TLS
For HTTPS-accessible services, enforce TLS at the load balancer and reject unencrypted HTTP connections:
Application Load Balancer: Add an HTTP-to-HTTPS redirect listener rule on port 80:
{
"Type": "redirect",
"RedirectConfig": {
"Protocol": "HTTPS",
"Port": "443",
"StatusCode": "HTTP_301"
}
}
S3 bucket policy: Deny HTTP requests:
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::your-bucket", "arn:aws:s3:::your-bucket/*"],
"Condition": {
"Bool": {"aws:SecureTransport": "false"}
}
}
API Gateway: Enable HTTPS-only endpoints (HTTP is disabled by default for REST APIs).
Enforce TLS 1.2 as the minimum version. AWS ALBs, CloudFront, and API Gateway all support specifying minimum TLS version in the security policy settings. TLS 1.0 and 1.1 have known vulnerabilities and should not be accepted.
KMS key management: the operational discipline
KMS customer-managed keys require ongoing operational attention:
Key rotation: Enable automatic annual rotation for all CMKs used for data at rest encryption. AWS generates new key material annually while retaining old material to decrypt data encrypted under previous key versions.
Key policy governance: Review key policies quarterly. The key policy defines who can use and manage the key. Overly permissive key policies (allowing broad IAM permissions to use the key) undermine the access control benefit of CMK encryption.
Key deletion protection: Keys schedule for deletion with a 7-30 day waiting period. Do not delete a key if any data encrypted under it may still need to be accessed. Use aws kms describe-key to review the key usage before scheduling deletion.
Audit key usage in CloudTrail: Every KMS API call is logged. Unexpected calls to kms:Decrypt from unusual principals are security signals worth investigating.
Where Critical Cloud comes in
Encryption is table stakes for regulated AWS environments, but implementation errors (unencrypted snapshots, HTTP endpoints that still accept connections, KMS key policies that are too permissive) are common. We audit and implement encryption for AWS environments under FCA, PCI DSS, and ISO 27001 requirements, with AWS Config rules enforcing encryption standards continuously. As the world's first Powered by Datadog accredited partner, we surface encryption compliance signals alongside operational health. See how Critical Support works.