DKIM for Microsoft 365 (Exchange Online): The Dual-Selector CNAME-Delegated Model, Defender Portal Workflow, Set-DkimSigningConfig PowerShell, 2048-bit Key Rotation, and the onmicrosoft.com Signing-Domain Gotcha

A focused operator-implementation walkthrough for DKIM on Microsoft 365 / Exchange Online. The Microsoft 365 DKIM model is structurally different from Google Workspace, cPanel, and self-hosted DKIM: two CNAME records per custom domain (selector1._domainkey and selector2._domainkey) delegate to Microsoft's tenant key infrastructure under <tenant>.onmicrosoft.com, a rotation started by the administrator switches signing between the two selectors without any DNS change, and the private keys never leave Microsoft's tenant infrastructure. Documents the dual-selector CNAME-delegated architecture, the three-step deployment workflow (publish CNAMEs, wait for DNS propagation, enable signing via the Defender portal or Set-DkimSigningConfig), three verification gates, 2048-bit key rotation, the onmicrosoft.com signing-domain gotcha (the #1 M365 DMARC failure mode), seven common mistakes, and a per-symptom troubleshooting decision matrix. Differentiation from sibling guides: help_dmarc_for_microsoft_365.php covers DKIM as Step 2 of a broader rollout; this page is the DKIM-only operator reference.

This reference is provided in English. Microsoft 365 Defender portal UI labels (security.microsoft.com > Email & Collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM), PowerShell cmdlets (Set-DkimSigningConfig, Get-DkimSigningConfig, Rotate-DkimSigningConfig, Connect-ExchangeOnline, Get-AcceptedDomain, Resolve-DnsName), and DNS-record syntax (selector1._domainkey CNAME, v=DKIM1, k=rsa, p=, c=relaxed/relaxed) do not translate. We keep the body in the source language so technical terms remain consistent with Microsoft Learn documentation and RFC 6376.

TL;DR

  • Microsoft 365 DKIM uses two CNAME records per custom domain (selector1._domainkey and selector2._domainkey) delegating to your tenant's key infrastructure under <tenant>.onmicrosoft.com. Microsoft owns the private keys; operators only publish CNAMEs.
  • Three steps: (1) publish the two CNAMEs the Defender portal displays for your custom domain, (2) wait 24-48 hours for DNS propagation, (3) flip the Defender portal "Enable" toggle or run Set-DkimSigningConfig -Identity <your-domain> -Enabled $true from Exchange Online PowerShell.
  • The #1 M365 DKIM failure mode: outbound mail signed under <tenant>.onmicrosoft.com instead of your custom domain. Cause: DKIM was never enabled for the custom accepted domain after CNAME publication. Fix: verify CNAME resolution, then enable signing.
  • Two selectors for zero-downtime rotation: only one of selector1 and selector2 signs at a time; a rotation, which the administrator starts, switches signing to the other with no DNS change.
  • 2048-bit keys are today's baseline. Check the key size of your domain in the Get-DkimSigningConfig output; if it is 1024 bits, move to 2048 with Rotate-DkimSigningConfig -Identity <your-domain> -KeySize 2048.
  • Defender portal path: security.microsoft.com > Email & Collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM. Equivalent PowerShell: Connect to Exchange Online, then Get-DkimSigningConfig to inspect or Set-DkimSigningConfig -Identity <your-domain> -Enabled $true to enable.
  • Verification: dig selector1._domainkey.<your-domain> CNAME must return selector1-<dashed-your-domain>._domainkey.<tenant>.onmicrosoft.com; Authentication-Results in delivered mail must show dkim=pass header.d=<your-domain> (NOT header.d=<tenant>.onmicrosoft.com).
  • DKIM alone does not stop spoofing; DKIM is one of two authentication signals DMARC consumes. Pair DKIM with SPF (see SPF for Microsoft 365) and DMARC (see DMARC for Microsoft 365) for end-to-end spoof-resistance.

What this guide covers

A focused operator-implementation walkthrough for DKIM on Microsoft 365 / Exchange Online tenants. Sibling pages cover the broader rollout (DMARC for Microsoft 365 walks Steps 1-5 of the full SPF + DKIM + DMARC deployment), the protocol primer (DKIM explained), the canonicalization deep dive (DKIM canonicalization), the selector deep dive (DKIM selectors), and the replay-attack analysis (DKIM replay attacks). THIS page is the Microsoft-365-specific operator reference: the dual-selector CNAME-delegated model, the Defender portal workflow, the Set-DkimSigningConfig PowerShell cmdlet, the onmicrosoft.com routing-domain failure mode, and the 2048-bit key cadence.

The page is anchored against the Feb 2024 Google/Yahoo bulk-sender requirements that demand aligned DKIM for any domain sending more than 5000 messages per day to gmail.com or yahoo.com. Without DKIM enabled for the custom accepted domain (the most common M365 misconfiguration), bulk-sender messages will be junked or rejected by Google and Yahoo.

How Microsoft 365 DKIM works

M365 DKIM is structurally different from Google Workspace, cPanel, and self-hosted DKIM. Three architectural choices define it:

1. CNAME delegation (not TXT publication)

Most DKIM deployments publish a TXT record at <selector>._domainkey.<domain> containing the public-key bytes directly (v=DKIM1; k=rsa; p=<base64 public key> per RFC 6376 §3.6.2). M365 instead publishes a CNAME pointing at the tenant key material:

selector1._domainkey.example.com.  CNAME  selector1-example-com._domainkey.tenant.onmicrosoft.com.
selector2._domainkey.example.com.  CNAME  selector2-example-com._domainkey.tenant.onmicrosoft.com.

The actual v=DKIM1; k=rsa; p=… TXT lives at the <tenant>.onmicrosoft.com target, inside Microsoft's infrastructure. Receivers follow the CNAME chain transparently and read the TXT at the resolved target.

2. Dual selectors for rotation

Every custom domain has TWO selectors: selector1 and selector2. Microsoft keeps two independent key materials inside its infrastructure; one signs at any given time, and a rotation started by the administrator switches signing to the other. Operators never see the private keys. The current active selector is whichever appears in the most recent message's DKIM-Signature s= tag.

3. The dashed-domain transformation

The CNAME target uses a dashed transformation of your custom domain: dots become dashes. So example.com becomes example-com:

selector1._domainkey.example.com         → selector1-example-com._domainkey.tenant.onmicrosoft.com
selector1._domainkey.mail.example.com    → selector1-mail-example-com._domainkey.tenant.onmicrosoft.com
selector1._domainkey.example.org         → selector1-example-org._domainkey.tenant.n-v1.dkim.mail.microsoft

The third line shows the newer format: for custom domains added since May 2025 the target ends in dkim.mail.microsoft and part of it is assigned by Microsoft, while existing domains keep the older format. The Defender portal and Get-DkimSigningConfig show the exact CNAME values your specific custom domain needs — copy them rather than constructing them by hand.

Prerequisites

  • An active Microsoft 365 tenant with at least one custom accepted domain (the domain you want to DKIM-sign mail from). Verify with Get-AcceptedDomain via Exchange Online PowerShell.
  • Administrative role assignment: Global Administrator or Security Administrator (the Defender portal DKIM panel requires one of these roles).
  • DNS administration rights at your custom domain's authoritative nameservers (to publish the two CNAME records).
  • An SPF record already published with include:spf.protection.outlook.com — see SPF for Microsoft 365. SPF + DKIM together is the prerequisite for DMARC alignment.
  • Exchange Online PowerShell module installed (optional, only needed for cmdlet-based DKIM management): Install-Module ExchangeOnlineManagement, then Connect-ExchangeOnline.

Step 1: Publish the two CNAME records

Open the Microsoft 365 Defender portal at security.microsoft.com. Navigate to Email & Collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM. Click on your custom domain in the list. The portal displays the two CNAME records you must publish at your authoritative DNS provider:

; Replace example.com with your custom domain and
; tenant with your tenant prefix (visible in the Defender portal):

selector1._domainkey.example.com.  IN  CNAME  selector1-example-com._domainkey.tenant.onmicrosoft.com.
selector2._domainkey.example.com.  IN  CNAME  selector2-example-com._domainkey.tenant.onmicrosoft.com.

Publish both records at your DNS provider (Cloudflare, AWS Route 53, Azure DNS, GoDaddy, Namecheap, Google Cloud DNS, etc.). The exact UI varies, but each provider supports CNAME records natively. Confirm the records are published before proceeding:

$ dig +short selector1._domainkey.example.com CNAME
selector1-example-com._domainkey.tenant.onmicrosoft.com.

$ dig +short selector2._domainkey.example.com CNAME
selector2-example-com._domainkey.tenant.onmicrosoft.com.

Or on Windows PowerShell:

PS> Resolve-DnsName selector1._domainkey.example.com -Type CNAME
PS> Resolve-DnsName selector2._domainkey.example.com -Type CNAME

Allow 24-48 hours for DNS propagation. CNAME publication at the registrar / authoritative nameserver is instant at the source but receivers cache by TTL; until propagation completes for the full receiver population, the Defender portal Enable step will fail.

Step 2: Enable DKIM signing for the custom domain

Two paths — UI (Defender portal) or PowerShell. Both produce the same effect: Exchange Online begins signing outbound mail from the custom accepted domain with the published CNAME's selector1 / selector2 chain.

Defender portal UI

  1. Navigate to security.microsoft.com > Email & Collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM.
  2. Click your custom domain in the list.
  3. Toggle Sign messages for this domain with DKIM signatures to On.
  4. The portal confirms the change with a status banner; the domain row updates to Enabled: True.

Exchange Online PowerShell

PS> Install-Module ExchangeOnlineManagement
PS> Connect-ExchangeOnline -UserPrincipalName admin@example.com
PS> Set-DkimSigningConfig -Identity example.com -Enabled $true

If Microsoft has not yet detected the CNAME records, the cmdlet returns an error that contains the values to publish, and the domain stays in the CnameMissing state. Check the records for typos, wait a while and re-run.

Once enabled, Exchange Online signs every outbound message from the custom accepted domain with a DKIM-Signature header that includes d=example.com (your custom domain) and s=selector1 or s=selector2 (whichever is currently active).

Step 3: Verify DKIM signing is working

Three verification gates: DNS, configuration, and end-to-end delivery.

Gate 1: DNS resolution

$ dig +short selector1._domainkey.example.com CNAME
selector1-example-com._domainkey.tenant.onmicrosoft.com.
$ dig +short selector1-example-com._domainkey.tenant.onmicrosoft.com TXT
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAA..."

The first dig follows your custom-domain CNAME; the second resolves the tenant-side TXT and must return a valid v=DKIM1 record with a non-empty p= public-key field.

Gate 2: Tenant configuration

PS> Get-DkimSigningConfig -Identity example.com | Format-List Enabled,Selector1CNAME,Selector2CNAME,Status
Enabled         : True
Selector1CNAME  : selector1-example-com._domainkey.tenant.onmicrosoft.com
Selector2CNAME  : selector2-example-com._domainkey.tenant.onmicrosoft.com
Status          : Valid

Enabled=True and Status=Valid are the two must-haves; if either is False or anything other than Valid, signing is not happening for that domain.

Gate 3: End-to-end delivery

Send a message from the custom domain to an external mailbox you control (Gmail, Yahoo, your personal Outlook.com account, or DMARC Analyzer's Email Header Analyzer). Open the message headers and locate the Authentication-Results stack:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=selector1 header.b=AbCdEf12;
       spf=pass (google.com: domain of admin@example.com designates ...)
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com

Three requirements: (1) dkim=pass, (2) header.i=@example.com (your custom domain, NOT @tenant.onmicrosoft.com), (3) header.s=selector1 or selector2. If item 2 shows the onmicrosoft.com tenant domain, return to the onmicrosoft.com section below.

DKIM key rotation on Microsoft 365

The administrator starts DKIM key rotation for a custom domain; Microsoft does not do it on its own. A rotation generates a new key pair on the standby selector (whichever of selector1 / selector2 is not currently signing) and then switches outbound signing to that selector. The transition is transparent to receivers — both selectors remain published, so messages signed under the previous selector still verify. Microsoft compares key rotation to changing passwords periodically.

How to start a rotation

In the Defender portal, select the domain on the DKIM tab and choose Rotate DKIM keys, or run in PowerShell:

PS> Rotate-DkimSigningConfig -Identity example.com -KeySize 2048

The cmdlet generates a fresh key on the inactive selector. The change is not immediate: the new key starts signing after four days (96 hours), and until then the existing key is used. The CNAME records do not need to change. Rotate regularly, and immediately after any suspected key compromise.

Key-size posture

Today's baseline is 2048-bit RSA keys. According to Microsoft's documentation, New-DkimSigningConfig without the KeySize parameter creates a 1024-bit key, so it is worth checking the key size of your domain:

PS> Get-DkimSigningConfig -Identity example.com | Format-List Selector1KeySize,Selector2KeySize
Selector1KeySize : 2048
Selector2KeySize : 2048

If Selector1KeySize or the second property shows 1024, start a rotation to 2048:

PS> Rotate-DkimSigningConfig -Identity example.com -KeySize 2048

1024-bit RSA keys are considered factorable by well-funded adversaries; RFC 8301 permits them as a minimum and recommends at least 2048 bits, which is what receivers expect today.

The onmicrosoft.com signing-domain gotcha

The number-one M365 DKIM failure mode: outbound mail from example.com arrives at receivers with header.d=tenant.onmicrosoft.com instead of header.d=example.com. DMARC fails because the DKIM-signing domain does not align with the visible From: header domain.

Why it happens

M365 always signs SOMETHING. When DKIM is not explicitly enabled for the custom accepted domain, Exchange Online falls back to signing under <tenant>.onmicrosoft.com using the default DKIM key Microsoft automatically provisions at tenant creation. The default key is real, valid, and signs successfully — but its d= tag points at the tenant routing domain, not at your custom domain.

Symptom in Authentication-Results

Authentication-Results: mx.google.com;
       dkim=pass header.i=@tenant.onmicrosoft.com header.s=selector1-tenant-onmicrosoft-com
       spf=pass (google.com: domain of admin@example.com designates ...)
       dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=example.com

Note: dkim=pass is True (signature verifies cryptographically), but header.i is @tenant.onmicrosoft.com, not @example.com. DMARC alignment fails (the SPF-passing domain may align if SPF is configured, but DKIM is mismatched). Aggregate DMARC reports surface this as dkim=pass + spf=fail + dmarc=fail rows for messages your tenant sent.

Symptom in Get-DkimSigningConfig

PS> Get-DkimSigningConfig -Identity example.com | Format-List Enabled,Status
Enabled : False
Status  : CnameMissing

Enabled=False means signing with the custom domain is not turned on; Status=CnameMissing adds that Microsoft does not (yet) see the CNAME records. Once the records are published, the fix is one cmdlet:

PS> Set-DkimSigningConfig -Identity example.com -Enabled $true

Or via the Defender portal: toggle Sign messages for this domain with DKIM signatures to On.

Seven common Microsoft 365 DKIM mistakes

  1. Publishing CNAMEs but never enabling signing — the onmicrosoft.com gotcha above. CNAMEs published correctly are necessary but not sufficient; the Defender portal Enable toggle (or Set-DkimSigningConfig -Enabled $true) is the second required step.
  2. Hand-constructing the CNAME target — the target depends on the tenant prefix and on whether the domain uses the older format (onmicrosoft.com) or the newer one (dkim.mail.microsoft). Always copy the exact CNAME values from the Defender portal or from the Get-DkimSigningConfig output rather than building them by hand.
  3. Publishing only one selector — both selector1 AND selector2 are required. Only one signs at a time, but the other must be resolvable before the next rotation; Microsoft says to always create both records, because the inactive selector is needed for a seamless rotation.
  4. Publishing as TXT instead of CNAME — M365 DKIM is CNAME-only. Operators experienced with cPanel or Google Workspace sometimes publish a v=DKIM1; k=rsa; p=... TXT at the selector location, which the Defender portal cannot use.
  5. Forgetting the trailing dot in the CNAME target — depending on the DNS provider's UI, the target may need a trailing dot to be treated as a fully-qualified name. The Defender portal shows the target without the trailing dot; some DNS UIs require it. If dig reports the resolution chain pointing at your-domain.com.<target> you have a missing-trailing-dot bug.
  6. Enabling DKIM before Microsoft detects the CNAMEs — the Set-DkimSigningConfig -Enabled $true cmdlet fails and the status stays CnameMissing as long as the CNAMEs are not visible to Microsoft. Check the records with dig, wait a while and try again.
  7. Assuming DKIM stops spoofing on its own — DKIM authenticates that a specific signing domain produced the message, but receivers do not enforce on DKIM alone. DMARC is the enforcement layer that consumes DKIM and SPF verdicts. Without DMARC at p=quarantine or p=reject, spoofed mail still delivers regardless of DKIM state.

Troubleshooting decision matrix

Map the observed symptom to the diagnostic next step:

  • Symptom: Authentication-Results shows dkim=none.
    Diagnosis: DKIM is not enabled for the sending domain. Run Get-DkimSigningConfig -Identity <your-domain> — likely returns Enabled=False or no config exists for the domain at all.
    Fix: Publish CNAMEs and enable per the Step 1 / Step 2 sections above.
  • Symptom: Authentication-Results shows dkim=pass but header.i=@tenant.onmicrosoft.com and DMARC fails.
    Diagnosis: The onmicrosoft.com gotcha. CNAMEs may be published but signing is not enabled for the custom domain.
    Fix: Set-DkimSigningConfig -Identity <your-domain> -Enabled $true.
  • Symptom: Authentication-Results shows dkim=fail (body hash mismatch).
    Diagnosis: Message body was modified after signing — a forwarder, mailing list, or security gateway rewrote the body or added a footer. M365 uses c=relaxed/relaxed canonicalization, which tolerates whitespace and header-case changes but not body content modification.
    Fix: For forwarders/gateways in your control, configure ARC sealing (see ARC explained); for upstream forwarders out of your control, accept the failure and rely on DMARC's relaxed-mode SPF + DKIM any-pass-wins alignment.
  • Symptom: Set-DkimSigningConfig -Enabled $true returns an error and the status is CnameMissing.
    Diagnosis: Microsoft does not see the CNAME records — propagation is incomplete, or a record has the wrong name or target.
    Fix: Verify CNAMEs resolve from your local resolver (dig +short selector1._domainkey.<your-domain> CNAME) and that the target matches the portal value exactly; wait a while; re-run.
  • Symptom: DKIM verifies for messages sent from Outlook on the web but fails for messages sent via SMTP submission from a third-party application.
    Diagnosis: Some SMTP submission paths bypass Exchange Online's DKIM signer (legacy POP/IMAP relays, on-prem hybrid routes, misconfigured SMTP AUTH endpoints).
    Fix: Verify the submission path lands on smtp.office365.com:587 with STARTTLS and AUTH LOGIN — that path always signs. Legacy direct-send endpoints do not.

Frequently asked questions

How do I enable DKIM on Microsoft 365?
Three steps. (1) Publish the two CNAME records the Defender portal displays for your custom domain: selector1._domainkey.<your-domain> CNAME selector1-<dashed-your-domain>._domainkey.<tenant>.onmicrosoft.com and selector2._domainkey.<your-domain> CNAME selector2-<dashed-your-domain>._domainkey.<tenant>.onmicrosoft.com. The dashed-domain transformation converts dots to dashes (example.com becomes example-com). (2) Wait 24-48 hours for DNS propagation, then verify resolution: dig selector1._domainkey.<your-domain> CNAME should return the .<tenant>.onmicrosoft.com target. (3) In the Microsoft 365 Defender portal (security.microsoft.com), navigate to Email & Collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM. Select your custom domain and click Enable, or run Set-DkimSigningConfig -Identity <your-domain> -Enabled $true from Exchange Online PowerShell. From this moment Exchange Online signs outbound mail from your custom accepted domain with DKIM-d=<your-domain> instead of d=<tenant>.onmicrosoft.com.
Why does Microsoft 365 use two DKIM selectors?
So that key rotation runs without interruption and without DNS changes. For each custom domain you publish two CNAME records (selector1._domainkey and selector2._domainkey) pointing to two independent key materials in Microsoft's infrastructure. Only one selector signs at any given time; the other is needed for rotation, which is why Microsoft says to always create both records. The administrator starts a rotation, in the Defender portal or with Rotate-DkimSigningConfig; the new key starts signing after four days (96 hours), and until then the existing key is used. Operators never see the private key; it stays entirely in Microsoft's infrastructure. The dual-selector design is what distinguishes M365 DKIM from Google Workspace DKIM (single selector google._domainkey with TXT publication) and cPanel/self-hosted DKIM (single selector default._domainkey with a self-managed key in a TXT record).
Why are my Microsoft 365 messages signed under onmicrosoft.com instead of my custom domain?
Because DKIM was never enabled for your custom accepted domain in the Defender portal. M365 always signs outbound mail with SOME DKIM key — the default key is your tenant.onmicrosoft.com key, which Microsoft provisions automatically when the tenant is created. To get DKIM signing under your custom domain (your-company.com instead of your-company.onmicrosoft.com), you must (1) publish the two CNAMEs for selector1 and selector2 of the custom domain, (2) wait for DNS propagation, then (3) enable DKIM signing for that custom domain via the Defender portal "Enable" toggle or Set-DkimSigningConfig -Identity your-company.com -Enabled $true. Until that explicit Enable call fires, DMARC will fail because the DKIM-signing domain (onmicrosoft.com) does not align with the visible From: header domain (your-company.com). This is by far the #1 cause of DMARC failures on M365 tenants.
What is the difference between Microsoft 365 DKIM and Google Workspace DKIM?
Three structural differences. (1) Record type: M365 publishes CNAMEs delegating to the tenant's key material under <tenant>.onmicrosoft.com; Workspace publishes a TXT record containing the public-key bytes directly. (2) Selectors: M365 uses TWO selectors (selector1 and selector2) and switches between them during a rotation; Google Workspace uses ONE selector (google._domainkey) and the operator creates a new one at rotation. (3) Key publication: in M365 a new key appears behind the same CNAME records with no change in the domain's DNS; in Google Workspace a new public key reaches DNS only when the operator publishes a new TXT record. In both services the private key stays with the provider and the administrator starts the rotation. The practical consequence: an M365 rotation requires no DNS change, a Google Workspace rotation does. Both produce RFC 6376 §3.6.2 compliant v=DKIM1 records that receivers verify identically.
How do I rotate Microsoft 365 DKIM keys manually?
In the Microsoft Defender portal (security.microsoft.com > Email & collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM) select your custom domain and choose Rotate DKIM keys, or run Rotate-DkimSigningConfig -Identity <your-domain> -KeySize 2048 in Exchange Online PowerShell. The rotation creates a new key pair on the inactive selector; the change is not immediate: the new key starts signing after four days (96 hours), and until then the existing key is used. The CNAME records do not need to change as long as both are published. Check key sizes with Get-DkimSigningConfig in the Selector1KeySize and Selector2KeySize properties; if they show 1024, pass -KeySize 2048 when rotating. Microsoft compares key rotation to changing passwords periodically: do it regularly, and immediately after any suspected key compromise.
Why does my DKIM-Signature header show d=onmicrosoft.com after I enabled DKIM for my custom domain?
Most likely DNS propagation is incomplete or the Defender portal Enable click never landed. Microsoft 365 falls back to signing with the <tenant>.onmicrosoft.com key when (a) the selector1 and selector2 CNAMEs for your custom domain do not yet resolve to the .<tenant>.onmicrosoft.com targets, (b) DKIM signing was published in DNS but never enabled in the portal (the Enable toggle on the Defender DKIM panel is OFF or the Set-DkimSigningConfig -Enabled flag is $false), or (c) the sender is mailing through a non-custom-accepted-domain identity. Diagnose with three commands: dig selector1._domainkey.<your-domain> CNAME must return the tenant target; Get-DkimSigningConfig -Identity <your-domain> | Format-List Enabled must return Enabled=True; the failing message's DKIM-Signature header d= tag must match your custom domain. If all three pass, run Set-DkimSigningConfig -Identity <your-domain> -Enabled $true again to force the activation cycle.
Do I need to publish a DKIM ADSP or DMARC record for DKIM on Microsoft 365 to work?
No to ADSP, yes to DMARC if you want enforcement. RFC 5617 DKIM ADSP was deprecated in 2013 (RFC 6376 §5 explicitly states DKIM does not authorise messages by itself); receivers ignore ADSP records and look at DMARC instead. DKIM on M365 functions standalone — Exchange Online signs your mail, downstream receivers verify the signature, and the Authentication-Results header reports the verdict. DMARC enters the picture when you want receivers to enforce a policy when DKIM (or SPF) fails: publish v=DMARC1; p=none; rua=mailto:dmarc-reports@your-domain at _dmarc.<your-domain> and read reports for 2-6 weeks before advancing to p=quarantine then p=reject. See help_dmarc_for_microsoft_365.php for the full rollout walkthrough.
Can I bring my own DKIM key to Microsoft 365 instead of using the tenant key?
Not for native Exchange Online signing. The CNAME-delegation model that M365 uses by design places the private key inside Microsoft's tenant infrastructure — operators publish CNAMEs pointing at the tenant key material; they do not publish the public-key bytes directly. Two workarounds exist: (a) for third-party senders relayed via M365 (e.g., a security gateway, mailing-list platform, or marketing tool that signs before relaying through Exchange Online), the upstream sender can sign with its own key and own d= signing domain — Exchange Online preserves DKIM-Signature headers it did not generate; (b) for full DKIM control over the d=<your-domain> identity, an organization must move outbound mail flow out of Exchange Online (custom MTA, third-party signing relay) — incompatible with native M365 send. The pragmatic recommendation: keep native M365 signing on selector1/selector2 with the tenant key, and rotate it regularly from the Defender portal.

Verify DKIM on your Microsoft 365 tenant now

DMARC Analyzer parses the daily aggregate reports Microsoft and other receivers send to your rua= mailbox and surfaces the per-sender DKIM verdict breakdown via includes/DmarcParser.php — catching the onmicrosoft.com signing-domain failure mode within hours of the first misaligned message. Live DNS verification for every DKIM selector on your domain runs through includes/DnsChecker.php; the Email Header Analyzer at header_analyzer.php diagnoses individual message failures by parsing the full Authentication-Results stack via includes/EmailHeaderParser.php.

Sign up — Free plan Check my Microsoft 365 DKIM setup