SPF, DKIM and DMARC: The Complete Email Authentication Stack
SPF, DKIM and DMARC are three separate standards that solve three different parts of the same problem. They make sense individually but they only become powerful together. This is the start-to-finish playbook for deploying all three.
Why all three?
Each protocol authenticates a different identity:
- SPF authenticates the envelope-sender (the address in the SMTP
MAIL FROM). - DKIM authenticates the signing domain (the
d=tag of the signature). - DMARC requires one of those to align with the visible
From:header that the user sees.
SPF and DKIM on their own are about who sent the message. DMARC adds the crucial constraint that the visible identity must match what was authenticated. Without DMARC, an attacker can satisfy SPF and DKIM for a domain they own and still spoof the visible From of yours.
The setup order that works
The order is non-obvious and getting it wrong will silently break legitimate mail.
Step 1: inventory every sender
Before touching DNS, list every system that sends email under your domain. Typical sources:
- Your transactional MTA (Postfix, Exim, PowerMTA).
- Your office mail provider (Google Workspace, Microsoft 365).
- Marketing ESP (Mailchimp, Sendinblue, Klaviyo).
- SaaS that send notifications (Salesforce, Zendesk, Stripe).
- CI/CD systems that send build alerts.
- Calendar and meeting tools (Calendly, etc.).
Anyone you forget will fail authentication once you tighten DMARC.
Step 2: deploy SPF with -all
For each sender, look up the SPF include or IP list it requires. Combine them into a single SPF record at the apex of your domain. See our SPF guide for syntax. Watch the 10-lookup limit.
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ip4:192.0.2.10 -all"
Step 3: deploy DKIM at every sender
For your own MTA, generate a key pair and publish the public key (see our DKIM guide). For each third-party sender, follow their docs — they usually give you a CNAME to publish that points at their key.
Critical: make sure each DKIM signature uses your domain in the d= tag, not the sender's. This is what enables DMARC alignment. Mailchimp, SendGrid and the rest all let you configure this; it's sometimes called "branded sending domain" or "domain authentication" in their UI.
Step 4: publish DMARC at p=none
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1"
Start with p=none — no enforcement. Send the aggregate reports to a mailbox you actually read, or to a service like dmarcian or Postmark's free DMARC monitor.
Step 5: read the reports for two weeks
You will see, for the first time, the complete list of senders that use your domain. For each:
- Authorised and aligned — do nothing.
- Authorised but failing — configure DKIM at the sender, or add to SPF.
- Unknown — investigate. Often a forgotten SaaS. Sometimes outright forgery.
Step 6: ramp DMARC enforcement
Once your reports show only authorised senders aligning, ramp the policy:
p=quarantine; pct=10— 10% of failing mail goes to spam.p=quarantine; pct=50p=quarantine; pct=100p=reject; pct=10p=reject; pct=100
Each step should be at least 3–5 days apart so that a full reporting cycle catches any new failures.
Step 7: tighten alignment (optional)
If you don't have a legitimate reason to use subdomain mismatch, switch to strict alignment by adding adkim=s; aspf=s to your DMARC record. Most organisations should leave this on relaxed.
Testing the chain end-to-end
The single fastest way to verify your setup works is to send a test message to a Gmail account and inspect the original. Look for these three lines in the Authentication-Results header:
spf=pass smtp.mailfrom=bounce@example.com
dkim=pass header.i=@example.com header.s=s1
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
All three should be pass. The DKIM and SPF domains must match the From domain (relaxed) for DMARC to pass.
Test from each sending source
Don't just test from your transactional MTA — test every system in your inventory. Send one message from your CRM, one from your marketing ESP, one from your calendar tool, etc. Each must produce dmarc=pass independently. The single most common failure mode is one forgotten sender that appears to be aligned in the report aggregate but actually isn't.
Tools we use for the audit
- mail-tester.com — one-off send-and-score, includes full SPF/DKIM/DMARC analysis.
- MXToolbox SuperTool — ad-hoc DNS, SPF, DKIM, DMARC lookups.
- Postmark DMARC monitor — free weekly digest of aggregate reports.
- dmarcian — commercial, the gold standard for multi-domain orgs.
- EasyDMARC — another commercial option with good unknown-sender detection.
Common gotchas
- Subdomain SPF. Each subdomain that sends mail needs its own SPF record. The apex SPF doesn't apply.
- Multiple SPF records. Two
v=spf1records on the same name = automaticpermerror. Merge them. - SPF over the 10-lookup limit. Flatten or remove unused includes.
- DKIM key not propagated. Wait at least an hour after publishing before you start signing — receivers cache negative DNS results.
- DMARC at p=reject without DKIM. SPF breaks on forwarding; DKIM doesn't. Without DKIM your forwarded mail will be rejected.
- Bounce address mismatched. If your envelope-from is on a subdomain you forgot to authorise in SPF, alignment fails even though everything looks right.
- Sender uses their own bounce domain. Common with ESPs — they set Return-Path to a domain like
bounces.sendgrid.net. SPF will pass for that domain but won't align with your From. You need DKIM alignment instead.
What "done" looks like
A correctly configured authentication stack has these properties:
- Single, valid SPF record at the apex with
-all. - Each sending source produces a DKIM signature with
d=yourdomain.com. - DMARC at
p=reject, withrua=reporting to a mailbox you monitor. - DMARC aggregate reports show 99%+ of mail aligning (the remaining are forwarders and edge cases).
- Test messages to Gmail, Outlook and Yahoo all produce
dmarc=pass.
Once you reach that state, your domain is as well-protected as the standards allow. The next levels — BIMI, ARC, MTA-STS, TLS-RPT — build on top of this foundation but assume it's in place.