Back to Checks
aws

S3 bucket has server-side encryption with AWS KMS

s3_bucket_kms_encryption
Service: s3Severity: medium
OfficialBuilt-inVerified
Categories:encryption
Resource Type:AwsS3Bucket

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 Cloud
Run
prowler aws --checks s3_bucket_kms_encryption

Recommendation

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

1In the AWS Console, go to S3 and open the target bucket
2Select the Properties tab
3Under Default encryption, click Edit
4Choose Server-side encryption with AWS KMS keys (SSE-KMS)
5Leave AWS managed key (aws/s3) selected (or choose your CMK if required)
6Click Save changes

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