How DKIM, SPF, and DMARC Work: Email Authentication Explained

DKIM, SPF, and DMARC are the three pillars of email authentication -- a set of DNS-based mechanisms that allow domain owners to declare which servers are authorized to send email on their behalf and to cryptographically sign messages so recipients can verify their authenticity. Together, they combat email spoofing, phishing, and spam by giving receiving mail servers a way to distinguish legitimate messages from forgeries. Without these protocols, anyone can send an email claiming to be from any domain -- the base SMTP protocol has no built-in sender verification.

Email authentication is not a single protocol but an ecosystem of complementary standards. SPF (Sender Policy Framework, RFC 7208) declares which IP addresses may send mail for a domain. DKIM (DomainKeys Identified Mail, RFC 6376) attaches a cryptographic signature to each message. DMARC (Domain-based Message Authentication, Reporting and Conformance, RFC 7489) ties SPF and DKIM together with a policy that tells receivers what to do when authentication fails and provides a reporting mechanism back to the domain owner. ARC (Authenticated Received Chain, RFC 8617) preserves authentication results through forwarding chains. Each layer addresses a gap left by the others.

Understanding how these protocols interact -- and where they break down -- is essential for anyone managing mail infrastructure, debugging delivery problems, or defending against phishing attacks.

SPF: Sender Policy Framework

SPF is the simplest of the three protocols. It answers one question: is the server sending this email authorized to do so for this domain? SPF works by publishing a DNS TXT record on the sending domain that lists all IP addresses and networks permitted to send mail on behalf of that domain. When a receiving mail server gets a message, it checks the envelope sender (the MAIL FROM address in the SMTP transaction, also called the Return-Path) against the SPF record of that domain.

SPF Record Syntax

An SPF record is a DNS TXT record that begins with v=spf1 and contains a series of mechanisms and modifiers. Each mechanism matches against the connecting server's IP address and returns a qualifier:

v=spf1 ip4:192.0.2.0/24 ip6:2001:db8::/32 include:_spf.google.com include:servers.mcsv.net ~all

The mechanisms are evaluated left to right, and the first match wins:

Each mechanism is prefixed with a qualifier (or defaults to + if omitted):

SPF Evaluation Flow Sending Server IP: 192.0.2.10 MAIL FROM: [email protected] Receiving Server MX for dest.com DNS TXT query example.com TXT v=spf1 ip4:192.0.2.0/24 -all IP in range? Yes SPF PASS No SPF FAIL

SPF Limitations

SPF has several well-known limitations that make it insufficient on its own:

DKIM: DomainKeys Identified Mail

DKIM provides what SPF lacks: cryptographic proof that a message was sent by the claimed domain and has not been modified in transit. Defined in RFC 6376, DKIM works by having the sending mail server attach a digital signature to each outgoing message. The signature covers specific message headers and the body, and the public key needed to verify the signature is published in the domain's DNS records.

How DKIM Signing Works

When a DKIM-enabled mail server sends a message, it performs the following steps:

  1. Canonicalization -- the message headers and body are normalized to handle minor variations introduced by different mail servers (extra whitespace, header folding, case differences). DKIM defines two canonicalization algorithms: simple (almost no changes allowed) and relaxed (whitespace and case normalization). The c= tag in the signature specifies which algorithm is used for headers and body separately, e.g., c=relaxed/relaxed.
  2. Hash the body -- a hash of the canonicalized body is computed (typically SHA-256). The body hash is included in the DKIM-Signature header as the bh= tag.
  3. Select headers to sign -- the signer chooses which headers to include in the signature. At minimum, the From: header must be signed. Typically, Subject:, Date:, To:, Cc:, Message-ID:, MIME-Version:, and Content-Type: are also included. The h= tag lists the signed headers.
  4. Compute the signature -- the signer concatenates the canonicalized signed headers plus the DKIM-Signature header itself (with an empty b= tag), hashes the result, and signs it with the domain's private key using RSA-SHA256 or Ed25519-SHA256.
  5. Attach the signature -- the signature is added as a DKIM-Signature: header at the top of the message.

A typical DKIM-Signature header looks like this:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  d=example.com; s=selector1;
  h=from:to:subject:date:message-id:mime-version:content-type;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
  b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk2P3QNPGdhYe
    NMRgTvQJDbhD7gxLNNJtT9CanCMnrSa...

The key tags in the signature are:

DKIM Key Management and DNS

The public key for DKIM verification is published in a DNS TXT record at <selector>._domainkey.<domain>. For example, if the signing domain is example.com and the selector is selector1, the public key is at:

selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4..."

The selector mechanism allows a domain to maintain multiple active DKIM keys simultaneously. This is essential for key rotation: deploy a new key with a new selector, start signing with it, and retire the old selector once all in-flight messages have been delivered. Large mail providers like Google use selectors like 20230601 to indicate the key's deployment date.

DKIM supports two signing algorithms:

DKIM Signing and Verification Sending Domain (example.com) Private Key Message Headers + Body Sign(headers + body_hash) DKIM-Signature: b=Rk3f... SMTP Receiving Server DNS: selector._domainkey.example.com Public Key: p=MIGf... Verify(signature, pubkey) DKIM PASS DKIM FAIL DNS TXT Record: selector1._domainkey.example.com "v=DKIM1; k=rsa; p=MIGfMA0..." Key Rotation: deploy new selector (selector2) → sign with both → wait for in-flight messages to deliver → remove old selector

DKIM Verification

When a receiving mail server gets a message with a DKIM-Signature header, it:

  1. Extracts the signing domain (d=) and selector (s=) from the signature.
  2. Queries DNS for the TXT record at <selector>._domainkey.<domain> to retrieve the public key.
  3. Canonicalizes the signed headers and body using the method specified in c=.
  4. Computes the body hash and compares it to the bh= value in the signature.
  5. Verifies the cryptographic signature using the public key.
  6. Records the result (pass, fail, or other) in an Authentication-Results: header added to the message.

A crucial distinction from SPF: DKIM survives forwarding. When a message is forwarded by an intermediary server, the DKIM signature remains intact (assuming the forwarder does not modify the signed headers or body), because the signature was computed by the original sending domain, not by the IP address of the sending server. This makes DKIM far more robust than SPF for messages that traverse mailing lists, alumni forwarding services, or other intermediaries.

DKIM Limitations

DKIM is not without its weaknesses:

DMARC: Tying SPF and DKIM Together

DMARC (RFC 7489) is the policy and reporting layer that makes SPF and DKIM actionable. Without DMARC, a receiving server that detects an SPF failure or a DKIM failure has no guidance from the sending domain about what to do -- and no way to inform the domain owner that failures are occurring. DMARC solves both problems.

DMARC Alignment

The core concept in DMARC is alignment: the domain in the From: header (visible to the user) must align with the domain authenticated by SPF or DKIM. This closes the gap where SPF checks the envelope sender (MAIL FROM) and DKIM signs with an arbitrary domain -- neither necessarily matches what the user sees in the From: field.

DMARC defines two types of alignment:

A message passes DMARC if either SPF or DKIM passes and aligns with the From: domain:

DMARC Policy Records

DMARC policies are published as DNS TXT records at _dmarc.<domain>:

_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; adkim=r; aspf=r; pct=100; sp=reject"

The key tags:

DMARC Deployment Strategy

DMARC should be deployed in stages to avoid disrupting legitimate email flows:

  1. Monitor (p=none) -- publish a DMARC record with p=none and collect aggregate reports. Analyze the reports to identify all legitimate mail sources for the domain. This phase typically lasts 2-4 weeks.
  2. Quarantine (p=quarantine; pct=10) -- gradually increase enforcement. Start with 10% of failing messages being quarantined, then ramp up to 100% while monitoring for legitimate mail being incorrectly caught.
  3. Reject (p=reject) -- once all legitimate sources are authenticated, enforce full rejection. At this point, any message failing DMARC is definitively spoofed.

DMARC Aggregate Reports

DMARC aggregate reports are XML documents sent daily (typically) by receiving mail servers. They contain a summary of all messages claiming to be from your domain, grouped by source IP, with SPF and DKIM results for each group. A simplified example:

<record>
  <row>
    <source_ip>192.0.2.10</source_ip>
    <count>1523</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>pass</spf>
    </policy_evaluated>
  </row>
  <row>
    <source_ip>203.0.113.45</source_ip>
    <count>87</count>
    <policy_evaluated>
      <disposition>reject</disposition>
      <dkim>fail</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
</record>

These reports are essential for identifying misconfigured legitimate senders (marketing platforms, CRM systems, support ticketing systems that send on behalf of your domain) and for quantifying the volume of spoofing attempts targeting your domain.

ARC: Authenticated Received Chain

ARC (RFC 8617) solves the most persistent problem with SPF and DKIM: message forwarding. When a message passes through a mailing list or forwarding service, SPF fails (the forwarding server's IP is not in the original domain's SPF record) and DKIM often fails (the mailing list modifies the subject or appends a footer). DMARC then fails because neither SPF nor DKIM passes with alignment.

ARC allows intermediary servers to assert the authentication results they observed when the message arrived, and to sign those assertions. Each intermediary in the forwarding chain adds a set of three ARC headers:

Each set is numbered with an instance counter (i=1, i=2, etc.), creating an ordered chain. When the final destination receives the message, it can walk the ARC chain backward: if it trusts the most recent ARC intermediary and that intermediary saw valid DKIM/SPF, the destination can accept the message despite the current DKIM/SPF failures.

ARC does not replace DMARC -- it supplements it. A receiver's DMARC evaluation can consider ARC results when making disposition decisions, but only if the receiver trusts the ARC-signing intermediaries. Gmail, Microsoft, and other major receivers maintain lists of trusted ARC signers.

Putting It All Together: The Full Authentication Pipeline

When a receiving mail server processes an inbound message, the full authentication pipeline looks like this:

  1. SMTP connection -- the sending server connects and provides the envelope sender (MAIL FROM).
  2. SPF check -- the receiver queries DNS for the SPF record of the envelope sender domain and checks the connecting IP against it. Result: pass, fail, softfail, neutral, permerror, or temperror.
  3. Message received -- the message headers and body are received.
  4. DKIM check -- the receiver extracts the DKIM-Signature header, fetches the public key from DNS, and verifies the signature. Result: pass, fail, or none (no signature).
  5. DMARC check -- the receiver queries DNS for the DMARC record of the From: header domain. It checks whether SPF or DKIM passed with alignment to the From: domain. Based on the DMARC policy (p=), the message is accepted, quarantined, or rejected.
  6. ARC check (if present) -- if DMARC fails but ARC headers are present, the receiver evaluates the ARC chain to determine if a trusted intermediary saw valid authentication earlier in the chain.
  7. Authentication-Results header -- the receiver adds an Authentication-Results: header summarizing all checks, which downstream mail processing (spam filters, user-visible indicators) can use.
Authentication-Results: mx.google.com;
  dkim=pass header.d=example.com header.s=selector1;
  spf=pass (google.com: domain of [email protected] designates 192.0.2.10 as permitted sender) [email protected];
  dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

Common Authentication Failures and Debugging

Email authentication failures are notoriously difficult to debug because the symptoms (messages going to spam, being silently dropped, or being rejected) are often reported by end users long after the message was sent. Common failure scenarios include:

SPF Failures

DKIM Failures

DMARC Failures

BIMI: Brand Indicators for Message Identification

BIMI is a newer standard that builds on top of DMARC to display a verified brand logo next to authenticated messages in supporting email clients. For BIMI to work, a domain must have p=quarantine or p=reject DMARC policy. The BIMI record is a DNS TXT record at default._bimi.<domain> containing a URL to the brand's SVG logo and optionally a Verified Mark Certificate (VMC) issued by a certificate authority.

BIMI provides a visible incentive for domain owners to deploy DMARC: users can see at a glance whether a message is authenticated, and brands get logo display as a reward for securing their email. Gmail, Apple Mail, and Yahoo Mail support BIMI.

DNSSEC and Email Authentication

All three protocols (SPF, DKIM, DMARC) rely on DNS for publishing and retrieving records. Without DNSSEC, an attacker who can spoof DNS responses (via cache poisoning or man-in-the-middle attacks) could provide a false SPF record (making the attacker's IP appear authorized), a false DKIM public key (allowing the attacker to forge signatures), or a false DMARC record (setting p=none to disable enforcement).

DNSSEC provides cryptographic authentication of DNS responses, ensuring that the SPF, DKIM, and DMARC records retrieved by the receiver are authentic and have not been tampered with. While DNSSEC adoption remains incomplete, signing your domain's DNS zone significantly strengthens email authentication.

Real-World Adoption and Impact

Major email providers have progressively tightened email authentication requirements:

Studies show that domains with p=reject DMARC policies see a 95%+ reduction in spoofed messages reaching recipients. However, as of 2025, fewer than 30% of domains have any DMARC record published, and fewer than 10% have enforcement-level policies (p=quarantine or p=reject).

Relevant RFCs

See It in Action

Email authentication is deeply tied to DNS infrastructure. Every SPF lookup, DKIM key retrieval, and DMARC policy check is a DNS query that traverses the internet's routing infrastructure. Use the god.ad BGP Looking Glass to explore the networks of major email providers and see the AS paths between them:

Every email you send traverses BGP-routed paths from your mail server to the recipient's MX server. The SMTP connection, the DNS lookups for SPF/DKIM/DMARC, and the aggregate report delivery all depend on the global routing table. Look up your mail server's IP address to see its route origin and the path it takes to reach major email providers.

See BGP routing data in real time

Open Looking Glass
More Articles
How TLS/HTTPS Works: Securing the Internet's Traffic
Certificate Transparency: How CT Logs Secure the Web's PKI
How Firewalls Work: Packet Filtering, Stateful Inspection, and Beyond
What is Cross-Site Scripting (XSS)?
What is Cross-Site Request Forgery (CSRF)?
What is Server-Side Request Forgery (SSRF)?