SPF, DKIM, DMARC: how email proves it isn't forged
Plain SMTP will happily let you type MAIL FROM:<[email protected]>, then a From: CEO <[email protected]> header, from any machine, with no proof you have anything to do with that bank. The protocol dates to 1982, when the hosts on the wire trusted each other, and the From your client shows is just text the sender wrote. SPF, DKIM, and DMARC are three layers published in DNS and bolted on later to make that forgery detectable. None of them changes SMTP itself.
Two different From addresses
The single most useful thing to understand is that an email carries two sender addresses, and they need not match. The envelope from (RFC5321.MailFrom, set by the MAIL FROM command) is what servers use to route mail and send bounces. The header from (RFC5322.From) is the line your mail client displays. A mailing list, a newsletter platform, or a phisher can put one address in the envelope and a different one in the header. That gap is what makes forgery easy, and pinning it down is the whole job of the three records.
SPF authorizes the sending IP
SPF, defined in RFC 7208, is a DNS TXT record listing which IP addresses may send for a domain. A record like v=spf1 include:_spf.google.com -all says: Google's servers may send for us, reject everything else. The receiver checks the connecting IP against the list. The catch most people miss is that SPF checks the envelope-from domain, not the From header you read — so SPF can pass while the visible sender is forged. SPF also breaks on plain forwarding, because the forwarder's IP is not in your record, and it is capped at 10 DNS-querying mechanisms. Exceed that and the check must return a permerror, which large include: chains do quietly.
DKIM signs the message
DKIM (RFC 6376) attaches a cryptographic signature over chosen headers and the body. The sending server holds a private key; the public key lives in DNS at selector._domainkey.example.com. The DKIM-Signature header names the signing domain in its d= tag, the selector in s=, and the signed headers in h=. A verifier fetches the key, recomputes the hash, and confirms nothing the signature covers changed in transit. DKIM survives forwarding because the signature travels with the message — but on its own it only proves the d= domain signed it, which need not be the From domain you see.
DMARC ties them to the visible From
SPF and DKIM each authenticate some domain; neither requires it to be the displayed one. DMARC closes that gap with alignment. A message passes DMARC only if SPF or DKIM passes and the domain it authenticated matches the header From domain. Alignment can be strict (exact match) or relaxed (same organizational domain, so mail.example.com aligns with example.com). Only one of the two needs to pass and align. The spec was rewritten in May 2026: RFC 9989 now obsoletes the original RFC 7489 and moves DMARC onto the IETF standards track, but the record still starts with v=DMARC1 and behaves the same way.
DMARC then tells the receiver what to do when nothing aligns, via the policy in your _dmarc TXT record:
p=none— monitor only. Receivers still deliver failing mail; you just collect aggregate reports at the address inrua=. This is for learning who sends as you, not protection.p=quarantine— treat failing mail as suspicious, typically routing it to spam.p=reject— refuse failing mail at the SMTP layer. This is the only setting that actually stops a forgedFromfrom landing.
A domain stuck on p=none has reporting but no enforcement. Anyone can still spoof its From, and inboxes will accept it.
Why legit mail still lands in spam
Passing all three is necessary, not sufficient. Authentication proves who sent a message, not whether it is wanted. Receivers also weigh sending-IP reputation, domain age, complaint and spam-trap rates, content, and list hygiene, so a perfectly aligned message from a cold IP or a domain with a history of complaints can still be filtered. The common own-goals are concrete, though: an SPF record that blows past the 10-lookup limit and turns into a permerror, a DKIM key rotated in software but not in DNS, or a subdomain sending mail the parent's relaxed alignment does not cover. Receiver feedback like Google Postmaster Tools and your own DMARC aggregate reports are where you find these.
Auditing a domain
To audit a domain, read the three records straight from DNS. Our dns toolkit has an Email-auth mode that pulls MX, SPF, DMARC, and a DKIM selector live and flags what is missing — pass a domain and read off the policy. From a terminal the same lookup is one request:
curl "https://exl.ink/api/dns?name=example.com&type=EMAIL"Look at whether SPF ends in -all or the weaker ~all, and whether DMARC is p=reject or just p=none. To see what actually arrives, send a test to a throwaway address from our disposable inbox and confirm the message lands with the From it claims. For the receiver's own verdict — the Authentication-Results line (RFC 8601) that records whether SPF, DKIM, and DMARC passed — use Show original in Gmail or the equivalent raw-header view in your mailbox; that stamp is added by the receiving provider, not by us. Both of our tools are ephemeral and best-effort: they read live DNS and live mail, keep nothing, and are rate-limited.
One last layer worth naming: BIMI lets a domain publish a logo that some mailbox providers show next to authenticated mail. It is a reward for getting authentication right, not a security control — it requires DMARC at quarantine or reject, and providers usually want a paid Verified Mark Certificate before they render the logo. Fix the first three records before thinking about it.