9.6 Email Authentication: SPF, DKIM, DMARC

90 minutes · Module 9

Email Authentication: SPF, DKIM, DMARC

By the end of this subsection, you will understand what each email authentication protocol verifies, know why passing authentication does not mean the email is safe, and be able to configure DMARC for your domain.

The three protocols

ProtocolWhat it verifiesWhat it does NOT verify
SPF (Sender Policy Framework)The sending server IP is authorized for the domain in the envelope From addressThat the domain is legitimate or trustworthy
DKIM (DomainKeys Identified Mail)The email was not modified in transit (cryptographic signature on headers and body)That the signer is trustworthy
DMARC (Domain-based Message Authentication, Reporting, and Conformance)SPF or DKIM passes AND the domain aligns with the header From addressThat the content is safe
Authentication verifies origin, not safety

In Module 14, the AiTM phishing email passed SPF, DKIM, and DMARC — because the attacker owned the sending domain (northgate-voicemail.com) and configured authentication correctly. It takes 5 minutes to set up SPF and DKIM for a new domain. Authentication tells you "this email really came from northgate-voicemail.com." It does not tell you "northgate-voicemail.com is trustworthy." Never dismiss a suspicious email because authentication passed.

Configuring DMARC for your domain

DMARC protects YOUR domain from being spoofed by others. It tells receiving mail servers what to do when someone sends email claiming to be from your domain but fails SPF/DKIM alignment.

DMARC policy levels:

PolicyDNS recordWhat happens to failing emailsDeploy when
None (monitoring)v=DMARC1; p=none; rua=mailto:dmarc@northgateeng.comNothing — reports onlyStart here. Collect data for 30 days.
Quarantinev=DMARC1; p=quarantine; rua=mailto:dmarc@northgateeng.comFailing emails go to JunkAfter confirming all legitimate senders pass alignment
Rejectv=DMARC1; p=reject; rua=mailto:dmarc@northgateeng.comFailing emails are rejected (not delivered)After quarantine runs clean for 30+ days
Do NOT deploy DMARC reject without monitoring first

If you have third-party services sending email on behalf of your domain (marketing platforms, CRM, ticketing systems) and they are not configured in your SPF record, DMARC reject will block their emails. Start with p=none, analyze the DMARC reports, add all legitimate senders to SPF, then move to quarantine, then reject.

Common DMARC deployment mistakes

MistakeConsequenceHow to avoid
Deploying p=reject without monitoringLegitimate third-party email blocked (marketing, CRM, support)Always start with p=none for 30 days of data
SPF record exceeds 10 DNS lookupsSPF fails for all email from your domainConsolidate include statements, use SPF flattening services
No DKIM for third-party sendersDMARC fails on alignment even though SPF passesConfigure DKIM signing with your domain for each third-party service
Not monitoring DMARC reports after deploymentNew services added without SPF/DKIM break silentlyReview DMARC reports monthly, automate with a DMARC monitoring service
Forgetting subdomain policyAttackers spoof subdomains (hr.yourdomain.com)Add sp=reject to your DMARC record for subdomain policy

Analyzing authentication results with KQL

1
2
3
4
5
6
7
EmailEvents
| where TimeGenerated > ago(7d)
| where SenderFromDomain != SenderMailFromDomain
| project TimeGenerated, SenderFromAddress, SenderMailFromAddress,
    SenderFromDomain, SenderMailFromDomain,
    AuthenticationDetails, Subject
| take 20
Expected Output
SenderFromAddressSenderMailFromAddressAuth (summary)
ceo@northgateeng.combounce@marketing-platform.comSPF: pass (marketing-platform.com), DKIM: pass, DMARC: fail (domain mismatch)
hr@northgateeng.comnoreply@attacker-domain.comSPF: pass (attacker-domain.com), DKIM: none, DMARC: fail
What to look for: Row 1: your marketing platform sends "from" ceo@northgateeng.com but the envelope sender is the platform. DMARC fails because the domains do not align. This is legitimate — add the platform to SPF and configure DKIM signing with your domain. Row 2: an attacker spoofing hr@northgateeng.com from their own domain. DMARC catches this — with a reject policy, this email would never reach your users.

Practical DMARC deployment timeline

WeekActionVerification
1Add DMARC TXT record with p=none and rua reportingnslookup -type=txt _dmarc.yourdomain.com returns your record
2-4Analyze DMARC reports (use a free service like dmarcanalyzer.com or EasyDMARC)Identify all legitimate senders
5Add all legitimate senders to SPF record. Configure DKIM signing for third-party services.SPF lookup confirms all senders authorized
6-8Change to p=quarantineMonitor Junk folder for false positives
9-12If quarantine is clean, change to p=rejectExternal spoofing of your domain is now blocked

Required role and blast radius

Required role: Exchange Administrator (for DKIM signing configuration). DNS Administrator (for SPF/DKIM/DMARC record changes). These are typically different people — coordinate.


SPF — practical implementation

SPF tells receiving mail servers which IPs are authorised to send email for your domain. The receiving server checks: did this email come from an IP listed in the domain’s SPF record?

Your SPF record: Check current: nslookup -type=txt northgateeng.com (or use MXToolbox). A typical M365-only SPF record: v=spf1 include:spf.protection.outlook.com -all.

Common additions for M365 environments:

  • Third-party email marketing (Mailchimp): add include:servers.mcsv.net
  • CRM (Salesforce): add include:_spf.salesforce.com
  • Helpdesk (Zendesk): add include:mail.zendesk.com
  • Transactional email (SendGrid): add include:sendgrid.net

The 10-lookup limit. SPF allows a maximum of 10 DNS lookups. Each include: counts as 1+ lookups (the included record may itself contain includes). Exceeding 10 causes SPF permerror — your email fails authentication. Monitor your lookup count as you add senders. If you approach 10: use IP addresses directly (ip4:203.0.113.0/24) instead of includes, or use an SPF flattening service.

Blast radius of SPF changes: If misconfigured: email from your domain fails SPF checks. Receiving servers may reject or junk your outbound email. Test changes by adding senders incrementally and monitoring delivery.

Rollback: Revert the DNS TXT record to the previous version. DNS propagation takes 5-60 minutes.

DKIM — practical implementation

DKIM adds a cryptographic signature to outbound email. The receiving server verifies the signature against the public key in your DNS — confirming the email was not modified in transit and genuinely originated from your infrastructure.

Enable DKIM for M365: Navigate to Defender → Email & collaboration → Policies → DKIM. Select your domain. Enable DKIM signing. M365 generates the key pair and provides the CNAME records to add to DNS.

Verify: After adding DNS records and enabling: send a test email to an external account. Check the email headers for dkim=pass.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Monitor DKIM pass/fail rates for your outbound email
EmailEvents
| where TimeGenerated > ago(30d)
| where SenderFromDomain == "northgateeng.com"
| extend AuthDetails = parse_json(AuthenticationDetails)
| extend DKIMResult = tostring(AuthDetails.DKIM)
| summarize
    Total = count(),
    DKIMPass = countif(DKIMResult == "pass"),
    DKIMFail = countif(DKIMResult == "fail"),
    DKIMNone = countif(DKIMResult == "none" or isempty(DKIMResult))
    by bin(TimeGenerated, 7d)

Target: 100% DKIMPass for email sent through M365. DKIMFail indicates a configuration issue (key mismatch, DNS record incorrect). DKIMNone indicates email sent through a system that is not DKIM-signed (a third-party sender not configured for DKIM with your domain).

DMARC — the enforcement layer

DMARC tells receiving servers what to do when email fails both SPF and DKIM. Without DMARC: the receiving server decides (usually delivers to junk or delivers normally). With DMARC at p=reject: the receiving server blocks the email entirely.

DMARC deployment path:

Month 1: v=DMARC1; p=none; rua=mailto:dmarc-reports@northgateeng.com. Monitor-only. Collect aggregate reports showing who sends email using your domain. Identify legitimate senders not covered by SPF/DKIM.

Month 2-3: Fix any legitimate senders failing DMARC (add to SPF, enable DKIM). Re-review aggregate reports: are all legitimate senders passing?

Month 4: p=quarantine. Failing email goes to junk. Monitor for reports of missing legitimate email.

Month 6: p=reject. Failing email is blocked entirely. Your domain is now protected against spoofing.

Do not skip to p=reject on day one. Legitimate email that fails DMARC (a marketing platform not yet added to SPF) will be silently blocked. The monitor period identifies these senders before enforcement breaks business communication.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Check inbound DMARC results for email claiming to be from your domain
EmailEvents
| where TimeGenerated > ago(30d)
| where SenderFromDomain == "northgateeng.com"
| extend AuthDetails = parse_json(AuthenticationDetails)
| extend DMARCResult = tostring(AuthDetails.DMARC)
| extend CompAuth = tostring(AuthDetails.CompAuth)
| where DMARCResult != "pass"
| project TimeGenerated, SenderFromAddress, SenderIPv4,
    DMARCResult, CompAuth, Subject

Any email claiming to be from your domain that fails DMARC is either: a legitimate sender misconfigured (fix the SPF/DKIM), or an attacker spoofing your domain (the exact attack DMARC prevents once at p=reject).

Compliance mapping

NIST CSF: PR.DS-5 (Protections against data leaks). ISO 27001: A.8.12 (Data leakage prevention). SOC 2: CC6.7 (Restrict transmission of data). UK Government Cyber Essentials: SPF, DKIM, and DMARC at p=quarantine or p=reject are required. Email authentication is one of the most frequently audited controls.


Common SPF/DKIM/DMARC troubleshooting

Problem: SPF PermError. Your SPF record exceeds 10 DNS lookups. Symptoms: some recipients reject your email, others junk it.

Diagnosis: nslookup -type=txt northgateeng.com — count each include: and recursively count their includes. Or use MXToolbox SPF record checker.

Fix: Replace include: directives with direct IP addresses where possible. Or use an SPF flattening service (these resolve all includes into a flat list of IPs and maintain the record automatically).

Problem: DKIM failing for third-party senders. Your marketing platform sends email “from” your domain but the DKIM signature uses their domain, not yours.

Fix: Configure the third-party platform to sign with your domain’s DKIM key. Most platforms support this: upload your DKIM public key to their configuration, or delegate a subdomain (e.g., em.northgateeng.com) and configure DKIM for the subdomain.

Problem: DMARC reports show legitimate senders failing. You moved to p=quarantine and a vendor’s email is being junked.

Fix: Add the vendor’s sending IPs to your SPF record, or configure the vendor to sign with DKIM using your domain or a DMARC-aligned domain. Do NOT move back to p=none — instead, fix the alignment for the specific sender while maintaining enforcement for everyone else.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// DMARC failure investigation: who is failing authentication?
EmailEvents
| where TimeGenerated > ago(7d)
| where SenderFromDomain == "northgateeng.com"
| extend AuthDetails = parse_json(AuthenticationDetails)
| extend SPF = tostring(AuthDetails.SPF)
| extend DKIM = tostring(AuthDetails.DKIM)
| extend DMARC = tostring(AuthDetails.DMARC)
| where DMARC != "pass"
| summarize
    FailCount = count(),
    SenderIPs = make_set(SenderIPv4, 10)
    by SenderFromAddress, SPF, DKIM, DMARC
| order by FailCount desc

This query identifies exactly which senders are failing DMARC and why (SPF fail, DKIM fail, or both). Use the SenderIPs to identify the sending system — then fix its SPF or DKIM configuration.


The business case for email authentication

SPF, DKIM, and DMARC are not just security controls — they are business reputation controls.

Without DMARC enforcement: Anyone can send email that appears to come from your domain. Attackers use this for: phishing your partners (they receive email “from” you with malicious content), BEC against your customers (they receive invoice changes “from” your domain), and brand damage (your domain appears in spam campaigns).

With DMARC at p=reject: Only authorised senders can send email using your domain. Spoofed email is blocked by the recipient’s mail server before delivery. Your domain reputation is protected.

The cost of NOT implementing DMARC: If your domain is spoofed in a phishing campaign targeting your customers, the reputational damage is significant — customers lose trust in email from your domain. Additionally, email deliverability degrades: major email providers (Google, Microsoft) increasingly penalise domains without DMARC enforcement by routing their email to junk.

UK government requirement: The UK National Cyber Security Centre (NCSC) recommends DMARC at p=quarantine or p=reject for all UK organisations. Government departments and their suppliers are increasingly required to have DMARC enforcement. Cyber Essentials Plus certification requires email authentication controls.

DMARC aggregate report analysis

DMARC aggregate reports arrive daily (or weekly, depending on the ri= tag in your DMARC record). Each report is an XML file from a receiving mail server showing: how many emails it received claiming to be from your domain, whether SPF and DKIM passed or failed for each, and what action it took (delivered, quarantined, rejected).

Manual analysis is impractical — you may receive 10-50 reports per day from different mail servers. Use a DMARC analysis service: dmarcian, Valimail, Agari, or PowerDMARC. These services aggregate reports into dashboards showing: total sending volume per source, pass/fail rates, and unauthenticated senders.

Free option: Parse reports with PowerShell or Python. Microsoft does not provide a built-in DMARC report analyser. The open-source tool parsedmarc converts XML reports into human-readable format.

What to look for in DMARC reports:

Legitimate senders failing authentication → fix their SPF/DKIM alignment. Unknown senders passing authentication → investigate (a compromised account or an authorised sender you forgot about). Unknown senders failing authentication → these are spoofing attempts that DMARC enforcement blocks. The volume and origin of these attempts informs your threat model.

Try it yourself

Check your test tenant's email authentication: (1) Look up your SPF record using MXToolbox. How many DNS lookups does it use? (2) Check DKIM signing status in the Defender portal. Is DKIM enabled for your domain? (3) Check your DMARC record: `nslookup -type=txt _dmarc.yourdomain.com`. What policy is set (none/quarantine/reject)? If any of these are missing or misconfigured: you have identified a production-ready hardening action.

A well-configured M365 tenant should have: SPF with `include:spf.protection.outlook.com -all` (under 10 lookups), DKIM enabled and signing (green status in Defender portal), and DMARC at `p=quarantine` or `p=reject` with a reporting address. Common gaps: DMARC at `p=none` (no enforcement), DKIM not enabled (default in some configurations), SPF with `~all` instead of `-all` (soft fail instead of hard fail).

Try it yourself

Your DMARC report shows that your marketing platform (Mailchimp) is failing DMARC alignment because it sends from its own servers but uses your domain in the From address. How do you fix this without disabling DMARC?

Two fixes (use both for maximum protection):

1. Add Mailchimp to your SPF record: Include include:servers.mcsv.net in your SPF TXT record. This authorizes Mailchimp's servers to send on behalf of your domain.

2. Configure DKIM signing with your domain: In Mailchimp settings, set up DKIM to sign emails with your domain's DKIM key (create a CNAME record for Mailchimp's DKIM selector pointing to your DNS). This makes Mailchimp emails pass DKIM alignment.

With both fixes, Mailchimp emails pass both SPF and DKIM alignment — DMARC succeeds. Without these fixes, moving to p=reject would block all your marketing emails.

Check your understanding

1. A phishing email passes SPF, DKIM, and DMARC. Is it safe?

No. Email authentication verifies that the email came from the claimed domain's authorized infrastructure. The attacker owns the domain and configured authentication correctly. Passing authentication means "this email is really from attacker-domain.com" — it does not mean "attacker-domain.com is trustworthy."
Yes — all three protocols passed
Only if DMARC is set to reject