Email Authentication Explained
How SPF, DKIM, DMARC, and ARC work together as a system — and what happens step by step when a message arrives at a receiving server.
Why Email Needs Authentication
SMTP was designed in the early 1980s with no built-in sender verification. Any server can connect to any other server and claim to be sending mail from any address. This is not a bug — it is how the protocol was built.
Email authentication is a set of standards layered on top of SMTP to answer three questions:
- SPF: Is this server authorized to send mail for this domain?
- DKIM: Was this message actually sent by the claimed domain, and is it unmodified?
- DMARC: What should I do if SPF and DKIM both fail — and does either result align with the From: header?
Each mechanism addresses a different attack surface. Together, they form a defense-in-depth system.
SPF: Who Is Allowed to Send
SPF (Sender Policy Framework, RFC 7208) lets a domain publish a list of servers authorized to send mail on its behalf. It is a DNS TXT record:
When a message arrives, the receiving server extracts the domain from the MAIL FROM (envelope sender) and queries DNS for the SPF record. It checks whether the connecting server's IP address matches any authorized mechanism.
SPF evaluation results:
- pass — The IP is explicitly authorized
-
fail — The IP is explicitly not authorized (
-all) -
softfail — The IP is probably not authorized (
~all) — accept but mark -
neutral — The domain makes no assertion about this IP (
?all) - temperror / permerror — DNS lookup failed or record is malformed
SPF limitations
SPF validates the envelope sender, not the From: header that users see. A phisher can pass SPF by using their own domain in the envelope while spoofing your domain in the From: header. SPF also breaks when mail is forwarded, because the forwarding server's IP is not in the original domain's SPF record. These limitations are why SPF alone is not enough.
DKIM: Cryptographic Message Signing
DKIM (DomainKeys Identified Mail, RFC 6376) adds a digital signature to the message. The sending server signs selected headers and the body using a private key. The corresponding public key is published in DNS:
The signature is added as a DKIM-Signature header:
c=relaxed/relaxed; q=dns/txt;
h=from:to:subject:date:message-id:mime-version:content-type;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yA...
Key DKIM-Signature fields:
- d= — The signing domain (this is what DMARC checks for alignment)
- s= — The selector, used to look up the public key in DNS
- h= — Which headers are included in the signature
- bh= — Hash of the message body
- b= — The actual signature
- c= — Canonicalization algorithm (relaxed/relaxed is standard — tolerates minor whitespace changes)
The receiving server fetches the public key from DNS, recomputes the hash over the signed headers and body, and verifies the signature. If it matches, the message was signed by someone with access to the private key for that domain, and the signed content has not been altered.
DKIM limitations
DKIM survives forwarding (unlike SPF) because the signature travels with the message. However, mailing lists that modify the Subject or body will break the signature. DKIM also does not tell the receiver what to do with a failed signature — that is DMARC's job.
DMARC: The Policy Layer
DMARC (Domain-based Message Authentication, Reporting, and Conformance, RFC 7489) ties SPF and DKIM together and adds a policy. It is published as a DNS TXT record on _dmarc.example.com:
DMARC introduces the critical concept of alignment — the domain in the authentication result must match the domain in the From: header that the user sees:
- SPF alignment: The domain in MAIL FROM must match (or be a subdomain of) the From: header domain, AND SPF must pass.
-
DKIM alignment: The
d=domain in a valid DKIM signature must match (or be a subdomain of) the From: header domain.
A message passes DMARC if either SPF or DKIM passes with alignment. Both can fail individually as long as one succeeds with alignment.
DMARC policies
-
p=none— Monitor only. Take no action on failures. Use this while rolling out. -
p=quarantine— Treat failures as suspicious (typically route to spam folder). -
p=reject— Reject messages that fail DMARC. This is the goal.
The rua= tag specifies where aggregate reports are sent — XML reports showing authentication results for all messages claiming your domain. These reports are essential for understanding your email ecosystem before tightening the policy.
What Happens When a Message Arrives
Here is the full authentication sequence, step by step, when mx.receiver.com receives a message claiming to be from alice@example.com:
-
Connection: The sending server connects from IP
198.51.100.42and sendsMAIL FROM:<bounce-123@sender.example.com>. -
SPF check: The receiver queries
sender.example.comfor its SPF record. The IP 198.51.100.42 is listed → SPF pass. But the envelope domain issender.example.com, and the From: header saysexample.com— these don't match, so there is no SPF alignment. - Message received: The DATA phase delivers headers and body.
-
DKIM check: The receiver finds a
DKIM-Signatureheader withd=example.com; s=mtg. It fetches the public key frommtg._domainkey.example.com, verifies the signature → DKIM pass. Thed=domain matches the From: header → DKIM aligned. -
DMARC check: The receiver fetches
_dmarc.example.com. Policy isp=reject. SPF passed but is not aligned. DKIM passed and IS aligned. At least one mechanism passes with alignment → DMARC pass. - Authentication-Results: The receiver records the outcome in a header:
spf=pass (sender SPF authorized) smtp.mailfrom=sender.example.com;
dkim=pass header.d=example.com header.s=mtg;
dmarc=pass (policy=reject) header.from=example.com
This header (RFC 8601) is added by the receiving server and is the authoritative record of authentication results for that hop.
ARC: Preserving Authentication Through Forwarding
ARC (Authenticated Received Chain, RFC 8617) solves the forwarding problem. When a message passes through an intermediary (like a mailing list or forwarding service), SPF breaks (the forwarder's IP is not in the original SPF record) and DKIM may break (if the list modifies the message).
ARC works by having each intermediary record the authentication results it observed before modifying the message, then signing those results. It adds three headers per hop:
- ARC-Authentication-Results (AAR): The authentication results at this hop
- ARC-Message-Signature (AMS): A DKIM-like signature of the message as it was at this hop
- ARC-Seal (AS): A signature over all previous ARC headers, chaining them together
Each header set is numbered (i=1, i=2, etc.), forming a chain. The final receiver can inspect the chain to see that the message originally passed DMARC at hop 1, even though it now fails because a forwarder modified it at hop 2.
ARC does not override DMARC. It provides evidence that the final receiver can choose to trust. Whether to honor ARC results is at the receiver's discretion.
Common Configuration: Sending Through a Third Party
When you use a transactional email service like Mailer To Go to send mail as your-domain.com, you need to configure all three layers:
your-domain.com. IN TXT "v=spf1 include:_spf.mailertogo.com -all"
; DKIM - publish the service's signing key
mtg._domainkey.your-domain.com. IN CNAME mtg._domainkey.mailertogo.com.
; DMARC - set your policy
_dmarc.your-domain.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@your-domain.com"
The email service sends with your domain in the DKIM d= field, ensuring DKIM alignment. The SPF include: directive authorizes their servers. DMARC ties it together.
What Can Go Wrong
SPF too many DNS lookups
SPF has a hard limit of 10 DNS lookups. Each include:, a:, mx:, and redirect= mechanism counts as one lookup. Nested includes count toward the total. If you exceed 10, SPF evaluation returns permerror and DMARC treats it as a fail. Audit your SPF record with a validator tool.
DKIM key rotation failures
If you rotate your DKIM key (publish a new public key) before your sending infrastructure starts using the new private key, all in-flight messages will fail DKIM verification. Always publish the new key first, wait for DNS propagation, switch to the new private key, then remove the old public key after a grace period.
DMARC alignment mismatch
Your SPF passes and your DKIM passes, but DMARC still fails. This happens when neither result aligns with the From: header. For example, SPF validates bounces.esp.com (the envelope sender) but the From: header says your-domain.com. The fix: ensure DKIM signs with d=your-domain.com.
Forwarded mail rejected
A user forwards their old@example.com mail to new@gmail.com. Your message passes DMARC at the original server, but Gmail sees the forwarding server's IP (fails SPF) and the message may be modified (fails DKIM). With p=reject, the forwarded copy is rejected. ARC can help, but adoption varies.
Subdomain policy gaps
You publish p=reject on _dmarc.example.com, but a phisher sends from billing.example.com, which has no DMARC record. Without sp=reject (subdomain policy) in your DMARC record, the subdomain inherits the organizational policy — but only if there is no separate record. Explicitly set sp=reject or publish DMARC records for all subdomains.
Key Takeaways
- SPF checks the sending server's IP against DNS. It validates the envelope sender, not the From: header.
- DKIM cryptographically signs the message. It survives forwarding (unless the message is modified) and validates the signing domain.
- DMARC requires that SPF or DKIM pass with alignment to the From: header. It publishes a policy for what to do on failure.
- ARC preserves authentication evidence across forwarding hops.
- You need all three (SPF, DKIM, DMARC) configured correctly. Any one alone has exploitable gaps.
- Start with
p=none, read your DMARC aggregate reports, then progress top=reject.