You're integrating SendGrid, Postmark, or Amazon SES. The docs say: "Add these DNS records for DKIM and SPF. Configure DMARC." You copy-paste the records, wait for propagation, and hope for the best.
That's how most developers handle email authentication. Here's what's actually happening under the hood — and how to verify it's working.
Why Email Authentication Exists
SMTP was designed in 1982 (RFC 821). The protocol has no built-in sender verification. Anyone can connect to an SMTP server and claim to be ceo@yourcompany.com. SPF, DKIM, and DMARC are three independent standards bolted onto SMTP to fix this gap. Each solves a different piece of the puzzle.
SPF — Who Is Allowed to Send
Sender Policy Framework (RFC 7208) is a DNS TXT record that lists which IP addresses and servers are authorized to send email for your domain.
A typical SPF record:
v=spf1 include:_spf.google.com include:sendgrid.net -all
This says: "Google's mail servers and SendGrid can send on our behalf. Reject everything else (-all)."
Common mistakes:
- The 10-lookup limit. SPF allows a maximum of 10 DNS lookups. Each
include:counts as one, and nested includes count too. Exceed 10 and SPF fails silently — apermerrorresult that most developers never notice. ~allvs-all. Tilde (~) is a soft fail — receivers note it but don't reject. Dash (-) is a hard fail — unauthorized senders are rejected. Use-allin production.- Forgetting to add your email service. You add SendGrid but forget that your app server also sends directly via localhost SMTP. Those emails fail SPF.
DKIM — The Message Wasn't Tampered With
DomainKeys Identified Mail (RFC 6376) adds a cryptographic signature to outgoing emails. The sending server signs specific headers and the body with a private key. The public key is published in DNS so receivers can verify the signature.
The DNS record looks like:
selector._domainkey.example.com TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."
The email header contains:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector;
h=from:to:subject:date:message-id;
bh=abc123...;
b=xyz789...
What to watch for:
- Key rotation. If you rotate your DKIM key pair but don't update the DNS record, all signatures will fail verification.
- Mailing lists and forwarders. Some mailing lists modify headers or body content, breaking the DKIM signature. This is a known issue with no perfect fix — it's one of the reasons DMARC's
p=nonepolicy exists.
DMARC — What to Do When SPF or DKIM Fails
Domain-based Message Authentication, Reporting, and Conformance (RFC 7489) ties SPF and DKIM together. It tells receiving servers what to do when authentication fails and where to send reports.
_dmarc.example.com TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s"
The three policy levels:
p=none— Monitor only. Failures are reported but mail is delivered normally. Start here.p=quarantine— Failures go to spam. Move here after monitoring shows few false positives.p=reject— Failures are dropped entirely. The end goal for maximum protection.
The alignment requirement: DMARC requires that the domain in the From: header aligns with the domain checked by SPF or DKIM. If your From: is noreply@app.com but SPF checks sendgrid.net, SPF passes but DMARC alignment fails.
How to Inspect Authentication Headers
Every email carries the authentication results in its headers. Here's what to look for:
Authentication-Results: mx.google.com;
dkim=pass header.d=example.com header.s=selector;
spf=pass (google.com: domain of bounce@example.com) smtp.mailfrom=bounce@example.com;
dmarc=pass (p=REJECT) header.from=example.com
Capturing a test email with MailHog lets you inspect these headers without sending to a real inbox. The headers inspector shows every header formatted for easy reading — including the full Authentication-Results chain.
The First-24-Hours Deployment Plan
- Publish your SPF record with all authorized senders and
~all(soft fail initially) - Generate DKIM key pair through your email provider and publish the DNS TXT record
- Add a DMARC record with
p=noneand arua=reporting address - Send test emails through your SMTP sandbox and verify all three pass
- Monitor DMARC reports for 1-2 weeks — look for legitimate senders you missed in SPF
- Tighten SPF to
-all(hard fail) - Move DMARC to
p=quarantine, monitor for another week - Advance to
p=rejectwhen confident
FAQ
Do I need all three — SPF, DKIM, and DMARC?
Yes. Each solves a different problem. SPF authorizes senders, DKIM proves message integrity, and DMARC tells receivers what to do about failures. Major providers like Gmail and Microsoft require all three for optimal deliverability.
What happens if I exceed the SPF 10-lookup limit?
SPF evaluation returns a permerror result, which most receivers treat as a failure. Your emails may be rejected or sent to spam. Use an SPF flattening tool to inline the IP addresses, or consolidate your sending services.
Can I test DKIM and SPF without sending to a real inbox?
Yes. Point your app at an SMTP testing service like MailHog.site, trigger a test email, and inspect the captured headers. You'll see exactly whether DKIM and SPF pass before any email reaches a real recipient.
What's the difference between SPF soft fail and hard fail?
~all (soft fail) tells receivers that unauthorized senders should be treated with suspicion but not rejected outright. -all (hard fail) tells receivers to reject unauthorized senders. Start with soft fail during setup, then switch to hard fail once you've confirmed all legitimate senders are included.