Without email authentication, sending email that appears to come from any domain on the internet requires no special access — just a mail server and a target. SPF, DKIM, and DMARC explained together form the three-layer defense that makes email spoofing detectable and, when configured correctly, blockable. This guide breaks down each standard technically, shows real DNS record examples, and covers what authentication failures look like from a DFIR perspective.
Why Email Authentication Matters
Email spoofing is trivial without controls in place. The SMTP protocol was designed in 1982 with no sender verification whatsoever. Any mail transfer agent can assert any From: address. Business Email Compromise (BEC) — one of the costliest threat categories tracked by the FBI — relies heavily on this gap.
SPF, DKIM, and DMARC are layered DNS-based mechanisms that close different parts of this gap. They do not encrypt email, but they let receiving mail servers verify:
- SPF — Was this email sent from an authorized server?
- DKIM — Was this email cryptographically signed by the claimed domain?
- DMARC — What should happen when SPF or DKIM fail, and who gets the reports?
None of the three is sufficient alone. All three together, with correct alignment, form a robust email authentication baseline.
SPF — Who Can Send on Your Behalf
What SPF Does
SPF (Sender Policy Framework), defined in RFC 7208, allows a domain owner to publish a list of IP addresses and mail servers that are authorized to send email on behalf of that domain.
Critically, SPF validates the envelope sender — the MAIL FROM address used in the SMTP transaction — not the From: header the recipient sees in their email client. This distinction matters: an attacker can pass SPF while still spoofing the visible From: header, which is why SPF alone is insufficient.
DNS TXT Record Format
SPF records are published as DNS TXT records at the domain's apex or relevant subdomain.
Example:
example.com. IN TXT "v=spf1 ip4:203.0.113.0/24 include:_spf.google.com include:sendgrid.net -all"Breaking this down:
| Mechanism | Meaning |
|---|---|
v=spf1 | SPF version identifier, required |
ip4:203.0.113.0/24 | Authorize this IP range |
include:_spf.google.com | Include Google's authorized senders |
include:sendgrid.net | Include SendGrid's authorized senders |
-all | Hard fail anything not matched above |
Qualifiers
Each mechanism can be prefixed with a qualifier that defines the result when it matches:
| Qualifier | Result | Meaning |
|---|---|---|
+ | Pass | Authorized (default if omitted) |
- | Fail | Not authorized; reject |
~ | SoftFail | Suspicious; accept but mark |
? | Neutral | No policy assertion |
When no mechanism matches, the result is None. Temporary DNS failures produce TempError; permanent DNS errors (such as a malformed record) produce PermError.
The 10 DNS Lookup Limit
RFC 7208 limits SPF evaluation to 10 DNS lookups. Each include:, a:, mx:, and exists: mechanism counts toward this limit. Exceeding it causes a PermError, which means SPF evaluation fails — often silently. Large organizations using multiple third-party senders frequently hit this ceiling.
ip4: and ip6: mechanisms do not count toward the lookup limit, which is why flattening SPF records (replacing includes with explicit IP ranges) is sometimes used — though it requires active maintenance as providers rotate their IP space.
Common Mistakes
+all: Authorizes every IP on the internet to send on your behalf. Completely negates SPF. Unfortunately not uncommon.- Too many
include:directives: Pushes you past the 10-lookup limit, causing PermError. - Publishing SPF on the wrong domain: If your
MAIL FROMusesbounce.example.com, SPF must be published there, not just atexample.com. - No SPF record at all: Results in None, which DMARC treats as a failure.
For a deeper reference, see the SPF wiki page.
DKIM — Proving the Message Wasn't Tampered
What DKIM Does
DKIM (DomainKeys Identified Mail), defined in RFC 6376, adds a cryptographic signature to outgoing email. The sending mail server signs selected headers and the message body using a private key. The receiving server retrieves the corresponding public key from DNS and verifies the signature.
Unlike SPF, DKIM validates the From: header domain (the d= value in the signature), which is the address the recipient actually sees. DKIM also survives forwarding in most cases, since it's bound to the message content rather than the sending IP.
How Signing Works
- The sending mail server computes a hash of the message body (canonicalized).
- It assembles a set of headers to sign (e.g.,
From,Subject,Date,To). - It signs the header set plus the body hash using an RSA or Ed25519 private key.
- It inserts a
DKIM-Signatureheader containing the signature and metadata.
The receiving server reads d= and s= from the DKIM-Signature header, constructs the DNS query <selector>._domainkey.<domain>, retrieves the public key, and verifies the signature.
DKIM-Signature Header Fields
Example of a real DKIM-Signature header:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=mail2024;
h=from:to:subject:date:message-id;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=abc123...base64encodedSignatureValue...xyz==
| Field | Meaning |
|---|---|
v=1 | DKIM version |
a=rsa-sha256 | Signing algorithm |
c=relaxed/relaxed | Canonicalization for header/body |
d=example.com | Signing domain |
s=mail2024 | Selector |
h= | List of signed headers |
bh= | Base64-encoded hash of the canonicalized body |
b= | Base64-encoded signature |
Selector and DNS Lookup
The selector (s=) allows a domain to publish multiple DKIM keys simultaneously — useful for rotating keys or using different keys per mail stream. The public key is published at:
<selector>._domainkey.<domain>.
For the example above:
mail2024._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."The p= field contains the Base64-encoded public key. An empty p= value means the key has been revoked.
RSA vs Ed25519
| RSA-SHA256 | Ed25519 | |
|---|---|---|
| Key size | 2048-bit minimum recommended | 256-bit |
| Defined in | RFC 6376 | RFC 8463 |
| Compatibility | Universal | Modern MTAs only |
| Performance | Slower | Faster |
Ed25519 is cryptographically stronger at a much smaller key size, but not all receiving mail servers support it yet. Publishing both an RSA and Ed25519 key under different selectors is the current best practice for environments that prioritize both compatibility and security.
For more, see the DKIM wiki page.
DMARC — Tying It All Together
What DMARC Does
DMARC (Domain-based Message Authentication, Reporting, and Conformance), defined in RFC 7489, builds on top of SPF and DKIM. It answers a question neither SPF nor DKIM alone can answer: does the authenticated domain align with the visible From: header?
Without DMARC, an attacker can set up a domain like evil.example that has valid SPF and DKIM, send email with From: ceo@example.com, and pass both checks — because SPF and DKIM validated evil.example, not example.com. DMARC closes this gap through identifier alignment.
Alignment
DMARC requires that at least one of the following is true:
- SPF alignment: The domain in the
MAIL FROM(Return-Path) matches theFrom:header domain. - DKIM alignment: The
d=value in the DKIM-Signature matches theFrom:header domain.
Alignment can be:
- Relaxed (
aspf=r/adkim=r): Organizational domain match is sufficient.mail.example.comaligns withexample.com. - Strict (
aspf=s/adkim=s): Exact domain match required.mail.example.comdoes not align withexample.com.
Policies
The p= tag defines what happens to messages that fail DMARC:
| Policy | Effect |
|---|---|
none | Take no action; collect reports only. Use this during initial deployment. |
quarantine | Deliver to spam/junk folder. |
reject | Do not deliver. Return a 5xx SMTP error. |
Deployment best practice: start at p=none, analyze aggregate reports for 2–4 weeks, move to p=quarantine, then p=reject once legitimate mail streams are confirmed.
DMARC TXT Record Format
Published at _dmarc.<domain>:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; adkim=r; aspf=r; pct=100; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1"| Tag | Meaning |
|---|---|
v=DMARC1 | Version identifier, required |
p=reject | Policy for failing messages |
adkim=r | DKIM alignment: relaxed |
aspf=r | SPF alignment: relaxed |
pct=100 | Apply policy to 100% of messages |
rua= | Aggregate report destination |
ruf= | Forensic report destination |
fo=1 | Generate forensic report if SPF or DKIM fails (not only both) |
Reporting
Aggregate reports (rua) are XML documents sent daily by receiving mail servers. They contain statistics: how many messages were received from each IP, whether they passed SPF/DKIM/DMARC, and what action was taken. These reports are essential for identifying unauthorized senders and mail infrastructure gaps.
Forensic reports (ruf) are per-message reports sent when a message fails. They may include redacted copies of the original message. Note that many large providers (Gmail, Outlook) have stopped sending forensic reports due to privacy concerns. Do not rely on ruf as your primary signal.
For a complete reference, see the DMARC wiki page.
ARC — The Missing Piece for Forwarding
Why Forwarding Breaks SPF and DKIM
When an email is forwarded through an intermediary (a mailing list server, a corporate forwarding rule, or a security gateway), the forwarding server typically changes the MAIL FROM address, breaking SPF alignment, and may modify headers or the message body, breaking DKIM signatures. The final receiving server sees an authentication failure that is not caused by spoofing — it's caused by legitimate forwarding.
ARC (Authenticated Received Chain), defined in RFC 8617, solves this by allowing each intermediary in the forwarding chain to attest to the authentication results it observed before modifying the message.
The Three ARC Headers
Each participating intermediary adds three headers, identified by an instance number (i=):
| Header | Purpose |
|---|---|
ARC-Authentication-Results | Records the authentication results (SPF, DKIM, DMARC) observed by this intermediary |
ARC-Message-Signature | A DKIM-style signature over the message at this hop |
ARC-Seal | A signature over all previous ARC headers, creating a verifiable chain |
The final receiving server evaluates the ARC chain. If the chain is intact and originated from a trusted ARC sealer, the receiver can honor the authentication results from earlier in the chain, even if SPF and DKIM appear broken at final delivery.
ARC is an informational standard — receivers may use it at their discretion. Gmail and Microsoft 365 both evaluate ARC chains. ARC does not override DMARC policy directly, but it gives receivers the information they need to make informed delivery decisions.
How to Check Your Domain's Configuration
Before assuming your domain is properly protected, verify it. DNS records are frequently misconfigured, outdated after infrastructure changes, or missing entirely.
The Domain Lookup tool at dfir-lab.ch/domain-lookup is a free utility that checks your domain's DNS security posture, including:
- SPF record presence, syntax validity, qualifier analysis, and lookup count
- DKIM public key retrieval (requires knowing your selector)
- DMARC record presence, policy level, and reporting configuration
- MX record enumeration
What to look for:
- SPF ends in
-all, not~allor+all - SPF lookup count is under 10
- DKIM key is 2048-bit RSA or Ed25519;
p=is not empty - DMARC policy is
quarantineorreject, notnone - DMARC
ruaaddress is valid and monitored - All subdomains that send email have their own SPF records
For subdomains that should never send email, publish an explicit null SPF record (v=spf1 -all) and a DMARC policy record to prevent subdomain abuse.
What Happens When Authentication Fails — A DFIR Perspective
Authentication Failures as Investigation Signals
In phishing analysis, authentication failures are high-fidelity signals. When an analyst receives a suspected phishing email, the email header analysis process starts with authentication results — typically embedded by the receiving mail server in the Authentication-Results header:
Authentication-Results: mx.example.com;
dkim=fail (signature verification failed) header.d=trusted-bank.com;
spf=pass (sender SPF authorized) smtp.mailfrom=evil.example;
dmarc=fail action=none header.from=trusted-bank.com
This pattern is characteristic: SPF passes for a domain the attacker controls, DKIM fails because the attacker cannot sign with trusted-bank.com's private key, and DMARC fails because there is no alignment between the SPF-authenticated domain and the From: header. The DMARC policy was none, so the message was delivered anyway.
This is precisely the configuration gap attackers look for: domains with p=none or no DMARC at all can be spoofed with high deliverability.
Automating the Analysis
Manual header inspection is time-consuming at scale. The Phishing Email Checker at platform.dfir-lab.ch automates the full authentication chain validation — SPF, DKIM, DMARC, and ARC — from a raw .eml file. It parses the authentication results, checks for alignment failures, flags policy gaps, and surfaces indicators relevant to the investigation.
From the command line using the DFIR CLI:
dfir-cli phishing analyze email.emlThe tool is available on the free tier at 100 credits per month — sufficient for routine phishing triage without any commitment. For high-volume SOC environments, paid plans remove the credit ceiling.
Conclusion
SPF, DKIM, and DMARC explained together describe a layered system where each standard compensates for the limitations of the others. SPF restricts which servers can send on a domain's behalf but does not protect the visible From: address. DKIM cryptographically binds a message to a signing domain but does not define what happens when verification fails. DMARC enforces alignment between authenticated domains and the visible sender, sets a rejection policy, and provides visibility through aggregate reports.
None of these controls require expensive tooling to deploy — they are DNS TXT records. What they require is care: understanding which services send email on your behalf, auditing that list regularly, and progressing your DMARC policy to reject once your mail streams are stable.
If you manage a domain and have not verified its current posture, start with the Domain Lookup tool. If you are investigating a suspected phishing campaign, the Phishing Email Checker will surface authentication failures and alignment gaps automatically, letting you focus on the indicators that matter.
Related reading: SPF · DKIM · DMARC · ARC Authentication · Email Spoofing · Email Header Analysis · DNS Security · Phishing Analysis · BEC