Our Thinking / Field Notes / The Guide

STEP-BY-STEP GUIDANCE / MICROSOFT 365 EMAIL AUTHENTICATION

How to Set Up SPF, DKIM and DMARC in Microsoft 365

A practical route to publishing SPF, turning on DKIM signing, adding a monitoring-only DMARC record, checking a test message's headers and tightening to quarantine or reject only when the reports show your genuine senders pass.

Start here

Work in this order. First publish one SPF record at your DNS host that includes Microsoft 365. Then turn on DKIM for your custom domain in the Microsoft Defender portal, which needs two CNAME records at your DNS host. Then add a DMARC record with a policy of none and a reports address, so you can see who sends as your domain without affecting delivery. Send a test message to an outside mailbox and confirm spf, dkim and dmarc all show pass in its headers. Only move DMARC to quarantine and then reject once the reports show every legitimate sender passing.

What each record does, and why the order matters

Three DNS-based checks decide whether a receiving mail system believes a message really came from your domain. SPF is a published list of the servers allowed to send mail for the domain. DKIM is a digital signature that Microsoft 365 adds to outgoing messages and the receiver verifies using a public key published in your DNS. DMARC sits on top: it says that SPF or DKIM must pass for a domain that matches the visible From address, tells receivers what to do when neither does, and asks them to send you reports.

The order matters because DMARC is the only one of the three that can cause your own legitimate mail to be junked or rejected, and it can only do that safely once you know every system that sends as your domain. So the sequence is SPF, then DKIM, then DMARC in monitor-only mode, then reading the reports, and only then tightening. Both Microsoft and the NCSC describe a staged rollout of this kind. A red mark on an online checker is not a reason to skip straight to reject.

Microsoft 365 has no screen for editing SPF or DMARC records. Those are created at whoever hosts your DNS, often the domain registrar. DKIM is a mixture: you switch it on in the Microsoft Defender portal and publish two records at your DNS host.

Before you begin, and what is already published

If you only ever send from your yourtenant.onmicrosoft.com address, Microsoft already handles SPF and DKIM for it. This guide is for organisations sending from their own domain, such as yourcompany.co.uk. Where mail is sent from more than one domain or subdomain, each needs its own SPF record and its own DKIM setup. DMARC is different: a record on the main domain also covers subdomains that have no record of their own.

The DNS changes below are each reversible by editing or deleting the record, but they affect how every message from the domain is judged. Change one thing at a time and keep a note of the old value.

The checks that follow only read public DNS, so they need no special rights. Run them from PowerShell on any Windows PC and replace YOUR_DOMAIN with your own domain, for example yourcompany.co.uk.

  • Access to the DNS records for the domain. If an agency or IT supplier manages them, give them the values from this guide and ask them to make the change.
  • A Microsoft 365 administrator account that can open Email authentication settings in the Microsoft Defender portal, for the DKIM step.
  • The domain already added and verified in Microsoft 365. Microsoft only lets a custom domain sign mail once that is done.
  • A list of everything that sends email using your domain as the From address: Microsoft 365 mailboxes, but also accounting or invoicing software, a CRM, website contact forms, marketing platforms, scanners and any on-premises mail server. This is the part that takes the time, so ask each department.
  1. Check for an existing SPF record. You should see either nothing or exactly one line beginning v=spf1. If one exists, you will edit it later, not add a second.
    powershell
    Resolve-DnsName -Name YOUR_DOMAIN -Type TXT | Select-Object -ExpandProperty Strings
  2. Check for an existing DMARC record. An error saying the name does not exist means none is published yet.
    powershell
    Resolve-DnsName -Name "_dmarc.YOUR_DOMAIN" -Type TXT | Select-Object -ExpandProperty Strings
  3. Check for existing DKIM records. Before setup these normally return nothing. After the DKIM section below, both should return a target name.
    cmd
    nslookup -type=CNAME selector1._domainkey.YOUR_DOMAIN
    nslookup -type=CNAME selector2._domainkey.YOUR_DOMAIN

Publish your SPF record

An SPF record is a single TXT record on the domain itself. When Microsoft 365 is your only sender, Microsoft's record for the standard commercial cloud is the one shown below. Each domain or subdomain may have only one SPF record. A second one makes SPF return a permanent error, so always edit the existing record.

Receivers will follow no more than 10 DNS lookups while evaluating SPF. Every include: counts, and so do nested includes inside the vendor's own record, which means fewer than 10 includes does not guarantee you are under the limit. Individual ip4: and ip6: entries cost nothing. Do not replace Microsoft's include with fixed IP addresses, because Microsoft says its sending addresses change frequently.

  1. At your DNS host, find the TXT record on the domain itself that starts with v=spf1. Many DNS hosts use @ for the domain itself, but check how yours labels it. If there is none, create one.
  2. Set the value to the record below if Microsoft 365 is your only sender.
    text
    v=spf1 include:spf.protection.outlook.com -all
  3. If other systems send as your domain, add their entries before the ending, exactly as each vendor documents them (usually an include: value, sometimes ip4: addresses for a server you run). The example shows an on-premises server alongside Microsoft 365, using a documentation-range address. For a service you do not control, such as a bulk mailer, Microsoft recommends sending from a subdomain with its own record, so that its problems do not damage the reputation of your main domain.
    text
    v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com -all
  4. Choose the ending. Microsoft recommends -all (reject anything not listed) when you also use DKIM and DMARC. If you are not yet confident you have found every sender, our suggestion is to publish ~all (accept but mark) first and move to -all when the DMARC reports show no surprises. A ~all failure is still an SPF failure to DMARC, but its policy is effectively ignored when the message has no DKIM signature, which is one more reason to complete the DKIM step.
  5. Set the TTL, the time resolvers may cache the record, to at least 3600 seconds (one hour), as Microsoft advises, and save. Run the SPF check from the previous section again. It should now show your new record.

Turn on DKIM signing for your domain

Until you do this, mail from your custom domain carries no DKIM signature from that domain, so DKIM cannot help DMARC. The signing keys live with Microsoft. You publish two CNAME records, which are DNS aliases pointing at Microsoft's copies of the matching public keys. Those two records are called selectors. Only one is used at a time. The other is needed when the keys are rotated, so create both.

The values you publish are specific to your tenant and domain. Copy them from the portal. Do not build them by hand and do not copy examples from other websites, because the target includes a character Microsoft assigns, and domains added since May 2025 use a different target format from older ones.

Turning DKIM off again is a single switch in the same place, so this step is easy to back out if something unexpected happens.

  1. Sign in to the Microsoft Defender portal at security.microsoft.com. Go to Email & collaboration, then Policies & rules, then Threat policies, then Email authentication settings. Select the DKIM tab. The direct address is security.microsoft.com/authentication.
  2. Find your domain in the list. Before setup it normally shows Status NoDKIMKeys and the Toggle Disabled. Try switching the Toggle to Enabled. A Client error dialog appears listing the CNAME values you need. That is expected here, because the records do not exist yet. Select OK. The Status should now read CnameMissing.
  3. Select the domain's row, avoiding the checkbox and the toggle, to open its details flyout. In the Publish CNAMEs section, note both records or use Copy.
  4. At your DNS host, create two records of type CNAME (not TXT). The host names are selector1._domainkey and selector2._domainkey, and the targets are the values you copied. In the host name field enter only that short name, because most DNS hosts add your domain automatically, and a doubled domain is the most common reason this step fails. Use a TTL of at least one hour. If you use Cloudflare, set both records to DNS only so the proxy is off, and if you use Amazon Route 53, include the trailing dot on the target.
  5. Check that both aliases resolve. Microsoft says it can take a few minutes, or possibly longer, for Microsoft 365 to detect new records, so this is a good moment to carry on with something else.
    cmd
    nslookup -type=CNAME selector1._domainkey.YOUR_DOMAIN
    nslookup -type=CNAME selector2._domainkey.YOUR_DOMAIN
  6. Go back to the details flyout and switch on Sign messages for this domain with DKIM signatures. A dialog warns it may take several minutes to synchronise. Select OK. When it has worked, the toggle shows Enabled and the Status reads Signing DKIM signatures for this domain.
  7. Optionally, confirm from Exchange Online PowerShell. Connect with an administrator account, then run this read-only command. Your domain should show Enabled as True and Status as Valid.
    powershell
    Get-DkimSigningConfig | Format-List Name,Enabled,Status,Selector1CNAME,Selector2CNAME

Add a DMARC record that only watches

DMARC passes when SPF or DKIM passes and the domain it passed for matches the domain in the visible From address. That matching is called alignment. It is the reason a service that sends as you can pass SPF and DKIM in its own name yet still fail DMARC: the checks passed, but for someone else's domain.

A policy of p=none asks receivers to take no action on failures. It changes nothing about delivery. What it does is ask them to send aggregate reports, daily summaries showing which servers sent mail as your domain and whether it passed. For the first stage you only need these. Forensic reports add volume, and Microsoft 365 does not send them anyway.

The reports arrive as compressed XML attachments, which is a generous definition of report. A handful of messages is readable by eye. Beyond that, a DMARC reporting service turns them into something a person can use, and Microsoft's partner catalogue lists several. Reports should go to a dedicated mailbox or Microsoft 365 group, not to someone's personal inbox.

  1. Create a dedicated mailbox or Microsoft 365 group in your domain to receive reports, for example with a name like dmarc-reports. If the address will be on a different domain, that domain must publish an authorisation record before receivers will send reports to it.
  2. At your DNS host, create a TXT record with the host name _dmarc and the value below. Replace YOUR_REPORTS_ADDRESS with the address from step 1. If your DNS host already has a record there, edit it instead of adding another.
    text
    v=DMARC1; p=none; rua=mailto:YOUR_REPORTS_ADDRESS
  3. Run the DMARC check from the earlier section. It should return the record you published.
  4. Leave the policy at none long enough to see your genuine mail patterns, which in our judgement means at least one full business cycle, such as month-end invoicing runs. Check the reports for every system on your sender list. Any source you did not expect, or any known sender showing as failing, needs fixing at that service first. Usually that means having it sign with DKIM using your domain or send using your domain in the envelope sender.

Check that it worked

The reports tell you what receivers saw over time. A single test message tells you right now whether the three pieces are working together.

  1. From a mailbox in your domain, send a message to a mailbox you control on a different email system, such as a personal webmail account. Do not use AOL for DKIM testing, as Microsoft notes it may skip the DKIM check. A recipient in your own organisation will show no DKIM signature, because Microsoft does not sign mail between addresses in the same organisation.
  2. Open the full message headers in the receiving mailbox. Most mail programmes have a show-original or view-source option, though the label varies. Microsoft's Message Header Analyzer can also make them easier to read.
  3. Find the DKIM-Signature header. Its d= value should be your domain, and s= should name one of your two selectors. Then find Authentication-Results. Exact formatting differs between providers, but it should show spf=pass, dkim=pass and dmarc=pass.
  4. Repeat the test from every other system on your sender list, such as an invoice from the accounting package or a website form notification. Each one takes its own route, so each needs its own check.
  5. After a day or two, look in the reports mailbox for the first aggregate reports. Mail from Microsoft 365 should appear as passing. Not every receiver sends reports, so absence from a particular provider is not a fault.

Tightening DMARC to quarantine and then reject

Moving beyond p=none is what actually stops other people spoofing your domain. It is also the point where a sender you forgot starts losing mail. Do it only once the reports show that every legitimate source passes with alignment. Microsoft also notes that outbound mail from your domain that fails DMARC at the destination is routed through its high-risk delivery pool when your policy is quarantine or reject, with no override, so mistakes are felt quickly.

Microsoft suggests stepping up the percentage of failing mail the policy applies to, for example 10, 25, 50, 75 and 100, using the pct tag. The NCSC guidance says many organisations report being able to move from quarantine to reject after about three months, and advises watching reports closely for at least two weeks after reject. Treat those as reference points. Your own reports decide the timing.

Rolling back is a DNS edit, so it is not instant. Receivers may keep the old record until its TTL expires, so allow for that.

  1. Edit the existing _dmarc TXT record, not adding a second, to start with quarantine applied to a small share of failing mail.
    text
    v=DMARC1; p=quarantine; pct=10; rua=mailto:YOUR_REPORTS_ADDRESS
  2. Watch the reports and ask staff and key suppliers whether mail has gone missing. Raise pct in stages. At each stage, wait long enough to see the effect in the reports.
  3. When quarantine at pct=100 has run cleanly, change the policy to reject. Keep reading the reports closely for at least the next two weeks.
    text
    v=DMARC1; p=reject; pct=100; rua=mailto:YOUR_REPORTS_ADDRESS
  4. If legitimate mail is being caught, set the policy back to the previous value at once, then fix the sending service before trying again.

Domains you own but never send mail from

Parked domains are easy to spoof precisely because nobody is watching them. Microsoft recommends telling the world that no mail should ever come from them. Publish the two records below at the DNS host for each such domain. Do not publish DKIM records for them. The absence of a public key stops forged signatures from validating.

If you do not use your yourtenant.onmicrosoft.com address for email, Microsoft also advises publishing a DMARC record for it. In the Microsoft 365 admin center that is under Settings, then Domains, where you select the onmicrosoft.com domain, open the DNS records tab and add a TXT record named _dmarc. Microsoft's example value is v=DMARC1; p=reject.

text
Type: TXT   Host: the domain itself   Value: v=spf1 -all
Type: TXT   Host: _dmarc               Value: v=DMARC1; p=reject;

If something does not work

Most failures come from a small set of DNS slips. Work through the one that matches what you see.

  • DKIM stays on CnameMissing after a reasonable wait: check that the host name is only selector1._domainkey or selector2._domainkey with no domain added, that both records are CNAME and not TXT, that the targets match the portal exactly and that any DNS proxy is switched off.
  • SPF shows permerror: look for two SPF records on the same domain, more than 10 DNS lookups once nested includes are counted, or a syntax slip such as a trailing full stop after a domain, an equals sign instead of a colon after include, or a space after the colon.
  • SPF and DKIM both pass but DMARC fails: this is an alignment failure. Typically a third-party service uses its own domain for the envelope sender and for DKIM. Have the service sign with your domain, or send that mail from a subdomain with its own records.
  • A test message to someone inside your organisation shows dkim=none: this is expected. Test with an outside mailbox.
  • Forwarded mail fails at the destination: forwarding breaks SPF because the forwarding server is not in your record. DKIM survives forwarding if the message body is not modified, which is another reason to have it switched on.
  • No reports arrive: confirm the reports address really exists and can receive external mail, that the record is published at _dmarc with the correct spelling and that the DNS publication check returns it. Give it a day or two, and remember not every receiver sends reports. An address on a different domain needs that domain to publish an authorisation record.
Technical terms explained
aggregate reports
Daily summaries sent by receiving mail systems to the address in your DMARC record, showing which servers sent mail as your domain and whether it passed.
alignment
The requirement that the domain verified by SPF or DKIM matches the domain in the visible From address. DMARC needs at least one aligned pass.
DKIM
DomainKeys Identified Mail. A digital signature added to outgoing mail, which receivers verify with a public key in DNS to confirm the message was signed by that domain and not altered.
DMARC
A DNS policy that requires SPF or DKIM to pass for a domain matching the From address, says what receivers should do on failure and where to send reports.
SPF
Sender Policy Framework. A DNS record listing the servers allowed to send mail for a domain. Receivers check the sending server against it.
TTL
Time to live. How long, in seconds, resolvers may cache a DNS record before checking again. It affects how quickly a change or rollback takes effect.

Sources and further reading

KEEP THE CONVERSATION GOING

Not sure who sends mail as your domain?

If you would rather not edit DNS yourself, or the reports show senders you cannot identify, tell us about your setup and we can help you work through it.

Talk to us