SES identity has DKIM signing enabled
Amazon SES identities are evaluated for DKIM (DomainKeys Identified Mail) signing enabled and verified. DKIM adds a cryptographic signature to outgoing emails, allowing recipients to verify that the email was sent by the domain owner and was not altered in transit.
Risk
Without DKIM signing, emails sent from SES identities are vulnerable to spoofing and tampering. Attackers can forge emails that appear to come from your domain, leading to phishing attacks, brand impersonation, and loss of email deliverability. Email providers are more likely to reject or mark unsigned emails as spam, impacting business communication and reputation.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks ses_identity_dkim_enabledRecommendation
Enable DKIM signing for all SES identities and ensure the DKIM status is SUCCESS. Add the required CNAME records to your DNS provider to complete verification. Combine DKIM with SPF and DMARC for comprehensive email authentication following defense in depth principles. Monitor DKIM status regularly and rotate DKIM keys as recommended by AWS.
Remediation
CLI
aws sesv2 put-email-identity-dkim-signing-attributes --email-identity <IDENTITY-NAME> --signing-attributes-origin AWS_SESTerraform
resource "aws_ses_domain_dkim" "<example_resource_name>" {
domain = "<example_domain_name>"
}
# Add the CNAME records to Route53 (or your DNS provider)
resource "aws_route53_record" "<example_resource_name>_dkim" {
count = 3
zone_id = "<route53_zone_id>"
name = "${aws_ses_domain_dkim.<example_resource_name>.dkim_tokens[count.index]}._domainkey.<example_domain_name>"
type = "CNAME"
ttl = 600
records = ["${aws_ses_domain_dkim.<example_resource_name>.dkim_tokens[count.index]}.dkim.amazonses.com"]
}Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ses.ses_client import ses_client
class ses_identity_dkim_enabled(Check):
def execute(self):
findings = []
for identity in ses_client.email_identities.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=identity)
if identity.dkim_status == "SUCCESS" and identity.dkim_signing_enabled:
report.status = "PASS"
report.status_extended = f"SES identity {identity.name} has DKIM signing enabled and verified."
elif identity.dkim_status in (
"PENDING",
"NOT_STARTED",
"TEMPORARY_FAILURE",
):
report.status = "FAIL"
report.status_extended = f"SES identity {identity.name} has DKIM signing not verified (status: {identity.dkim_status})."
elif identity.dkim_status == "FAILED":
report.status = "FAIL"
report.status_extended = f"SES identity {identity.name} has DKIM signing failed verification."
elif (
identity.dkim_status == "SUCCESS" and not identity.dkim_signing_enabled
):
report.status = "FAIL"
report.status_extended = f"SES identity {identity.name} has DKIM verified but signing is disabled."
else:
report.status = "FAIL"
report.status_extended = f"SES identity {identity.name} does not have DKIM signing configured."
findings.append(report)
return findings