Guard Envelope

RFC 7489 §3.1 DMARC Identifier Alignment validator. Gates the envelope-vs-header domain relationship at the MX listener's end-of-DATA boundary so a sender that passes SPF / DKIM under one domain but spoofs the user-visible From: header under another is refused before the message reaches the mail-store.

## What aligns with what

DMARC's central identifier is **RFC 5322 From: domain** — the user-visible header field. Alignment requires at least one of:

- **SPF alignment** — RFC5321.MailFrom domain (envelope-from) passed SPF (RFC 7208) AND matches the From-header domain. - **DKIM alignment** — at least one DKIM signature with d= verified (RFC 6376) AND matches the From-header domain.

Match semantics (RFC 7489 §3.1.1 / §3.1.2):

- **Strict (s)** — exact FQDN match. From: alice@example.com requires the authenticated identifier to be exactly example.com. - **Relaxed (r)** — organizational-domain match (via Public Suffix List). From: alice@mail.example.com aligns with SPF bounces.example.com because both share organizational domain example.com. Relaxed is the spec default per RFC 7489 §6.2.

## Why this primitive vs. b.mail.auth.dmarc.evaluate

b.mail.auth.dmarc.evaluate (existing) is the FULL DMARC policy evaluation: parse DMARC TXT record, evaluate pct sampling, compute final disposition (none / quarantine / reject), produce the aggregate-report tuple. It composes the alignment check internally.

b.guardEnvelope.check exposes JUST the alignment primitive so:

- The v0.9.36 MX listener can short-circuit on alignment fail before even running the upstream DMARC TXT lookup. - Operator middleware composing a custom anti-spoofing policy can reuse the alignment primitive without dragging in the full DMARC machinery (TXT parse, aggregate reporting, …). - Tests against alignment edge cases don't have to mock the full DMARC pipeline.

Both primitives produce the same alignment verdict for the same input — b.guardEnvelope is the focused gate; b.mail.auth.dmarc is the orchestrator.

## Verdict shape

{
  spf:    { aligned: bool, mode: "strict"|"relaxed", domain: string, fromDomain: string },
  dkim:   [{ aligned: bool, mode, signingDomain, fromDomain }, …],
  aligned: bool,      // at least one of SPF/DKIM aligned
  action: "accept" | "refuse"
}

When operator's profile is strict and neither SPF nor DKIM aligns, action = "refuse". Under permissive, action is always "accept" (the primitive computes alignment but doesn't gate on it — operator decides downstream from the verdict).

## CVE / threat model

- **Display-name spoofing class** — From: "Bank Of Foo" where SPF passes for evil.com and DKIM signs evil.com: this primitive ALIGNS (both evil.com), so the spoof passes DMARC. Defense lives upstream in b.guardEmail (display-name vs domain mismatch detection). - **Envelope-vs-header spoofing** (the class this PRIMITIVE defends): MAIL FROM: SPF passes for aws-bounces.com, but From: payments@your-bank.example — misalignment refused under strict. - **Same-org-different-subdomain attack** under strict: legitimate mail from bounces.example.com to alignment-strict example.com is REFUSED — operator opts to relaxed for cross-subdomain mail. - **Public-suffix confusion** — relaxed mode uses b.publicSuffix.organizationalDomain which composes the vendored PSL; an attacker can't claim co.uk as their org domain because PSL classifies it as a public suffix.

b.guardEnvelope.check(ctx, opts?) #

stable0.9.36
{
  profile:   "strict" | "balanced" | "permissive",
  posture:   "hipaa" | "pci-dss" | "gdpr" | "soc2",
  spfMode:   "strict" | "relaxed",                      // per-call override (RFC 7489 §6.2)
  dkimMode:  "strict" | "relaxed",                      // per-call override
  audit:     b.audit namespace,
}

Evaluate DMARC Identifier Alignment between the user-visible From: header domain and the authenticated identifiers (SPF MailFrom + DKIM d=). Returns the alignment verdict.

var v = b.guardEnvelope.check({
  fromHeaderDomain: "example.com",
  spfResult:        { result: "pass", domain: "bounces.example.com" },
  dkimResults:      [{ result: "pass", signingDomain: "example.com" }],
});
if (v.action === "refuse") return reply(550, "5.7.1 DMARC alignment fail");

b.guardEnvelope.compliancePosture(name) #

stable0.9.36hipaapci-dssgdprsoc2

Return the effective profile NAME for a compliance posture, or null for a name this parser does not map. Unlike the content-guard variant this returns the resolved profile string (every line-protocol parser composes gateContract.ALL_STRICT_POSTURES, so "hipaa" / "pci-dss" / "gdpr" / "soc2" all resolve to "strict") and never throws — the parser shape carries no overlay-clone, no buildProfile, and no loadRulePack. Wired by gateContract.defineParser.

b.guardEnvelope.compliancePosture("hipaa");                   // → "strict"
b.guardEnvelope.compliancePosture("not-a-regime");            // → null

Last updated 2026-08-08T16:39:49.652Z by seeder.