Guard Auth

Composite auth-bundle safety primitive (KIND="auth-bundle"). One gate that sequences b.guardJwt (bearer token), b.guardOauth (authorization-code / token-exchange flow shape), b.cookies.parseSafe (Cookie header), and a light request-header threat scan (Content-Length + Transfer-Encoding header smuggling per RFC 9112 §6.1) into a single check operators wire into the request lifecycle. Consumes ctx.authBundle:

{ jwtToken?: string, // routed to guardJwt oauthFlow?: object, // routed to guardOauth cookieHeader?: string, // routed to b.cookies.parseSafe requestHeaders?: object, // routed through threat detection }

Each sub-validator runs independently; aggregated issues carry a source field ("jwt" / "oauth" / "cookies" / "headers" / "auth") tagging which sub-guard raised them so operators see the full failure surface in one verdict.

Refusal posture: stale-token / alg=none JWT / unknown OAuth grant / CL+TE header smuggling all surface as high-severity issues. Strict profile requires at least one auth input via requireAtLeastOne — a bundle with no jwtToken / oauthFlow / cookieHeader / requestHeaders is refused so operators don't accidentally ship an unauthenticated request through a gate they thought was active.

Profiles: strict / balanced / permissive. Compliance postures: hipaa / pci-dss / gdpr / soc2. Operators select via { profile: "strict" } or { compliancePosture: "hipaa" }; postures overlay on the profile baseline.

b.guardAuth.validate(input, opts?) #

stable0.7.41hipaapci-dssgdprsoc2
{
  profile:           "strict"|"balanced"|"permissive",
  compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
  childProfile:      "strict"|"balanced"|"permissive",   // forwarded to guardJwt / guardOauth
  requireAtLeastOne: boolean,
  allowedRedirectUris: string[],   // forwarded to guardOauth
  maxBytes:          number,       // bundle JSON-byte cap
}

Inspect an auth-bundle object and return { ok, issues }. Each issue carries { kind, severity, ruleId, source, snippet } with severity in "warn"|"high"|"critical" and source tagging the sub-guard that raised it ("jwt" / "oauth" / "cookies" / "headers" / "auth"). Pure inspection — never mutates input or throws on hostile bundles.

Strict profile sets requireAtLeastOne: true so an empty bundle (no jwtToken / oauthFlow / cookieHeader / requestHeaders) emits a no-auth-input issue — guards against an operator wiring a gate onto a request that ships no credentials at all.

var rv = b.guardAuth.validate({
  jwtToken: "eyJhbGciOiJub25lIn0.eyJzdWIiOiJ4In0.",
}, { profile: "strict" });
rv.ok;                                             // → false
rv.issues.some(function (i) { return i.source === "jwt"; });   // → true

b.guardAuth.sanitize(input, opts?) #

stable0.7.41
{
  profile:    "strict"|"balanced"|"permissive",
  compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
}

Strict pass-through validator. The auth-bundle is composed of values the framework cannot safely mutate (forging a JWT alg / rewriting an OAuth state parameter / dropping cookies would be silently dangerous — sanitize must never disarm an actual attack token), so this function refuses (throws GuardAuthError) on any critical or high issue and returns the input unchanged when clean.

var clean = b.guardAuth.sanitize({
  jwtToken: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9." +
            "eyJpc3MiOiJleGFtcGxlIiwiZXhwIjo5OTk5OTk5OTk5LCJpYXQiOjE3MDAwMDAwMDB9.sig",
  cookieHeader: "sid=abc123",
}, { profile: "balanced" });
clean.cookieHeader;                                // → "sid=abc123"

b.guardAuth.gate(opts?) #

stable0.7.41hipaapci-dssgdprsoc2
{
  profile:    "strict"|"balanced"|"permissive",
  compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
  name:       string,    // gate identity for audit / observability
  childProfile: "strict"|"balanced"|"permissive",
  allowedRedirectUris: string[],
}

Build a b.gateContract gate that consumes ctx.authBundle (or ctx.auth) and dispatches to guardJwt / guardOauth / cookies / header-smuggling detection. Action chain on validation: serve (no bundle, or bundle clean) → audit-only (warn-only issues) → refuse (any critical or high issue from any sub-validator). No sanitize action — the auth bundle isn't repairable in transit.

var authGate = b.guardAuth.gate({ profile: "strict" });
var verdict = await authGate.check({ authBundle: {
  jwtToken: "eyJhbGciOiJub25lIn0.eyJzdWIiOiJ4In0.",
} });
verdict.action;                                    // → "refuse"

b.guardAuth.compliancePosture(name) #

stable0.7.41hipaapci-dssgdprsoc2

Look up a compliance-posture overlay by name (one of "hipaa" / "pci-dss" / "gdpr" / "soc2"). Returns a fresh clone of the posture overlay so the caller may mutate it freely without disturbing the shared table. Throws GuardAuthError with code "auth.bad-posture" when the name is not one this guard maps. Wired by gateContract.defineGuard through gateContract.lookupCompliancePosture, so the clone semantics and error code are identical across every guard in the family.

var posture = b.guardAuth.compliancePosture("hipaa");
posture;                                             // → overlay clone (mutable)

try {
  b.guardAuth.compliancePosture("not-a-regime");
} catch (e) {
  e.code;                                            // → "auth.bad-posture"
}

b.guardAuth.buildProfile(opts) #

stable0.7.41
{
  extends:   string|string[],   // base profile name(s) to compose
  ...:       any guard key,      // inline override of resolved keys
}

Compose a derived profile from one or more named bases plus inline overrides, resolving names through this guard's own PROFILES table. opts.extends is a base profile name ("strict" / "balanced" / "permissive") or an array of names — later entries shadow earlier ones, and inline opts keys win last. Wired by gateContract.defineGuard through gateContract.makeProfileBuilder, so operator-defined profiles stay traceable to a baseline instead of a hand-typed dictionary.

var custom = b.guardAuth.buildProfile({ extends: "strict" });
custom;                                              // → composed profile object

b.guardAuth.loadRulePack(pack) #

stable0.7.41

Register an operator-supplied rule pack with this guard's rule-pack registry. The pack is identified by pack.id (a non-empty string) and stored for later dispatch by gates that opt in via opts.rulePackId. Returns the pack unchanged on success; throws GuardAuthError with code "auth.bad-opt" when pack is missing or pack.id is not a non-empty string. Wired by gateContract.defineGuard through gateContract.makeRulePackLoader, so storage shape and validation are identical across the family.

var pack = b.guardAuth.loadRulePack({ id: "tenant-policy", rules: [] });
pack.id;                                             // → "tenant-policy"

b.guardAuth.resolveOpts(opts?) #

stable0.7.41
{
  profile:           string,    // one of PROFILES; default this guard's default
  compliancePosture: string,    // overlay one of hipaa/pci-dss/gdpr/soc2
}

Resolve caller opts against this guard's PROFILES + compliance-posture overlays into the fully-defaulted option set the guard runs on — the same resolution validate / sanitize / gate apply internally. Wired by gateContract.defineGuard from the guard's binding config (profiles / postures / defaults / error class), so a guard's bespoke gate calls resolveOpts instead of re-declaring the per-guard resolver wrapper. Throws GuardAuthError with code "auth.bad-opt" / "auth.bad-posture" on an unknown profile or posture name.

var resolved = b.guardAuth.resolveOpts({ profile: "strict" });
resolved.profile;                                    // → "strict"

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