SPF, DKIM, DMARC: Email Authentication for Your Domain

Email spoofing is trivially easy. Without the right DNS records in place, anyone on the internet can send a message that appears to come from your domain. SPF, DKIM, and DMARC are the three protocols that close this gap. Together they form a verification chain that tells the world: only certain servers are authorized to send mail on behalf of your domain, and any message that fails this check should be treated with suspicion or rejected outright.

This guide covers all three in depth — how they work, how to configure them correctly, how they interact, and where most implementations go wrong.

Why Email Authentication Matters

The spoofing problem

SMTP, the protocol that carries email between servers, was designed in 1982 with no authentication mechanism whatsoever. The From address in an email is just a string — any server can claim any origin. This was fine in an era when the internet was a small academic network. It is catastrophically inadequate today.

Spoofing your domain enables phishing attacks against your customers, business email compromise where attackers impersonate executives, and spam campaigns that burn your domain's reputation. Even if your own mail infrastructure is perfectly secure, an unauthenticated domain is an open invitation for abuse.

Deliverability consequences

Beyond security, authentication directly affects whether your legitimate mail reaches the inbox. Gmail, Microsoft 365, Yahoo, and virtually every major receiving mail provider now use SPF and DKIM pass rates as inputs to their spam filters. Domains without authentication records see measurably higher spam folder placement rates.

In 2024, both Google and Yahoo formalized requirements: bulk senders must have SPF or DKIM authentication, a DMARC policy, and low complaint rates. Failing any of these results in deferred or rejected mail.

How Email Delivery Works

Before diving into the protocols, a quick picture of what happens when you send email.

sequenceDiagram
    participant S as Sending MTA
    participant R as Receiving MTA
    participant DNS as DNS Server
    S->>R: MAIL FROM: user@example.com
    R->>DNS: Query SPF for example.com
    DNS-->>R: v=spf1 include:_spf.google.com -all
    R->>R: Check sender IP against SPF
    R->>DNS: Query DKIM key
    DNS-->>R: Public key for selector
    R->>R: Verify DKIM signature
    R->>DNS: Query DMARC for example.com
    DNS-->>R: v=DMARC1#59; p=reject
    R->>R: Check SPF/DKIM alignment
    R-->>S: Accept or Reject

Two addresses travel with every message:

  • The envelope sender (also called MAIL FROM): used during the SMTP transaction to handle bounces. This is what SPF checks.
  • The header From: the address displayed to the human recipient. This is what DMARC ties to.

These two addresses can be different, and this distinction matters enormously for understanding how SPF and DMARC interact.


SPF: Sender Policy Framework

SPF lets you publish a list of mail servers authorized to send email on behalf of your domain via a DNS TXT record.

Basic syntax

v=spf1 include:_spf.google.com ip4:203.0.113.42 -all

Breaking this down:

  • v=spf1 — identifies this as an SPF record (required, must come first)
  • include:_spf.google.com — authorizes all IPs listed in Google's SPF record
  • ip4:203.0.113.42 — directly authorizes a specific IPv4 address
  • -all — hard fail: any server not matched is unauthorized

Mechanisms

| Mechanism | Meaning | |-----------|---------| | ip4: / ip6: | Direct IP or CIDR range | | include: | Recursively check another domain's SPF record | | a: | Authorize the IPs in the domain's A/AAAA records | | mx: | Authorize the IPs in the domain's MX records | | all | Matches everything — used as the final catch-all |

The -all vs ~all decision

  • -all (hard fail): the receiving server should reject the message. This is the correct setting for domains with a well-defined set of senders.
  • ~all (soft fail): the message should be accepted but marked as suspicious. Use during initial rollout.
  • ?all (neutral): no policy statement, essentially useless.
  • +all (pass): authorizes everyone — never use this.

The 10-lookup limit

SPF imposes a hard limit of 10 DNS lookups per evaluation. Each include:, a:, mx:, and exists: mechanism counts as one lookup, and includes are resolved recursively. Exceeding the limit causes a permerror, which many receivers treat as a fail.

SPF flattening resolves all IPs behind your include chains and replaces them with direct ip4: and ip6: entries. This eliminates lookup depth but introduces a maintenance burden: when a third-party provider adds new sending IPs, your flattened record is out of date.


DKIM: DomainKeys Identified Mail

Where SPF verifies which server sent a message, DKIM verifies that the message content has not been tampered with in transit and that it was authorized by the domain's owner using asymmetric cryptography.

How DKIM signing works

flowchart LR
    A[Mail Server] -->|Signs with private key| B[Message + DKIM-Signature header]
    B --> C[Receiving Server]
    C -->|Looks up public key in DNS| D[selector._domainkey.example.com]
    D --> C
    C -->|Verifies signature| E{Valid?}
    E -->|Yes| F[DKIM Pass]
    E -->|No| G[DKIM Fail]

When your mail server sends a message, it computes a cryptographic hash of selected headers and the message body, then signs that hash using a private key. The resulting signature is added as a DKIM-Signature header.

The receiving server extracts the domain and selector from the signature, looks up the public key in DNS, and verifies the signature.

DNS record structure

The public key is published as a TXT record at:

<selector>._domainkey.<domain>

For example:

google._domainkey.example.com  TXT  "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3..."

Key rotation

DKIM private keys should be rotated periodically:

  1. Generate a new key pair
  2. Publish the new public key in DNS under a new selector
  3. Configure your sending infrastructure to sign with the new key
  4. Wait for DNS propagation and confirm signing works
  5. Retire the old selector

The ability to run two selectors in parallel makes rotation possible without downtime.

What DKIM does and does not protect

DKIM signs specific headers and the body. The signature survives mailing list forwarding better than SPF does (SPF checks the envelope sender, which a mailing list changes; DKIM checks the content, which ideally remains intact).

DKIM does not prevent replay attacks and does not on its own prevent spoofing of the From header. That is what DMARC adds.


DMARC: Domain-based Message Authentication, Reporting, and Conformance

DMARC builds on SPF and DKIM to answer the question neither alone can answer: does this message legitimately represent the domain shown in the From header?

The alignment requirement

flowchart TD
    A[Incoming Email] --> B{SPF Pass?}
    A --> C{DKIM Pass?}
    B -->|Yes| D{SPF Aligned with From?}
    B -->|No| E[SPF Fails DMARC]
    C -->|Yes| F{DKIM Aligned with From?}
    C -->|No| G[DKIM Fails DMARC]
    D -->|Yes| H[DMARC Pass]
    D -->|No| E
    F -->|Yes| H
    F -->|No| G
    E --> I{DKIM aligned?}
    I -->|Yes| H
    I -->|No| J[Apply DMARC Policy]
    G --> K{SPF aligned?}
    K -->|Yes| H
    K -->|No| J
    J -->|p=none| L[Deliver, send report]
    J -->|p=quarantine| M[Send to spam]
    J -->|p=reject| N[Reject message]

DMARC requires that at least one of SPF or DKIM aligns with the From domain. Alignment means the authenticated domain matches the From domain.

DMARC record syntax

v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; pct=100; adkim=r; aspf=r

Key tags:

| Tag | Meaning | |-----|---------| | p= | Policy: none, quarantine, or reject | | rua= | Aggregate report destination (daily XML summaries) | | ruf= | Forensic report destination (individual failure samples) | | pct= | Percentage of messages subject to filtering (default 100) | | adkim= | DKIM alignment: r relaxed, s strict | | aspf= | SPF alignment: r relaxed, s strict |

Rollout strategy

Rushing to p=reject is one of the most common DMARC mistakes. The correct sequence:

  1. Publish p=none with rua= — collect reports for 2-4 weeks
  2. Analyze reports — identify every source sending mail as your domain
  3. Fix gaps — add missing senders to SPF, configure DKIM signing
  4. Move to p=quarantine — optionally use pct=25 to start
  5. Move to p=reject — once quarantine is stable

This process typically takes 4-12 weeks for organizations with complex mail stacks.


How SPF, DKIM, and DMARC Work Together

The protocols are complementary and designed to layer:

  • SPF authorizes the sending infrastructure
  • DKIM provides message integrity and a cryptographic link to the signing domain
  • DMARC ties the results of both to the visible From domain and gives you a policy for what to do on failure

A message passes DMARC if it passes SPF and SPF is aligned, or it passes DKIM and DKIM is aligned. Passing both is ideal but only one is required.

This means forwarded mail (which often breaks SPF) can still pass DMARC via DKIM alignment, provided the original DKIM signature is preserved. Configuring DKIM on all your sending services is therefore not optional.


Common Mistakes

Too many SPF lookups. Chains of include: statements across multiple SaaS mail providers routinely push organizations over the 10-lookup limit. Audit regularly and consider flattening.

Missing DKIM alignment. SPF alone is not enough. If a forwarding service changes the envelope sender, SPF fails and DMARC depends entirely on DKIM.

Jumping to p=reject too fast. Skipping the monitoring phase means you will reject legitimate mail from services you forgot to configure.

Ignoring aggregate reports. DMARC without rua= is operating blind. The reports are the entire feedback loop.

Using ~all permanently. Soft fail is a transitional setting, not a destination.


Testing Your Records

Before and after any changes, verify your records:

# Check SPF
dig TXT example.com | grep spf

# Check DKIM (replace 'selector' with your selector name)
dig TXT selector._domainkey.example.com

# Check DMARC
dig TXT _dmarc.example.com

For SPF, run a lookup count against your record to confirm you are under the 10-mechanism limit. For DKIM, send a test message and inspect the raw headers for the DKIM-Signature and Authentication-Results headers.


How SiteProbe Checks Email Authentication

Manually digging through DNS records is error-prone and time-consuming, especially when you need to trace include chains or verify alignment across multiple selectors. SiteProbe automates this analysis: enter your domain and the scanner retrieves your SPF record and counts lookup depth, checks for common DKIM selectors and validates key syntax, parses your DMARC record and flags policy gaps, alignment mismatches, and missing reporting addresses, then summarizes your overall email authentication posture in a single view.

If you are unsure whether your domain's email authentication is correctly configured, scan your domain at siteprobe.live. The results are immediate, free, and give you a concrete list of what to fix.

Check your domain now

See how your domain scores on SSL, security headers, and more.
Then set up monitoring alerts to catch problems early.

$
SPF, DKIM, DMARC: Email Authentication for Your Domain | SiteProbe