Microsoft 365 will send mail for your domain the moment you add it, with no authentication configured beyond a default that does not align. Everything below is what you have to do on top, in the order it needs doing.
1. SPF
One include covers all of Exchange Online:
example.com. IN TXT "v=spf1 include:spf.protection.outlook.com -all"
That include costs one DNS lookup and resolves to a flat list of ranges — no nested includes, which is more considerate than most providers:
"v=spf1 ip4:40.92.0.0/15 ip4:40.107.0.0/16 ip4:52.100.0.0/15 ip4:52.102.0.0/16 ip4:52.103.0.0/17 ip4:104.47.0.0/17 ip6:2a01:111:f400::/48 … -all"
Do not add these ranges to your own record
Flattening this particular include is a bad trade. Microsoft revises the list, and a stale copy means some of your own Exchange Online mail starts failing SPF with no error anywhere. One lookup for the whole platform is cheap — spend it.
If you send from anywhere else — a marketing tool, a ticketing system, an application — add those includes to the same record. Two v=spf1 records is a permerror, not twice the capacity.
2. DKIM, and the alignment trap
This is the step that matters most, and the one most often skipped, because mail appears to work without it.
Out of the box, M365 signs your outbound mail with a key belonging to your tenant's onmicrosoft.com domain. That signature is valid. DKIM passes. And DMARC fails, because the signing domain is yourtenant.onmicrosoft.com and your From: header says example.com, which do not align.
At p=none you will never notice. At p=reject, with SPF as the only thing holding DMARC up, every forwarded message is rejected.
Publish the two CNAMEs
M365 does not give you a key to publish. It gives you two CNAMEs pointing into your tenant domain, and Microsoft holds the keys on the other end:
selector1._domainkey.example.com. IN CNAME
selector1-example-com._domainkey.yourtenant.onmicrosoft.com.
selector2._domainkey.example.com. IN CNAME
selector2-example-com._domainkey.yourtenant.onmicrosoft.com.Microsoft's own domain is set up exactly this way, so you can see the shape in live DNS:
selector1-microsoft-com._domainkey.microsoft.onmicrosoft.com.
Your tenant name is the *.onmicrosoft.com domain listed under Microsoft 365 admin center → Settings → Domains.
Then turn it on
Publishing the CNAMEs is not sufficient. The signing has to be enabled in the portal, and it will refuse until the CNAMEs resolve:
Microsoft Defender portal → Email & Collaboration → Policies & rules → Threat policies → Email authentication settings → DKIM → select the domain → Enable
If it rejects the domain, the CNAMEs have not propagated yet or one of them has a typo. Both must resolve; one is not enough.
3. DMARC
Start at monitoring, with reporting on:
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
Leave it there until your aggregate reports show every legitimate sender passing, then move through quarantine to reject. The staged path covers what each stage is for.
Microsoft is a receiver too
M365 enforces inbound DMARC on mail arriving at your tenant, configurable under the same Email authentication settings. That is a separate decision from your own outbound policy, and worth reviewing at the same time.
4. Verify from outside
The portal showing DKIM as enabled means M365 believes it is signing. Confirm what the internet actually sees:
selector1-example-com._domainkey.yourtenant.onmicrosoft.com. "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ…" "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
Then send a message to an external address and read the headers. You want d=example.com in the DKIM-Signature. If it still says d=yourtenant.onmicrosoft.com, the enable step did not take.
The DKIM Inspector checks selector1 and selector2 by default, so it will find an M365 setup without being told the selector.
What M365 does differently
DKIM by CNAME, not by key. Almost every other provider generates a keypair and hands you a TXT record containing the public half. Microsoft keeps both halves and has you point at them. The practical consequence is good: rotation happens on Microsoft's side and your DNS never changes. The cost is that you cannot inspect or control the key, and you get two fixed selectors whether you want them or not.
The keys are 1024-bit. This is consistent across every tenant we checked, including Microsoft's own domain, GitHub's, and DuckDuckGo's — all on selector1 at 1024-bit RSA. RFC 8301 §3.2 treats 1024 as the floor and recommends 2048. It is not causing failures today, and it is not something you can change from your side.
MX shares the naming convention. example-com.mail.protection.outlook.com — same dashes-for-dots rule as the DKIM CNAME target, which is a useful thing to recognise when reading someone else's DNS.
Failure modes particular to M365
| Symptom | Cause | Fix |
|---|---|---|
DMARC fails while DKIM shows pass | Signing with tenant.onmicrosoft.com — custom-domain DKIM was never enabled | Publish both CNAMEs, then enable the domain in the Defender portal |
| The portal will not let you enable DKIM | One or both CNAMEs do not resolve yet | Check both with dig; allow for TTL after publishing |
| Some mail fails SPF after months of working | Someone copied the spf.protection.outlook.com ranges into the record instead of using the include | Replace the literal ranges with the include |
| Mail from a distribution list or shared mailbox fails | It is being forwarded, so SPF breaks and only DKIM can carry DMARC | Custom-domain DKIM. This is the case it exists for. |
| DKIM stops verifying after a tenant change | The CNAME targets embed the tenant name; renaming or migrating the tenant invalidates them | Republish the CNAMEs against the new tenant domain |
Honest limits
- You cannot choose your DKIM key length or algorithm. 1024-bit RSA is what you get.
- Two selectors, fixed names. If you need per-service selectors, they have to come from somewhere else.
- The DKIM controls live in the Defender portal rather than the main admin center, which is why they are hard to find. Microsoft has moved this page more than once.
- M365 does not host MTA-STS or provide DMARC report parsing. Both are separate problems once you get this far.
Nothing above needs CertaDNS — it is all records you publish wherever your DNS lives. Where we help is afterwards: the DMARC reports arrive as XML that is unreadable at volume, and the SPF record grows every time someone adds a sender. Email Authentication handles both.