- Knowledge Base
- Amazon Web Services
- Amazon S3
- Server Side Encryption
Ensure that your Amazon S3 buckets are protecting their sensitive content by enabling encryption at rest. With encryption at rest enabled, the Amazon S3 service can encrypt and decrypt your S3 objects using either AWS S3-managed keys (SSE-S3) or AWS KMS-managed keys (SSE-KMS).
This rule can help you with the following compliance standards:
- PCI
- HIPAA
- GDPR
- APRA
- MAS
- NIST4
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
When dealing with sensitive or mission-critical data, it is strongly recommended that you enable encryption at rest in order to protect your S3 data from attackers or unauthorized personnel. Encryption at rest can be implemented at the bucket level (S3 Default Encryption) and object level (Server-Side Encryption). S3 Default Encryption provides a way to set the default encryption behavior for an S3 bucket. Once S3 Default Encryption is enabled for a bucket, all new objects are automatically encrypted when they are uploaded to that bucket. Server-Side Encryption (SSE) is the encryption of S3 data at its destination by the application or service that receives it. Amazon S3 encrypts your data at the object level as it writes it to the S3 service disks and decrypts it for you when you access it.
Audit
Case A: To determine if S3 Default Encryption is enabled for your Amazon S3 buckets, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon S3 dashboard at https://s3.console.aws.amazon.com/s3.
03 Click on the name (link) of the S3 bucket that you want to examine to access the bucket configuration settings.
04 Select the Properties tab from the console menu to access the bucket properties.
05 In the Default encryption section, check the Default encryption feature status. If the feature status is set to Disabled, the S3 Default Encryption is not enabled for the verified bucket, therefore the selected Amazon S3 bucket does not automatically encrypt all S3 objects during upload.
06 Repeat steps no. 3 – 5 for each Amazon S3 bucket that you want to examine, available in your AWS cloud account.
Using AWS CLI
01 Run list-buckets command (OSX/Linux/UNIX) using custom query filters to list the names of all Amazon S3 buckets available in your AWS cloud account:
aws s3api list-buckets --query 'Buckets[*].Name'
02 The command output should return the name(s) of your Amazon S3 bucket(s):
[ "cc-project5-analytics", "cc-project5-api-bucket", "cc-project5-reports" ]
03 Run get-bucket-encryption command (OSX/Linux/UNIX) using the name of the Amazon S3 bucket that you want to examine as the identifier parameter, to describe the S3 Default Encryption feature configuration available for the selected bucket:
aws s3api get-bucket-encryption --bucket cc-project5-analytics
04 The command output should return the requested configuration information:
An error occurred (ServerSideEncryptionConfigurationNotFoundError) when calling the GetBucketEncryption operation: The server side encryption configuration was not found.
If the get-bucket-encryption command output returns the ServerSideEncryptionConfigurationNotFoundError error message, as shown in the output example above, the S3 Default Encryption is not enabled for the verified bucket, therefore the selected Amazon S3 bucket does not automatically encrypt all S3 objects during upload.
05 Repeat step no. 3 and 4 for each Amazon S3 bucket that you want to examine, created within your AWS cloud account.
Audit
Case B: To determine if your Amazon S3 buckets are configured to enforce Server-Side Encryption (SSE) via bucket policies, perform the following actions:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon S3 dashboard at https://s3.console.aws.amazon.com/s3.
03 Click on the name (link) of the S3 bucket that you want to examine to access the bucket configuration settings.
04 Select the Permissions tab from the console menu to access the bucket permissions.
05 Check the access policy defined for the selected S3 bucket, listed in the Bucket policy section. If the bucket does not have an access policy defined, the encryption at rest is not enabled at the object level, therefore the Server-Side Encryption (SSE) is not enabled for the selected Amazon S3 bucket. If the verified bucket has an access policy defined, check the policy document for the following Condition element: "Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" } }. When this condition is added to the bucket access policy, Amazon S3 will encrypt your objects by adding the x-amz-server-side-encryption header to the upload request. If this condition is not defined within the existing bucket policy, the Server-Side Encryption (SSE) is not enabled for the selected Amazon S3 bucket.
06 Repeat steps no. 3 – 5 to examine the bucket policy for other Amazon S3 buckets provisioned within your AWS account.
Using AWS CLI
01 Run list-buckets command (OSX/Linux/UNIX) using custom query filters to list the names of all Amazon S3 buckets available in your AWS cloud account:
aws s3api list-buckets --query 'Buckets[*].Name'
02 The command output should return the name(s) of your Amazon S3 bucket(s):
[ "cc-project5-analytics", "cc-project5-api-bucket", "cc-project5-reports" ]
03 Run get-bucket-policy command (OSX/Linux/UNIX) using the name of the Amazon S3 bucket that you want to examine as the identifier parameter and custom output filters to describe the access policy defined for selected bucket:
aws s3api get-bucket-policy --bucket cc-project5-analytics --query Policy
04 The command output should return the requested S3 bucket policy:
{ "Version": "2012-10-17", "Id": "cc-access-policy", "Statement": [ { "Sid": "RequireMFA", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::cc-project5-analytics/*", "Condition": { "Null": { "aws:MultiFactorAuthAge": true }} } ] }
If the get-bucket-policy command output returns a NoSuchBucketPolicy error message (i.e. An error occurred (NoSuchBucketPolicy) when calling the GetBucketPolicy operation: The bucket policy does not exist), the selected Amazon S3 bucket does not have an access policy defined, therefore the Server-Side Encryption (SSE) is not enabled for the selected S3 bucket. If the verified bucket has an access policy defined, check the policy document for the following Condition element: "Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" } }. When this condition is added to the bucket policy, Amazon S3 will encrypt your objects by adding the x-amz-server-side-encryption header to the upload request. If this condition is not defined in the access policy returned by the get-bucket-policy command output, the Server-Side Encryption (SSE) is not enabled for the selected Amazon S3 bucket.
05 Repeat steps no. 3 and 4 to verify the bucket policy for other Amazon S3 buckets available within your AWS cloud account.
Remediation / Resolution
Case A: To enable S3 Default Encryption for your existing Amazon S3 buckets, perform the following operations:
To enable S3 Default Encryption for your existing Amazon S3 buckets, use one of the following sets of templates, based on your requirements:1. Enable Default Encryption using the Amazon S3 key (SSE-S3):
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Enable S3 Default Encryption (SSE-S3)", "Resources": { "EncryptedS3Bucket": { "Properties": { "BucketName": "cc-project5-analytics", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { "ServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" } } ] } }, "Type": "AWS::S3::Bucket" } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Enable S3 Default Encryption (SSE-S3) Resources: EncryptedS3Bucket: Properties: BucketName: cc-project5-analytics BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 Type: AWS::S3::Bucket
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_s3_bucket" "encrypted-bucket" { bucket = "cc-project5-analytics" server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } } }
2. Enable Default Encryption using the Amazon KMS managed key (SSE-KMS):
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Enable S3 Default Encryption (SSE-KMS)", "Resources": { "EncryptedS3Bucket": { "Properties": { "BucketName": "cc-project5-analytics", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { "ServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:alias/aws/s3" } } ] } }, "Type": "AWS::S3::Bucket" } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Enable S3 Default Encryption (SSE-KMS) Resources: EncryptedS3Bucket: Properties: BucketName: cc-project5-analytics BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: aws:kms KMSMasterKeyID: arn:aws:kms:us-east-1:123456789012:alias/aws/s3 Type: AWS::S3::Bucket
Using Terraform
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_s3_bucket" "encrypted-bucket" { bucket = "cc-project5-analytics" server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { kms_master_key_id = "arn:aws:kms:us-east-1:123456789012:alias/aws/s3" sse_algorithm = "aws:kms" } } } }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon S3 dashboard at https://s3.console.aws.amazon.com/s3.
03 Click on the name (link) of the S3 bucket that you want to reconfigure.
04 Select the Properties tab from the console menu to access the bucket properties.
05 In the Default encryption section, choose Edit to change the feature configuration.
06 On the Edit default encryption page, perform the following actions:
- Select Enable under Server-side encryption, and choose one of the following encryption key types, based on your requirements:
- Select Amazon S3 key (SSE-S3) to encrypt your S3 objects automatically at upload using an encryption key that Amazon S3 creates, manages, and uses for you (i.e. S3-Managed Key – SSE-S3).
- Select AWS Key Management Service key (SSE-KMS) to automatically encrypt your S3 objects using an encryption key protected by AWS Key Management Service (SSE-KMS). If you choose this option, you must select a KMS-managed key from the AWS KMS key section. This KMS encryption key can be an AWS-managed key (aws/s3) or a customer-managed Customer Master Key (CMK). If you don't have a customer-managed CMK already created, choose Create key and follow the setup wizard to create a new one.
- (Optional) Select Enable under Bucket Key to configure the S3 bucket to use an Amazon S3 bucket key for Server-Side Encryption with Amazon KMS-Managed Keys (SSE-KMS).
- Choose Save changes to apply the configuration changes.
07 Repeat steps no. 3 – 6 to enable S3 Default Encryption for other Amazon S3 buckets provisioned in your AWS cloud account.
Using AWS CLI
01 To enable S3 Default Encryption for your existing Amazon S3 buckets, execute one of the following command requests, based on your requirements:
- Run put-bucket-encryption command (OSX/Linux/UNIX) to enable S3 Default Encryption for the specified Amazon S3 bucket using Server-Side Encryption with Amazon S3-Managed Keys – SSE-S3 (the command does not produce an output):
aws s3api put-bucket-encryption --bucket cc-project5-analytics --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" } } ] }'
- Run put-bucket-encryption command (OSX/Linux/UNIX) to enable S3 Default Encryption for the selected Amazon S3 bucket using Server-Side Encryption with AWS KMS-Managed Keys (SSE-KMS). To use this encryption type, you must provide the Amazon Resource Name (ARN) of the KMS-managed key that you want to use, as value for the KMSMasterKeyID parameter (e.g. "arn:aws:kms:us-east-1:123456789012:key/aaaabbbb-cccc-dddd-eeee-aaabbbcccddd"). The put-bucket-encryption command request does not produce an output:
aws s3api put-bucket-encryption --bucket cc-project5-analytics --server-side-encryption-configuration '{ "Rules": [ { "ApplyServerSideEncryptionByDefault": { "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/aaaabbbb-cccc-dddd-eeee-aaabbbcccddd", "SSEAlgorithm": "aws:kms" } } ] }'
02 Repeat step no. 1 to enable S3 Default Encryption for other Amazon S3 buckets available within your AWS cloud account.
Remediation / Resolution
Case B: To enforce Server-Side Encryption (SSE) for your existing Amazon S3 buckets via bucket policies, perform the following actions:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Enforce Encryption In Transit", "Resources": { "S3Bucket": { "Properties": { "BucketName": "cc-web-app-assets" }, "Type": "AWS::S3::Bucket" }, "SecureTransportPolicy": { "Type": "AWS::S3::BucketPolicy", "UpdateReplacePolicy" : "Retain", "Properties": { "Bucket": "cc-web-app-assets", "PolicyDocument": { "Version": "2012-10-17", "Id": "cc-secure-transport-bucket-policy", "Statement": [ { "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": "s3:*", "Condition": { "Bool": { "aws:SecureTransport": false } }, "Resource":"arn:aws:s3:::cc-web-app-assets/*" } ] } } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Description: Enforce Encryption In Transit Resources: S3Bucket: Properties: BucketName: cc-web-app-assets Type: AWS::S3::Bucket SecureTransportPolicy: Type: AWS::S3::BucketPolicy UpdateReplacePolicy: Retain Properties: Bucket: cc-web-app-assets PolicyDocument: Version: '2012-10-17' Id: cc-secure-transport-bucket-policy Statement: - Effect: Deny Principal: AWS: "*" Action: s3:* Condition: Bool: aws:SecureTransport: false Resource: arn:aws:s3:::cc-web-app-assets/*
Using Terraform
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.27" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_s3_bucket" "encrypted-bucket" { bucket = "cc-project5-analytics" } resource "aws_s3_bucket_policy" "encrypted-bucket-policy" { bucket = aws_s3_bucket.encrypted-bucket.id policy = jsonencode({ "Version": "2012-10-17", "Id": "PutObjPolicy", "Statement": [ { "Sid": "DenyIncorrectEncryptionHeader", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::cc-project5-analytics/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" } } }, { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::cc-project5-analytics/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" } } } ] }) }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon S3 dashboard at https://s3.console.aws.amazon.com/s3.
03 Click on the name (link) of the S3 bucket that you want to reconfigure.
04 Select the Permissions tab from the console menu to access the bucket permissions.
05 In the Bucket policy section, choose Edit to modify the bucket policy document (if there is one available).
06 On the Edit bucket policy page, in the Policy editor section, perform one of the following actions based on the existing policy configuration:
- If there is no access policy defined, paste the following JSON document in the Policy editor, replace
<bucket-name>
with the name of your own Amazon S3 bucket, and click Save changes. This bucket policy will enforce the owner and the users that have access to the selected Amazon S3 bucket to enable Server-Side Encryption (SSE) for every object uploaded via AWS Management Console, AWS CLI, or programmatically via AWS API:{ "Version": "2012-10-17", "Id": "PutObjPolicy", "Statement": [ { "Sid": "DenyIncorrectEncryptionHeader", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::
<bucket-name>
/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" } } }, { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<bucket-name>
/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" } } } ] } - If the selected S3 bucket has already an access policy configured, append the highlighted policy statements to the existing ones, as shown in the following example. Replace
<bucket-name>
with the name of your own Amazon S3 bucket, then click on the Save changes button to apply the policy changes. This policy configuration will enforce the bucket owner and the bucket users to enable Server-Side Encryption for every object uploaded via AWS Management Console, AWS CLI, or AWS API:{ "Id": "S3BucketAccessPolicy", "Version": "2012-10-17", "Statement": [ { ... },
{ "Sid": "DenyIncorrectEncryptionHeader", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<bucket-name>/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" } } }, { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<bucket-name>/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" } } }
] }
07 Repeat steps no. 3 – 6 to implement Server-Side Encryption using bucket policies for other Amazon S3 buckets available in your AWS cloud account.
Using AWS CLI
01 Define the access policy that will enforce the bucket owner and the users that have access to the bucket to enable Server-Side Encryption (SSE) for every object uploaded via AWS Management Console, AWS CLI, or programmatically via AWS API. Use the content of the access policy listed below, replace <bucket-name>
with the name of your own Amazon S3 bucket, then save the policy document to a JSON file named s3-sse-access-policy.json. If your Amazon S3 bucket has already an access policy configured, append only the highlighted statement blocks to the existing Statement element:
{
"Version": "2012-10-17",
"Id": "PutSSEObjPolicy",
"Statement": [
{
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<bucket-name>/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<bucket-name>/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
02 Run put-bucket-policy command (OSX/Linux/UNIX) to attach the access policy defined at the previous step, i.e. s3-sse-access-policy.json, to the specified Amazon S3 bucket (the command does not produce an output):
aws s3api put-bucket-policy --bucket cc-project5-analytics --policy file://s3-sse-access-policy.json
03 Repeat step no. 1 and 2 to enable Server-Side Encryption (SSE) using bucket policies for other Amazon S3 buckets provisioned within your AWS account.
References
- AWS Documentation
- General S3 FAQs
- Protecting data using encryption
- Protecting data using server-side encryption
- Protecting data using server-side encryption with Amazon S3-managed encryption keys (SSE-S3)
- Identity and access management in Amazon S3
- Setting default server-side encryption behavior for Amazon S3 buckets
- AWS Command Line Interface (CLI) Documentation
- s3api
- list-buckets
- get-bucket-encryption
- get-bucket-policy
- put-bucket-encryption
- put-bucket-policy