Quick Answer

DKIM key management at scale requires a systematic approach: use unique selectors per signing source, implement annual key rotation with overlap periods, maintain 2048-bit keys minimum, and automate where possible. For multi-domain setups, use CNAME delegation to centralize key hosting. Store private keys securely with access controls and audit logging.

DKIM Key Management at Scale

By Braedon·Mailflow Authority·Email Infrastructure·Updated 2026-03-31

Why Key Management Matters

Poor DKIM key management leads to:

  • Security gaps: Compromised keys enable spoofing
  • Deliverability issues: Broken DKIM fails authentication
  • Operational chaos: "Which key is used where?"
  • Compliance failures: Audits flag unrotated keys

At scale — multiple domains, ESPs, and environments — key management requires systems thinking. This is part of broader email authentication and DNS configuration.

Selector Strategy

Naming Convention

Use descriptive selectors that indicate:

  • Source: Which system signs with this key
  • Date/version: When the key was created

Examples:

sendgrid202603._domainkey.example.com   (ESP + year/month)
postfix-prod._domainkey.example.com     (System + environment)
marketing-v2._domainkey.example.com     (Use case + version)
s1._domainkey.example.com               (Generic, SendGrid default)

One Selector Per Signing Source

Never share selectors across signing systems:

Good:
  sendgrid._domainkey.example.com  → SendGrid's key
  mailgun._domainkey.example.com   → Mailgun's key
  postfix._domainkey.example.com   → [Self-hosted](/self-hosted-smtp/mailcow-setup-guide) key

Bad:
  default._domainkey.example.com   → Used by everything

Separate selectors let you:

  • Rotate independently
  • Troubleshoot by source
  • Remove an ESP without breaking others

Multi-Domain Selector Strategy

For agencies or multi-brand organizations:

# Each domain has its own selectors
marketing.clienta.com → s1._domainkey (SendGrid CNAME)
marketing.clientb.com → s1._domainkey (SendGrid CNAME)
marketing.clientc.com → s1._domainkey (SendGrid CNAME)

# Or use CNAME to centralized location
s1._domainkey.clienta.com → s1._domainkey.agency.com
s1._domainkey.clientb.com → s1._domainkey.agency.com

Practitioner note: CNAME delegation is the only way to manage DKIM sanely across 50+ domains. You host the actual keys in one DNS zone, and every client domain CNAMEs to it. Key rotation becomes one update instead of 50.

Key Generation

Generate 2048-bit Keys

Using OpenDKIM tools:

# Generate keypair
opendkim-genkey -b 2048 -d example.com -s selector202603

# Creates:
#   selector202603.private (private key)
#   selector202603.txt (DNS TXT record)

Using OpenSSL:

# Generate private key
openssl genrsa -out selector202603.private 2048

# Extract public key for DNS
openssl rsa -in selector202603.private -pubout -outform PEM | \
  grep -v "^-" | tr -d '\n'

Key Size Considerations

SizeStatusNotes
1024-bitDeprecatedWeak, some receivers penalize
2048-bitRecommendedStandard, good security
4096-bitOverkillMay exceed DNS TXT limits

Stick with 2048-bit.

Key Rotation Process

Timeline

Day 0:   Generate new keypair with new selector
Day 1:   Publish new selector's TXT record
Day 2-3: Wait for DNS propagation (check worldwide)
Day 4:   Update signing config to use new key
Day 5-7: Monitor for DKIM failures
Day 14:  Remove old selector's TXT record

Step-by-Step

1. Generate New Key

opendkim-genkey -b 2048 -d example.com -s selector202703

2. Publish New TXT Record

selector202703._domainkey.example.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."

3. Verify Propagation

# Check multiple resolvers
dig @8.8.8.8 TXT selector202703._domainkey.example.com +short
dig @1.1.1.1 TXT selector202703._domainkey.example.com +short

4. Update Signing Configuration

For Postfix + OpenDKIM, edit /etc/opendkim/KeyTable:

# Old
# example.com example.com:selector202603:/etc/opendkim/keys/selector202603.private

# New
example.com example.com:selector202703:/etc/opendkim/keys/selector202703.private

Reload OpenDKIM:

systemctl reload opendkim

5. Monitor

Check DMARC reports and mail logs for DKIM failures:

grep "DKIM" /var/log/mail.log | grep -i fail

6. Remove Old Key

After 2 weeks (messages in transit have cleared):

# Remove old TXT record from DNS
# Delete old private key file (securely)
shred -u /etc/opendkim/keys/selector202603.private

Automation

Rotation Script

#!/bin/bash
# dkim-rotate.sh

DOMAIN="example.com"
NEW_SELECTOR="selector$(date +%Y%m)"
KEY_DIR="/etc/opendkim/keys"

# Generate new key
opendkim-genkey -b 2048 -d $DOMAIN -s $NEW_SELECTOR -D $KEY_DIR

# Get public key for DNS (format for your DNS API)
PUBLIC_KEY=$(grep "p=" $KEY_DIR/$NEW_SELECTOR.txt | sed 's/.*p=//' | tr -d '";')

# Update DNS via API (example with Cloudflare)
# Replace with your DNS provider's API
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{
    \"type\": \"TXT\",
    \"name\": \"$NEW_SELECTOR._domainkey.$DOMAIN\",
    \"content\": \"v=DKIM1; k=rsa; p=$PUBLIC_KEY\",
    \"ttl\": 3600
  }"

# Wait for propagation
echo "Waiting 24 hours for DNS propagation..."
sleep 86400

# Update KeyTable
echo "$DOMAIN $DOMAIN:$NEW_SELECTOR:$KEY_DIR/$NEW_SELECTOR.private" > /etc/opendkim/KeyTable

# Reload
systemctl reload opendkim

echo "Rotation complete. Remove old selector after 2 weeks."

Schedule

Add to crontab for annual rotation:

# Rotate DKIM keys on March 1st each year
0 0 1 3 * /usr/local/bin/dkim-rotate.sh

ESP Key Management

Managed by ESP (CNAME)

Most ESPs prefer managing keys via CNAME:

# You add CNAME
s1._domainkey.example.com CNAME s1.domainkey.u12345.wl.sendgrid.net.

# ESP manages the actual key and rotation

Pros: Automatic rotation, no management Cons: Trust ESP's practices, less visibility

Self-Managed (TXT)

You host the key directly:

selector._domainkey.example.com TXT "v=DKIM1; k=rsa; p=..."

Pros: Full control, no vendor dependency Cons: Manual rotation, more work

Hybrid Approach

  • ESP sends with their managed CNAME selector
  • You add a second selector for self-hosted/backup signing
  • Both selectors can sign; either passing DKIM is valid

Practitioner note: For critical domains, I set up both ESP-managed and self-managed selectors. If the ESP has an issue with their keys (rare but happens), you have a fallback. ESP for convenience, self-managed for control.

Security Best Practices

Private Key Protection

# Restrict permissions
chmod 600 /etc/opendkim/keys/*.private
chown opendkim:opendkim /etc/opendkim/keys/*.private

# Encrypt at rest (if paranoid)
# Store keys in encrypted volume or use HSM for enterprise

Access Control

  • Limit who can access private keys
  • Use separate keys for dev/staging/production
  • Audit key access in logs

Key Compromise Response

If a key is compromised:

  1. Immediately rotate to new key (follow rotation process, but accelerate)
  2. Remove compromised key from DNS within hours, not days
  3. Audit for any spoofed messages using the compromised key
  4. Investigate how the compromise occurred
  5. Report to DMARC monitoring (expect spike in failures during transition)

Multi-Environment Management

Dev/Staging/Production

# Different selectors per environment
dev._domainkey.example.com      → Dev signing key
staging._domainkey.example.com  → Staging signing key
prod._domainkey.example.com     → Production signing key

This prevents:

  • Dev email from impacting production reputation
  • Key exposure in lower environments affecting production

Documentation

Maintain a key registry:

SelectorDomainEnvironmentCreatedRotatesPrivate Key Location
prod202603example.comProduction2026-032027-03/etc/opendkim/keys/
sendgridexample.comProductionESP managedAuton/a (CNAME)
dev202601example.comDev2026-01Never/etc/dev-opendkim/

If you need help designing DKIM key management processes or recovering from key-related deliverability issues, schedule a consultation.

Sources


v1.0 · March 2026

Frequently Asked Questions

How often should I rotate DKIM keys?

Annually is the standard recommendation. More frequent rotation (quarterly) adds security but increases operational overhead. Less frequent (multi-year) increases risk if a key is compromised. Always maintain overlap—publish new keys before removing old ones to handle messages in transit.

What DKIM key size should I use?

2048-bit minimum. 1024-bit keys are considered weak and some receivers penalize them. 4096-bit is overkill and may cause DNS TXT record issues. Stick with 2048-bit for the balance of security and compatibility.

How do I manage DKIM across multiple domains?

Use CNAME delegation: each domain's selector._domainkey CNAME points to your central DNS where you host the actual TXT records. When you rotate keys, update one location and all domains inherit the change. Much easier than managing TXT records on 50+ domains.

Should each ESP have its own DKIM selector?

Yes. Use different selectors for each signing source: sendgrid._domainkey, mailgun._domainkey, etc. This lets you rotate keys independently, troubleshoot by source, and remove an ESP without affecting others.

How do I automate DKIM key rotation?

Script the process: generate new keypair, publish new selector TXT record, wait for propagation (24-48h), update signing config to use new key, monitor for issues, remove old key after 2 weeks. Use DNS APIs for record management. Run quarterly or annually via cron/scheduler.

Want this handled for you?

Free 30-minute strategy call. Walk away with a plan either way.