S3 bucket has server-side encryption with AWS KMS
Amazon S3 buckets use server-side encryption with AWS KMS keys, including dual-layer aws:kms:dsse. The evaluation identifies buckets whose default encryption is aws:kms or aws:kms:dsse rather than SSE-S3.
Risk
Without KMS-based encryption, data relies only on SSE-S3, reducing confidentiality controls. Missing key policies and grants weakens least privilege, cross-account scoping, and the ability to disable or rotate keys. Lack of KMS audit trails obscures key usage, hindering detection of misuse and defense in depth.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks s3_bucket_kms_encryptionRecommendation
Enable default SSE-KMS (or DSSE-KMS for highly sensitive data). Use a customer-managed key, enforce least privilege and separation of duties for key usage, and require KMS encryption via bucket policy (specify aws:kms and a designated key). Monitor key activity in CloudTrail and consider S3 Bucket Keys to control cost.
Remediation
CLI
aws s3api put-bucket-encryption --bucket <BUCKET_NAME> --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}'Terraform
# Enable default SSE-KMS on an existing S3 bucket
resource "aws_s3_bucket_server_side_encryption_configuration" "<example_resource_name>" {
bucket = "<example_bucket_name>"
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms" # Critical: enforces SSE-KMS by default
}
}
}NativeIaC
# CloudFormation: enable default SSE-KMS on the bucket
Resources:
<example_resource_name>:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms # Critical: sets default encryption to AWS KMS (SSE-KMS)Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.s3.s3_client import s3_client
class s3_bucket_kms_encryption(Check):
def execute(self):
findings = []
for bucket in s3_client.buckets.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=bucket)
if bucket.encryption == "aws:kms" or bucket.encryption == "aws:kms:dsse":
report.status = "PASS"
report.status_extended = f"S3 Bucket {bucket.name} has Server Side Encryption with {bucket.encryption}."
else:
report.status = "FAIL"
report.status_extended = f"Server Side Encryption is not configured with kms for S3 Bucket {bucket.name}."
findings.append(report)
return findings