Key Rotation
Key rotation
Cryptographic keys age. The strength of a key against attack erodes as compute power increases, and a key in production for years has been exposed to more potential compromise than one minted last month. Every modern DKIM deployment rotates keys on a regular cadence.
Rotation without downtime is the reason DKIM supports multiple selectors. This lesson covers why two selectors exist on M365, how Workspace rotation works, and what a manual rotation looks like for a self-hosted sender.
The rotation problem in one paragraph
The naive approach to rotating a DKIM key — generate a new key, replace the old TXT record with the new one — breaks every in-flight message signed with the old key. Once the old public key is gone from DNS, receivers verifying older messages fail. Mailing-list software with delayed delivery, queued bounces, anything held for several minutes — all fail.
The solution: publish both keys for an overlap period. The sender signs with the new key while receivers can still verify older messages against the old one. After the overlap, the old record gets retired.
This is what two selectors are for. One selector holds the active key. The other holds the previous key. On rotation, the roles swap. The receiver fetches whichever selector the message’s s= field names — both work during the overlap.
How M365 rotation works
Microsoft handles rotation automatically. The CNAMEs you published at selector1._domainkey and selector2._domainkey point to TXT records inside the tenant’s onmicrosoft.com namespace. Microsoft owns those TXT records.
The default rotation cadence in M365 is approximately every six months. The mechanism:
- At rotation time, M365 generates a new key pair inside the tenant.
- The TXT record behind one of the CNAMEs (say
selector1) updates to the new public key. - M365 begins signing outbound mail with
s=selector1and the new private key. - The TXT record behind
selector2continues to hold the previous key. Receivers verifying messages signed during the previous period still resolve against the old key successfully. - At the next rotation, the roles swap.
selector2gets the new key;selector1holds the previous.
From the client’s DNS perspective, nothing changes. The CNAMEs you published continue to point to the same hostnames. Microsoft updates the records on the other end of the CNAME.
From Cathedra’s perspective, nothing changes either. The check confirms that both CNAMEs resolve and both lead to valid public keys. Rotation is invisible.
This is the entire reason M365 uses CNAME indirection. The setup looks more complex than Workspace’s direct TXT record, but the tradeoff is that the client never has to think about rotation again.
How Google Workspace rotation works
Google Workspace does not rotate automatically. The TXT record at google._domainkey holds whatever key you published when you ran the workflow in lesson 4.5. Until someone re-generates the key in admin.google.com and re-publishes the TXT record, the key continues to live in DNS unchanged.
This is a real operational gap. A Workspace tenant set up in 2019 may still be signing with the same key it had at the start. We address this on Isidore’s side with a periodic review cadence.
The manual rotation workflow:
admin.google.com → Apps → Google Workspace → Gmail → Authenticate email. Select the domain.- Click “Generate new record.” Workspace generates a fresh key pair. The new public key is shown.
- Publish the new TXT record in DNS. Do not delete the old one yet. During the overlap, both records can coexist — Workspace signs with the new key, and the old key is still resolvable for any in-flight messages signed previously.
The wrinkle: there is only one host name (google._domainkey). Two TXT records at the same host means receivers picking either record. In practice this breaks verification because the receiver has no way to know which key matches the signature.
Workspace’s actual rotation mechanism: it generates a new selector internally and rotates the selector name. You publish the new selector’s record. Old selector stays in place during overlap.
- Confirm the new record resolves with
dig. - Back in admin.google.com, click “Switch to new DKIM record.” Workspace begins signing with the new key.
- Wait the overlap period — Isidore standard is 48 hours, longer for clients with heavy mailing-list use.
- Delete the old TXT record from DNS.
The exact UI labels and dialog flow shift periodically in the Workspace admin console. Read what the dialog tells you to do; the underlying mechanism is what’s described above.
Recommended cadence: every twelve months on a calendar reminder per client.
How rotation works for custom-keyed providers
Self-hosted mail servers and some transactional senders generate their own keys and require manual rotation. The general pattern, regardless of vendor:
- Generate the new key pair in the sender’s admin interface. Some senders generate a single key per domain; some generate per-selector.
- Pick a new selector name. If the current selector is
s1, uses2for the new one. The selector name is arbitrary as long as you can publish a record at{selector}._domainkey.{domain}. - Publish the new selector’s TXT record in DNS. Verify with
dig. - Switch the sender to use the new selector. Outbound mail begins carrying
s=set to the new selector. Receivers fetch the new public key. - Wait the overlap. 48 hours minimum, longer for high-volume senders.
- Delete the old selector’s TXT record.
Two real-world examples:
- Postmark. Generates a single key per signing domain, selector
pm. Rotation: generate a new key in Postmark, publish the new TXT, Postmark exposes a manual “rotate” action that performs the switchover. - SendGrid. Generates two selectors at setup,
s1ands2, similar to M365. Rotation alternates between them. Manual via the SendGrid admin.
Document the rotation cadence and the last-rotated date in IT Glue for every custom-keyed sender we manage.
What Cathedra sees during rotation
Cathedra’s check is stateless. It probes each selector and reports what currently resolves. During an M365 rotation, both selector1 and selector2 always resolve — Cathedra shows two selectors found regardless of which one is currently signing.
During a Workspace rotation, you may briefly see one selector reported as found and a separate one when running consecutive scans, depending on which records are in DNS at that moment. This is expected. The finding text remains pass as long as at least one valid record exists.
During a custom-provider rotation, Cathedra will report whichever of the 14 selectors in its list happen to match. If your rotation moves between s1 and s2, both are in Cathedra’s list and both show as found during the overlap.
Cathedra cannot tell you when the last rotation happened. It can only confirm what is currently published. The rotation cadence lives in IT Glue, not in DNS.
Why the two-selector pattern is the right default
When designing DKIM for a new client, plan for two selectors from day one. M365 gives you this for free. Workspace and most custom senders make it manual but still possible.
The cost of always having two selectors:
- One additional DNS record per domain.
- Slightly more cognitive overhead on first setup.
The benefit:
- Zero-downtime rotation, every time, forever.
- No support tickets from “DKIM started failing today.”
- The pattern is consistent across providers, so the rotation runbook is the same regardless of where mail is hosted.
This is worth the marginal complexity.
What you should remember
- DKIM keys need to rotate. The two-selector pattern enables rotation without downtime.
- M365 rotates automatically. Both selectors live in DNS as CNAMEs; Microsoft swaps the underlying keys on its own schedule.
- Google Workspace rotation is manual. Cadence: every twelve months at minimum, tracked in IT Glue.
- Custom-keyed providers vary. The general pattern is: generate new key on a fresh selector, publish, switch sender, wait the overlap, delete the old selector.
- Cathedra is stateless. It reports whatever currently resolves. Rotation cadence lives in IT Glue, not the audit.
Next: the remediation workflow — publishing M365 DKIM CNAMEs in GoDaddy from end to end.
Cathedra alignment: DkimRecordCheck.php — selector1/selector2 dual finding makes sense only after this lesson
