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?) #
{
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) #
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.