The Quiet Risk of Set-and-Forget DKIM
Most Amazon SES senders configure DKIM once, watch the green tick appear in the console, and never revisit the subject. That is understandable. The keys keep working, no alerts fire, and the maintenance requirement is invisible. The problem is that a long-lived private key is a long-lived risk. If that key is ever exposed through a leaked configuration repository, a server snapshot left in an S3 bucket, a compromised CI/CD secret, or a cloud credentials breach, an attacker can forge valid DKIM signatures for as long as the key remains active. Rotating keys limits the blast radius of any such compromise to the period between rotations, rather than the entire lifetime of your sending domain.
RFC 6376, the DKIM specification, explicitly recommends periodic key rotation as a security measure. Industry guidance reinforces this: M3AAWG recommends rotating DKIM keys at least twice a year, having revised an earlier quarterly recommendation after research showed that a six-month cadence better balances security benefit against operational effort. A twice-yearly schedule is a sound baseline for most teams. Organisations with higher risk profiles, those handling financial, government, or health-related mail, should consider rotating quarterly. With a repeatable runbook, rotation becomes routine maintenance rather than a risky, infrequent event. This article provides that runbook for Amazon SES, covering all three signing modes SES supports.
The Three SES DKIM Signing Modes
Amazon SES offers three distinct approaches to DKIM signing, and the rotation procedure differs for each. Understanding which mode you are using is the necessary first step before touching anything.
Easy DKIM
With Easy DKIM, Amazon SES automatically generates the DKIM public-private key pair and provides three CNAME records that must be published in your domain's DNS. After those records are in place, SES handles signing for outgoing messages and manages key rotation internally. This three-selector architecture means AWS can cycle the underlying keys without requiring you to republish DNS records, because your CNAMEs point to SES-managed infrastructure. SES defaults to a 2048-bit RSA key length for Easy DKIM. The key-length setting can be changed, but AWS enforces a limit of one change per 24-hour period. For the vast majority of senders, Easy DKIM is the lowest-friction and lowest-maintenance option available.
BYODKIM (Bring Your Own DKIM)
With BYODKIM, you generate your own public-private key pair, publish the public key as a TXT record in DNS under a selector you choose, and configure SES to sign with your private key via the SES v2 API. The private key must be in PKCS#1 or PKCS#8 format, use between 1024-bit and 2048-bit RSA encryption, and be base64-encoded before being supplied to the API. BYODKIM uses a single DNS TXT record rather than three CNAMEs, giving you one selector to manage per rotation cycle. The trade-off is that you are entirely responsible for rotation. BYODKIM is the right choice for organisations with centralised key management systems, compliance requirements that mandate control over cryptographic material, or security policies that prohibit delegating key custody to a third party.
Deterministic Easy DKIM (DEED)
Announced in December 2024, DEED extends Easy DKIM to work across all commercial AWS Regions rather than being limited to the single region where the identity was verified. While standard Easy DKIM requires DNS lookups to resolve in the region where the identity was created, DEED allows replica identities in other regions to inherit the signing attributes of a parent identity automatically, without additional DNS changes. DEED is primarily aimed at large customers with multinational operations and at independent software vendors who send on behalf of customers across multiple regions. From a rotation perspective, DEED inherits Easy DKIM's automatic key cycling, so the operational burden remains minimal.
Choosing the Right Mode
If you have no compliance mandate specifying who must hold the private key, Easy DKIM or DEED is the sensible default. AWS handles key generation, storage, and cycling, removing the most error-prone parts of the process. If you send from multiple AWS Regions and want a single DNS configuration to cover all of them, DEED is the mode to use. If your security policy requires that private keys be generated and stored within your own key management infrastructure, such as AWS KMS or a hardware security module, then BYODKIM is the only viable option.
One important caveat when migrating: if you are currently on Easy DKIM and switch to BYODKIM, there is a window between the moment you call the API and the moment SES confirms your DNS configuration during which outbound mail may be sent without a DKIM signature. AWS recommends using an intermediary step, such as enabling BYODKIM on a subdomain first and then deleting it once verification passes, or performing the cutover during a planned low-volume period.
Selector Naming Conventions
The selector is the DNS label that tells a receiving mail server which public key to use when verifying a signature. It appears as the s= value in the DKIM-Signature header of every outgoing message. With Easy DKIM, SES generates opaque token-style selectors that you do not control. With BYODKIM, you choose the selector name yourself, and that choice has long-term operational consequences.
Date-stamped selectors are the most auditable option. A name such as ses-20260901 or ses-2026-q3 tells you at a glance when the key was deployed, which matters when reviewing DMARC aggregate reports months after a rotation. Sequential selectors such as ses-key1 and ses-key2 are simpler to generate programmatically but require a separate record to determine when each key was created. Provider-prefixed names such as ses-prod-20260901 are useful when a domain is signed by multiple systems, because they prevent selector collisions with keys created by Google Workspace, Microsoft 365, or other sending platforms. Whatever convention you adopt, use only alphanumeric characters and hyphens in the selector name, keep it lowercase, and never reuse a selector name after its key has been retired. Reusing a retired selector name causes verification failures for any recipient or security team attempting to validate an older message that was signed with the original key under that name.
BYODKIM Rotation Runbook
The following procedure assumes you are rotating an existing BYODKIM configuration. Adjust the selector names and domain to match your environment. All CLI commands use the SES v2 API.
Step 1: Generate a new 2048-bit RSA key pair
Run the following on a secure, access-controlled machine or within a pipeline connected to your key management system. Never generate keys on a shared build server with broad access.
openssl genrsa -out ses-new-private.key 2048openssl rsa -in ses-new-private.key -pubout -out ses-new-public.key
Before placing the public key in DNS, strip the PEM header and footer lines. Before supplying the private key to the API, strip its header and footer lines and remove all line breaks so that the result is a single unbroken base64 string. RFC 8301 requires RSA keys of at least 1024 bits and recommends at least 2048 bits; do not generate anything shorter.
Step 2: Publish the new selector in DNS alongside the old one
Create a new TXT record in your DNS zone. Do not remove the existing selector record at this stage. Both selectors must coexist throughout the rotation window.
ses-20260901._domainkey.yourdomain.com. 300 IN TXT "v=DKIM1; k=rsa; p=YOUR_BASE64_PUBLIC_KEY"
Set the TTL to 300 seconds at publication. This allows the record to propagate quickly and means that if you need to correct a formatting error, the change takes effect within minutes rather than hours. Incorrect base64 encoding is the most common cause of BYODKIM validation failure; verify the record with a DKIM lookup tool before proceeding.
Step 3: Wait for DNS propagation
Allow at least the TTL duration plus a buffer before moving to the next step. For a 300-second TTL, wait at least ten minutes, then use dig TXT ses-20260901._domainkey.yourdomain.com from multiple geographic vantage points to confirm the record is resolving correctly everywhere you test. Do not proceed until it is.
Step 4: Update SES signing attributes via the AWS CLI
Call put-email-identity-dkim-signing-attributes to tell SES to begin signing with the new key and selector. The private key value must be base64-encoded and must not include PEM headers or line breaks.
aws sesv2 put-email-identity-dkim-signing-attributes \
--email-identity yourdomain.com \
--signing-attributes-origin EXTERNAL \
--signing-attributes '{"DomainSigningSelector":"ses-20260901","DomainSigningPrivateKey":"BASE64_PRIVATE_KEY"}'
SES will verify the new selector in DNS before activating signing. Check the identity's DKIM status in the console or by calling aws sesv2 get-email-identity --email-identity yourdomain.com and inspecting the DkimAttributes block. The status should move from PENDING to SUCCESS once SES has confirmed the DNS record. Note that SES will not fall back to any previous signing method during the pending state, so messages sent in that window may go out unsigned.
Step 5: Observe the overlap period before retiring the old selector
Keep the old selector's DNS TXT record published for a minimum of seven days after cutover, and ideally for 30 days. There are three reasons for this window. First, DNS resolver caches can hold a TXT record for its TTL, which may be up to 24 hours on records that previously had high TTL values. Second, a receiving mail transfer agent can hold a message in its retry queue for up to five days; if a message was signed with the old key and the old selector disappears before delivery, DKIM verification will fail. Third, security teams sometimes need to validate the DKIM signature of a message received days or weeks earlier, and a retired selector makes that impossible.
Step 6: Remove the old selector
Once the overlap window has passed and your DMARC aggregate reports confirm that no messages are still being signed with the old selector, delete the old TXT record from DNS. Never reuse the retired selector name for a future key.
Easy DKIM: What You Actually Need to Monitor
If you are running Easy DKIM, AWS handles key cycling automatically via the three pre-published CNAME records. You do not generate keys, you do not publish new selectors, and you do not call any API to trigger rotation. The CNAME pointers remain stable while the underlying keys at the SES infrastructure layer change. Your operational responsibility is to ensure those three CNAME records remain in DNS at all times. Removing even one of them can cause signing failures for a subset of messages. Check that all three CNAMEs are still resolving correctly whenever you make changes to your DNS zone, and include a periodic automated check in your monitoring setup.
If your identity was originally configured with the 1024-bit key-length option, you can upgrade to 2048-bit by calling put-email-identity-dkim-signing-attributes with the RSA_2048_BIT value. AWS enforces a limit of one key-length change per 24-hour period, so plan the upgrade accordingly.
DNS TTL Guidance and Timing
TTL management is one of the most frequently mishandled parts of BYODKIM rotation. Lower your selector's DNS TTL to 300 seconds several days before you intend to publish the new record. This ensures that when you do publish, the change propagates quickly across resolvers. Keep the TTL low throughout the rotation window, and restore it to your normal value, typically 3600 seconds or higher, only after the old selector has been retired and the new one has been confirmed stable by actual mail flow. The critical rule is never to delete the old DKIM DNS record before the new one is confirmed active, propagated, and verified. The overlap period is what prevents delivery failures during rotation.
Post-Rotation Verification
Verification has two layers: immediate header inspection and longer-term aggregate data review.
For immediate verification, send a test message and inspect the raw headers. Look for the DKIM-Signature header and confirm that the s= tag matches your new selector. Then check the Authentication-Results header inserted by the receiving server and confirm it reads dkim=pass. If the s= value still shows the old selector, SES has not yet switched signing. If dkim=fail or dkim=permerror appears, check that the public key in DNS exactly matches the private key you uploaded and that base64 encoding is correct and free of whitespace.
For aggregate verification, review your DMARC aggregate reports in the days following the cutover. These reports are delivered as XML to your DMARC rua address and show per-message authentication results including the selector used. You are looking for two things: confirmation that the new selector is appearing in reports with a dkim=pass result, and confirmation that the old selector is no longer appearing once you have switched signing. If the old selector still appears in fresh reports after the cutover, something in your sending infrastructure is still using it, which may indicate a misconfigured sending path or an identity-level DKIM override in SES. Also monitor your SES bounce and complaint rates in the days immediately following rotation. A sudden spike is a reliable early signal that DKIM verification is failing for some portion of your mail.
Common Mistakes to Avoid
Overwriting an existing BYODKIM key by reusing the same selector name is one of the most damaging errors. When you update the TXT record under an existing selector name, any message signed with the old key under that selector will fail verification at the receiving end, because the public key in DNS no longer matches. Always create a new selector name for each rotation event.
Forgetting identity-level DKIM overrides in SES is another common trap. DKIM signing properties are inherited from the parent domain to email address identities within SES. If a specific email address identity has had DKIM signing explicitly disabled or overridden, it will not inherit the updated signing configuration from the domain. Check for identity-level overrides if a particular sender's mail is unsigned while everything else on the domain passes correctly.
Leaving stale selectors in DNS after migrating between sending providers creates unnecessary noise in DMARC reports and, more importantly, leaves an orphaned public key in DNS that nobody manages. If you have migrated away from a provider that used BYODKIM, remove the old selector TXT records once you are confident no messages signed with those keys are still in transit or subject to audit.
Continuous DKIM Health Monitoring with SES Monitor
A runbook executed twice a year is only as reliable as the alerting that surrounds it. DKIM rotation is a living maintenance task, not a one-time procedure, and the gaps between rotations need active surveillance. SES Monitor provides continuous monitoring of your SES identity's DKIM status, alerting you immediately if a selector enters a failed or pending state rather than leaving you to discover the problem hours later through customer complaints. Bounce and complaint spike detection during the rotation window gives you an early signal if the new key is not verifying correctly across major mailbox providers. DMARC alignment monitoring confirms that the new selector is producing correctly aligned signatures rather than merely passing DKIM in isolation. Together, these signals replace the manual header inspection and report-reading that would otherwise consume engineering time after every rotation event.