Internet Protocols · Email Protocols

DMARC Alignment Between Header and Envelope Domains

How DMARC combines two independent authentication results into one verdict, why alignment is stricter than either check, and what the policy record actually authorizes.

SPF and DKIM each authenticate a domain, and neither authenticates the domain a reader sees. SPF checks the envelope sender’s domain against the connecting IP; DKIM checks the signing domain against a hash. A message can pass both while displaying a From header belonging to someone else, because nothing in either mechanism compares the authenticated identity with the displayed one. DMARC adds exactly that comparison, and the addition changes what the two mechanisms prove.

The alignment test

DMARC evaluation begins with the From header’s domain (the “RFC5322.From domain” in the specification’s terms) and asks whether any passing authentication result refers to a domain that is aligned with it.

Alignment comes in two modes. Relaxed alignment accepts a result whose domain is the From domain or a subdomain of it, comparing only the organizational domain. Strict alignment requires an exact match of the full domain.

The organizational domain is the registrable domain: the part that a public suffix list says is controlled by one entity. mail.example.co.uk has an organizational domain of example.co.uk, and a signature from example.co.uk relaxedly aligns with a From of mail.example.co.uk. The public suffix boundary is what makes this well-defined; without it, example.co.uk and co.uk would be indistinguishable levels of the same hierarchy.

The combination produces a small truth table:

SPF resultSPF domain alignedDKIM resultDKIM domain alignedDMARC
passyesanyanypass
anyanypassyespass
passnofailnofail
failnopassnofail
nonenononenonone

The row that surprises people is the second: a message can fail SPF entirely and still pass DMARC, provided a DKIM signature from an aligned domain verifies. That is intentional. SPF is fragile under forwarding because the forwarder’s IP is not in the author’s record; DKIM survives forwarding as long as the signed fields are not rewritten. Either mechanism passing is enough, which makes DMARC a disjunction rather than a conjunction.

The fifth row matters too. When neither mechanism produces any result at all, with no SPF record and no signature, DMARC returns none, and the domain’s policy is not applied. A domain that publishes p=reject but no SPF record and no signing practice has published a policy it cannot enforce, and receivers treat such messages as having no policy rather than as failing one.

The record and its policy

The policy lives in a TXT record at _dmarc.<domain>. The version tag is v=DMARC1 and must be first. The tags that matter:

p is the requested policy: none (monitor only), quarantine (treat as suspicious), or reject. It applies to messages that fail the alignment test.

sp is the policy for subdomains, defaulting to the value of p. It exists because a domain that rejects at the organizational level may want a looser policy for subdomains that send different mail.

adkim and aspf select strict or relaxed alignment for DKIM and SPF respectively, defaulting to relaxed (r). The letters are the tag value: s for strict, r for relaxed.

rua and ruf are report addresses. rua requests aggregate reports, which are periodic XML summaries of message counts by authentication outcome, and ruf requests failure reports, which include the offending message or headers. Failure reports are privacy-sensitive and many receivers do not send them, or send them only for domains they trust.

pct is the percentage of messages to which the policy applies, defaulting to 100. It exists for staged rollout: a domain can publish p=quarantine; pct=10 and have the policy applied to one message in ten, which lets it observe the effect before committing. A pct value below 100 makes the policy probabilistic, and a receiver may treat a message not selected for the policy as if the policy were none.

_dmarc.example.com.  TXT  "v=DMARC1; p=quarantine; sp=reject;
                            adkim=s; aspf=r; pct=100;
                            rua=mailto:dmarc-reports@example.com"

The record is subject to a size limit inherited from DNS: a TXT record is a sequence of character-strings, each at most 255 octets, and the whole record is limited by what a resolver will return in a UDP response. A record with several report addresses can exceed the practical limit and be silently truncated by an intermediary, which produces a policy that is parsed differently by different receivers. The fix is to use one or two report addresses, not to rely on truncation being handled.

What the policy authorizes the receiver to do

The policy is a request, not a command. It tells the receiver what the domain would like done with mail that fails alignment. The receiver decides whether to honor it, and the decision depends on its own trust in the authentication results.

p=none requests no action but is not a no-op: it is the mode under which receivers send aggregate reports to the addresses in rua, which is the entire point of the mode. A domain deploying DMARC starts at none to learn which legitimate sources are failing, then moves to quarantine and reject as the failures are fixed.

p=quarantine asks for the message to be treated as suspicious, typically delivered to a spam folder or tagged. The receiver chooses the mechanism; the specification deliberately does not define what quarantine means.

p=reject asks for the message to be rejected outright. It is the strongest request and the one that produces the most visible failures, because a legitimate message that fails alignment (a forwarded newsletter, a mailing list that rewrote the From header, a payment processor sending on behalf of a bank) is refused.

The gap between the policy and its enforcement is where most real-world DMARC problems live. A receiver that applies p=reject to a message whose SPF passed but whose alignment failed is making a policy decision on evidence the sender did not anticipate. A sender that publishes p=reject before its own forwarders are fixed is rejecting its own users’ mail.

Why indirect mail flow breaks the model

DMARC’s alignment test assumes the message arrives directly from the domain that authored it, or through a path that preserves the author’s identifiers. Both assumptions fail for common mail flow.

Mailing lists that rewrite the From header to the list address replace the author domain with the list’s, and then sign or send as the list. The result can pass DMARC for the list domain while destroying the author’s authentication entirely. Lists that leave From alone and only rewrite the envelope preserve DKIM if the body is not modified, which is why list software is careful about footers and subject tags.

Forwarders change the envelope sender and the connecting IP, breaking SPF, while leaving the headers intact. If the DKIM signature covers fields the forwarder does not touch, DKIM survives and DMARC passes through the disjunction. If the forwarder modifies the subject or appends a body footer, DKIM fails and so does DMARC, and the message is rejected under a strict policy.

Services sending on behalf of a domain, such as an invoicing platform or a support desk, send with the customer’s From domain but from their own infrastructure. The customer must either publish the service’s IPs in SPF and accept relaxed alignment, or have the service sign with a key under the customer’s domain via a selector the customer delegates. The second is the arrangement DMARC effectively pushes toward, because it survives forwarding.

The first arrangement has a specific weakness: relaxed SPF alignment compares organizational domains, so a service that sends from customer.com but has its own envelope domain service.example fails alignment even though SPF passes. The service has to use the customer’s domain in the envelope, which means the customer has authorized it in the SPF record, which is the actual control being exercised.

The reason a third mechanism was needed for the forwarding case is that DMARC can only report failure, not distinguish a legitimate forward from a forgery. That distinction is what the chain described in ARC and Authentication Across Forwarding Hops attempts to preserve.

Aggregate reports as a feedback loop

The reporting mechanism is the part of DMARC that changes operations rather than protocol. An aggregate report is an XML document, compressed and sent as an attachment, containing per-source-IP counts of messages that passed and failed each mechanism, with the alignment outcome.

The report’s structure is a list of records, each naming the source IP, the number of messages, the disposition applied, and the authentication results. The policy_published block records the record the receiver evaluated, which lets the domain confirm that receivers are reading the policy it intended.

Two properties make reports useful and awkward. They are sent to the domain, not to the sender, so a domain with many sending sources gets a single stream that it must correlate against its own inventory. And they are sent by the receiver at its own cadence, typically daily, so a sudden failure appears a day late. A domain that publishes p=reject before reading a week of p=none reports is acting without the data the mechanism was designed to provide.

The report is unauthenticated in the sense that anyone can send a document that looks like one to the rua address. Parsing it requires trusting the sender, which in practice means checking that the report’s report_metadata org_name and email correspond to a known receiver, and that the source IPs in the records are plausible for that receiver.

Where alignment stops being informative

A passing DMARC result says the message’s From domain authorized it, by one of two mechanisms, under the domain’s own policy. It does not say the message is wanted, well-formed, or free of malicious content. A compromised account at a domain with a correct SPF record and a valid signature produces a message that passes DMARC and is still a phishing attempt. The mechanism authenticates the domain, and the domain is the thing that was compromised.

That limit is structural rather than an implementation gap, and it is why the authentication layer is treated as one input among several rather than as a verdict. The same limit applies to the mechanism that extends authentication across forwarding, described in ARC and Authentication Across Forwarding Hops, and to the signing mechanism it builds on, described in DKIM Canonicalization and What It Actually Signs.

References

  1. RFC 7489: Domain-based Message Authentication, Reporting, and Conformance (DMARC) — IETF
  2. RFC 7208: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email — IETF
  3. RFC 6376: DomainKeys Identified Mail (DKIM) Signatures — IETF