Enable DKIM for Microsoft 365

Enable DKIM for Microsoft 365

This is the most frequent DKIM enablement workflow we run. Most clients arrive at Isidore with M365 mailboxes and no DKIM configured — the tenant defaults send mail signed with onmicrosoft.com as the DKIM domain, which is technically valid but does not align with the client’s actual From: domain. DMARC will not credit it. From a Cathedra perspective the tenant looks broken.

The fix has two parts. Microsoft generates two keys in the tenant and asks you to publish two CNAME records in DNS. After both CNAMEs resolve, you flip a toggle in Defender and M365 begins signing outbound mail with the client’s domain.

The whole workflow runs in about fifteen minutes, with most of that being a wait for DNS propagation between the CNAMEs landing and the toggle being available.

Why CNAMEs and not TXT records

M365 does not let you hold the DKIM private key. Microsoft holds the key inside the tenant and rotates it on its own schedule. What you publish in DNS is not the public key directly — it is a CNAME that points to a TXT record under onmicrosoft.com, where Microsoft publishes the actual key.

This indirection is the reason M365 DKIM rotation is invisible. When Microsoft rotates the key on their side, the TXT record at selector1-{tenant}._domainkey.{tenant}.onmicrosoft.com changes. The CNAME in the client’s DNS keeps pointing to the same hostname; receivers resolve through the CNAME and pick up the new key with no client-side change required.

The pattern Microsoft publishes:

  • Host: selector1._domainkey
  • Target: selector1-{tenant}._domainkey.{tenant}.onmicrosoft.com

And for the second selector:

  • Host: selector2._domainkey
  • Target: selector2-{tenant}._domainkey.{tenant}.onmicrosoft.com

The {tenant} placeholder is the client’s M365 tenant name — the part before .onmicrosoft.com. For Isidore’s own tenant, that string is isidoregroup. The CNAMEs look like:

  • selector1._domainkey.isidoregroup.com → selector1-isidoregroup-com._domainkey.isidoregroup.onmicrosoft.com
  • selector2._domainkey.isidoregroup.com → selector2-isidoregroup-com._domainkey.isidoregroup.onmicrosoft.com

Note the slight transformation: the dot in isidoregroup.com becomes a hyphen when Microsoft constructs the subdomain. Always read the exact target from the Defender admin panel rather than constructing it by hand.

Step 1 — Open Defender and find DKIM settings

Sign into the M365 tenant as an admin. The DKIM controls live in Defender, not the main admin center.

Navigate to:

security.microsoft.com → Policies & rules → Threat policies → Email authentication settings → DKIM

You will see a list of every domain in the tenant. For a fresh tenant, every domain shows status “Sign messages for this domain with DKIM signatures: Disabled” with no CNAMEs yet generated.

Click the client’s domain.

Step 2 — Read the two CNAMEs Microsoft wants you to publish

A side panel opens with the domain’s DKIM details. Two CNAME records are listed under “Publish CNAMEs.” Copy both. Each has a Host and a Points to (the target) value.

The exact values are tenant-specific. Do not assume — read them from the panel.

Expected pattern:

  • Host: selector1._domainkey
  • Points to: selector1-{tenant}._domainkey.{tenant}.onmicrosoft.com
  • Host: selector2._domainkey
  • Points to: selector2-{tenant}._domainkey.{tenant}.onmicrosoft.com

Leave the Defender panel open. You will come back to it once DNS is published.

Step 3 — Publish the two CNAMEs in GoDaddy

Open the client’s DNS Management in GoDaddy. Confirm the access model in IT Glue first (Module 3’s remediation lesson covers this in detail).

Add the first CNAME:

  • Type: CNAME
  • Name (Host): selector1._domainkey
  • Value (Points to): the exact target from Defender
  • TTL: 1 hour

Save. Add the second CNAME the same way with selector2._domainkey and its target.

A note on the Host field. GoDaddy strips the domain suffix automatically — you enter selector1._domainkey, not selector1._domainkey.isidoregroup.com. If you include the suffix, GoDaddy publishes the record at selector1._domainkey.isidoregroup.com.isidoregroup.com and nothing resolves.

Step 4 — Verify the CNAMEs resolve

Wait a minute or two for GoDaddy to publish. Then from terminal:

dig selector1._domainkey.isidoregroup.com CNAME +short
dig selector2._domainkey.isidoregroup.com CNAME +short

Both should return the targets you entered. If either returns nothing, check the record in GoDaddy — typo in the Host field is the most common issue.

A +short query for the underlying TXT through the CNAME chain returns Microsoft’s actual key:

dig selector1._domainkey.isidoregroup.com TXT +short
"v=DKIM1; k=rsa; p=MIGfMA0GCSq..."

If that returns the full key, the chain is working end to end.

Step 5 — Enable DKIM in Defender

Return to the Defender DKIM panel for the domain. With both CNAMEs resolving, the previously-greyed-out toggle is now active. Set:

Sign messages for this domain with DKIM signatures: Enabled

Microsoft validates the CNAMEs at this moment. If validation fails — usually a typo in one of the targets — the toggle bounces back to disabled with an error message. Fix the CNAME in GoDaddy and try again.

If validation passes, the status updates to Enabled. M365 begins DKIM-signing outbound mail for the domain within minutes.

Step 6 — Confirm with Cathedra

Open Cathedra Workbench → Examen → Mail Diagnostics. Enter the domain. Run.

Expected DKIM finding:

DKIM Records — status: pass
2 DKIM selector(s) found: selector1, selector2

The raw_value array on the finding shows both selectors as CNAME → selector1-{tenant}._domainkey.{tenant}.onmicrosoft.com style entries — confirmation that Cathedra is following the CNAME indirection cleanly.

Common pitfalls

Wrong tenant in the target. A tech assumes the tenant name from the domain name. The tenant might be different — a client whose domain is acmecorp.com might have a tenant of acmecorpinc from the original M365 signup. Always copy the target straight from Defender.

Old CNAME records left over. If a previous tech started this workflow and didn’t finish, there may be stale selector1._domainkey and selector2._domainkey records pointing to the wrong tenant. Cathedra will find them (the CNAME fallback fires) but Defender validation will fail because the target tenant is wrong. Delete the stale records before re-publishing.

Defender validation cached. If you fix a wrong CNAME after a failed validation, Defender sometimes caches the failure for a few minutes. Wait, retry. If it still won’t validate after ten minutes with confirmed-correct CNAMEs, sign out of Defender and back in.

Domain not in the tenant. DKIM cannot be enabled for a domain that isn’t a verified accepted domain in the tenant. Confirm the domain shows up under “Accepted domains” in the Exchange admin center before troubleshooting CNAMEs further.

When to use one selector vs. two

Microsoft generates two from day one because both are needed for rotation (lesson 4.6). Publish both. Enable DKIM only when both validate. Do not try to run with one — the rotation workflow assumes both exist.

What you should remember

  • M365 publishes DKIM as two CNAMEs at selector1._domainkey and selector2._domainkey, pointing into the tenant’s onmicrosoft.com namespace.
  • Read the exact targets from Defender. Do not construct them by hand.
  • Publish both CNAMEs in DNS, verify with dig, then enable the toggle in Defender. Cathedra’s DKIM check passes once both CNAMEs resolve.
  • The CNAME indirection is what makes M365 DKIM rotation transparent. The key lives behind the CNAME; rotation changes the key without touching the client’s DNS.

Next: the same workflow for Google Workspace, which uses one selector and a direct TXT record.


Cathedra alignment: DkimRecordCheck.php — the selector1/selector2 CNAME branch fires green after this workflow