Why Mail Authentication Exists
SMTP, the protocol that delivers email, was designed in 1982 with no authentication of any kind. Anyone can send a message claiming to be from anyone. Without help, every email is anonymous.
This was fine in 1982 because the entire internet trusted itself. By the time spam, phishing, and business-email-compromise became the dominant economic activity on email, the protocol was too widely deployed to redesign. So the industry stacked authentication standards on top of SMTP, one at a time, each filling a different gap that the others had missed.
The result is the trio on this page. None of them are mandatory parts of SMTP. None of them prevent a message from being sent. All of them help the receiver decide whether to trust a message after it arrives. They are also additive: a domain that publishes all three is much harder to spoof than a domain that publishes one or none.
SPF authenticates the sending server: is this IP allowed to send mail for this domain? DKIM authenticates the message: was this exact body and these headers signed by someone who controls the domain's private key? DMARC authenticates the identity claim: do SPF's domain or DKIM's signing domain agree with the visible From: header that the user sees?
SPF · Sender Policy Framework
SPF is an allow-list of IP addresses (and other domains) permitted to send mail for your domain. It lives as a single TXT record in DNS.
The domain owner publishes a list saying, in effect, "these IPs and these third-party services are allowed to send email claiming to be from me." When a receiving server gets a message, it looks at the SMTP envelope sender's domain, pulls up that domain's SPF record, and checks whether the connecting IP is in the allow-list. If it is, SPF passes. If it is not, SPF fails (or soft-fails, depending on the all-mechanism at the end of the record).
SPF has limits. It checks the MAIL FROM address (the envelope sender, which becomes Return-Path), not the visible From: header. A phisher can put one domain in the envelope and a different domain in the visible From, and SPF will happily pass on the envelope while the user still sees the spoofed name. DMARC (later) closes this gap by checking alignment between the two.
Read the record as a series of mechanisms separated by spaces. Each mechanism either matches the connecting IP or does not. Evaluation stops at the first match. The final all mechanism is the catch-all and decides what happens when nothing else matched.
| Mechanism | Example | What it means |
|---|---|---|
v=spf1 | v=spf1 | Required version tag. Always the first thing in the record. |
ip4: | ip4:128.210.7.45ip4:128.210.0.0/16 | This IPv4 address (or CIDR range) is allowed to send for this domain. |
ip6: | ip6:2620:0:e10::/48 | Same as ip4 but for IPv6. |
a | a or a:mail.northgate.edu | The A/AAAA records of this domain (or the named host) are allowed senders. |
mx | mx | The MX servers of this domain are allowed senders. Convenient for small setups where the same server sends and receives. |
include: | include:_spf.google.com | "And whatever their SPF record says is also allowed." Used to delegate to providers like Google Workspace, Microsoft 365, Mailgun, SendGrid. |
+all | +all | Catch-all: pass anyone not matched above. Dangerous. Effectively disables SPF. |
~all | ~all | Soft-fail: receiver should be suspicious of unmatched senders but may still deliver. Common during initial rollout. |
-all | -all | Hard-fail: receiver should reject unmatched senders. The correct final stance for any mature deployment. |
?all | ?all | Neutral: no policy expressed. Effectively useless for enforcement. |
SPF caps the number of DNS lookups a single evaluation can make at 10. Every include, a, mx, and similar mechanism counts. Bloated SPF records that pull in too many third-party providers exceed the limit and the receiver returns permerror, which most servers treat as fail. If you publish SPF, audit your lookup count.
DKIM · DomainKeys Identified Mail
DKIM cryptographically signs each outgoing message with a private key. The matching public key lives in the sender's DNS. Receivers verify the signature against the public key and know the message has not been tampered with in transit.
The sending mail server computes a cryptographic hash over the body and a selected list of headers, then signs the hash with its private RSA or Ed25519 key. The resulting signature, along with metadata describing which headers were signed and which selector to use, is attached as a DKIM-Signature: header. The corresponding public key is published as a TXT record at a well-known location: <selector>._domainkey.<domain>.
The receiving server pulls the public key from DNS using the selector named in the DKIM-Signature header, recomputes the hash, and verifies the signature. If the body or any signed header has changed (or never matched in the first place), verification fails. If the public key cannot be retrieved, DKIM is treated as none.
Sender (northgate.edu)
- Compose the message.
- Compute a hash over the body and selected headers (
From,To,Subject,Date,Message-ID, etc.). - Sign the hash with the domain's private key.
- Add a
DKIM-Signature:header carrying the signature, the selector name, the signed-headers list, and the hashing algorithm. - Send the message.
Receiver (anyone)
- Read the
DKIM-Signature:header. - Look up the public key in DNS at
<selector>._domainkey.northgate.edu. - Re-compute the same hash over the same headers and body.
- Verify the signature against the public key.
- Record the result in
Authentication-Results:asdkim=pass,dkim=fail, ordkim=none.
DKIM signs the body and the headers the sender chose to include in the signature's h= tag. Received: headers added by relays are not signed (they don't exist yet when signing happens). Footers added by mailing lists often break DKIM signatures, which is one reason DMARC has its own alignment rules to compensate. Always sign the From: header at minimum — that is what DMARC needs.
DMARC · The Policy Layer
DMARC is the standard that ties SPF and DKIM to the visible From header, declares what to do when neither aligns, and asks the world to send aggregated reports back to the domain owner.
SPF and DKIM each authenticate a piece of the message, but neither one inherently protects the field your users actually see — the From: header. DMARC fills that gap. It defines two new requirements: alignment (covered in the next section), and a published policy of what receivers should do when the alignment check fails. It also adds a reporting channel so the domain owner can see who is sending mail as them.
The DMARC policy lives at a well-known DNS location: _dmarc.<domain>. It is a single TXT record with a small set of tags.
| Tag | Example | What it means |
|---|---|---|
v | v=DMARC1 | Required version tag. Always present. |
p | p=nonep=quarantinep=reject | The policy to apply when a message fails DMARC. None = monitor only. Quarantine = treat as spam. Reject = bounce the message. |
sp | sp=reject | Optional policy applied to subdomains. If not set, subdomains inherit p. |
rua | rua=mailto:agg@example.com | Where to send aggregate reports (daily XML summaries). The single most useful tag in the record. |
ruf | ruf=mailto:fail@example.com | Where to send forensic reports (per-failed-message detail). Many receivers don't honor this for privacy reasons. |
adkim | adkim=r (relaxed)adkim=s (strict) | DKIM alignment mode. Relaxed allows the DKIM signing domain to be any organizational match. Strict requires an exact domain match. |
aspf | aspf=r (relaxed)aspf=s (strict) | SPF alignment mode. Same logic as adkim but for the SPF-validated domain. |
pct | pct=100 | Percentage of messages to apply the policy to. Lets you ramp up enforcement gradually (e.g. start at 10%, ramp to 100% over weeks). |
p=noneMonitor mode
The receiver still applies SPF and DKIM checks and still writes the result into Authentication-Results, but takes no enforcement action against failing messages. The sender simply receives aggregate reports.
p=quarantineSend to spam
Failing messages should be treated as suspicious and delivered to the spam / junk folder, not the inbox. Recipients can still recover them by digging.
p=rejectRefuse the message
Failing messages are bounced at SMTP time. The mail never reaches the user, not even spam. The sender gets a bounce back.
This is the under-appreciated half of DMARC. Receivers that honor rua= send the domain owner a daily aggregate XML report listing every IP that tried to send mail claiming the domain, broken down by SPF and DKIM result. You will learn things you didn't know — including legitimate third-party services your own organization signed up for that aren't in your SPF record yet. Free tools (parsedmarc, postmark, etc.) turn the XML into dashboards.
DMARC Alignment
SPF can pass while the message is still spoofed. DKIM can pass while the message is still spoofed. DMARC catches both because it requires alignment: SPF's domain or DKIM's signing domain has to match the visible From domain.
Recall: SPF checks the SMTP envelope sender (the domain in MAIL FROM, which becomes Return-Path:). DKIM signs whichever domain the sender chose to sign with (the d= tag in the DKIM-Signature header). Neither is required to be the same as the From: header that the user sees. A phisher can perfectly pass SPF for bulkmailer.co (the envelope they actually used) while writing From: alice@northgate.edu in the visible header.
DMARC declares this attack out of bounds. It requires that at least one of SPF or DKIM passes and aligns with the From domain. Either one is sufficient. Both failing means DMARC fails. Whether "aligns" means "exact match" or "organizational match" depends on the alignment mode in the DMARC record.
Relaxed (the default): the organizational domains must match. From: alice@mail.northgate.edu aligns with SPF's northgate.edu because both share the organizational domain northgate.edu.
Strict: the full domain names must match exactly. From: alice@mail.northgate.edu would not align with SPF's northgate.edu under strict mode. Reserved for organizations that want maximum protection and have no sub-domain mail.
Both SPF and DKIM pass and both align with the From domain. DMARC passes by either path. Mail is delivered.
SPF passed for the bulk mailer's own domain, but that domain does not align with the visible From. DKIM was never signed. DMARC fails. The domain's p=quarantine policy sends the message to spam.
The Evaluation Flow
When a message arrives at a receiving server, it runs the trio in order. The diagram below shows the full decision tree.
An SPF pass alone does not mean DMARC passes. A DKIM pass alone does not mean DMARC passes. DMARC requires that at least one of the two also aligns with the visible From:. A message can have spf=pass dkim=pass dmarc=fail, which is exactly what happens when a spoofer correctly authenticates their own domain but writes a different domain in From.
Industry Adoption
Major mailbox providers have moved from "we encourage SPF / DKIM / DMARC" to "we require all three for any bulk sender." That requirement quietly went into effect on February 1, 2024 and has not relaxed since.
If you operate any mailing list, marketing platform, or transactional sender that delivers more than 5,000 messages per day to Gmail or Yahoo accounts, your domain must pass all three checks or your messages will be filtered, deferred, or rejected. Microsoft has signaled they will reach the same posture on similar timelines. The era of opt-in mail authentication is over.
- SPF and DKIM both required for any sender >5,000 messages/day to Gmail.
- DMARC required (any policy, including
p=none) with a validruareporting address. - One-click List-Unsubscribe header required for marketing mail.
- Hard spam-rate ceiling of 0.3%.
- Same requirements as Gmail. The two announced jointly.
- Failure mode: defer, then bounce. Senders see delivery rates collapse rather than receive clean rejections.
- SPF and DKIM strongly recommended; aggressive spam scoring against senders without DMARC.
- Tenant-level enforcement available to admins; default trending toward required.
- All three checked; failures heavily weighted in spam scoring.
- Mail Privacy Protection adds an extra layer that can interfere with simple open-tracking pixels.
If you teach at a university, run a small business, or operate any service that sends email from a custom domain, you need all three. Start with SPF and DKIM at your mail provider (every major provider documents this), then add a DMARC record at p=none to collect reports for a few weeks, then graduate to p=quarantine and finally p=reject. The whole process takes a few hours of setup and a few weeks of monitoring. It is no longer optional.
A Complete Setup
Below are the three DNS records a hypothetical small institution would publish to authenticate its mail. Together they take less than five lines of zone file.
Three quick checks: dig +short TXT example.edu for SPF, dig +short TXT google._domainkey.example.edu for DKIM, and dig +short TXT _dmarc.example.edu for DMARC. Online validators (MXToolbox, dmarcian, Postmark) parse the records and tell you whether anything is malformed. Once published, send a test message to a Gmail account and use Show original to confirm all three pass.
Where to Go Next
You now have the three pieces of the phishing puzzle. Take the concepts back to a real email and read its headers.