# `crit` enforcement ## Purpose RFC 7515 §4.1.11 enforcement: every entry in `header.crit` MUST be in the caller's `acceptableCriticalHeaders` allowlist. The RFC's intent is that callers refuse to verify any token whose protected header carries critical parameters they do not understand — otherwise the producer could downgrade security guarantees (e.g. an `exp` claim becoming critical against a verifier that ignores it). This module owns that gate. ## Features - Empty `crit` array rejected. - Non-array `crit` rejected. - Non-string entry rejected. - `crit` referencing itself rejected (RFC 7515 §4.1.11 MUST). - Entry not in caller's allowlist → `JWS.CRIT_UNRECOGNIZED`. - Entry in allowlist accepted. ## Usage: Basic Example ```ts import { enforceCrit, parseHeader } from "@suaveplan/jws"; const header = parseHeader("eyJhbGciOiJIUzI1NiIsImNyaXQiOlsiZXhwIl0sImV4cCI6MTYwfQ"); enforceCrit(header, ["exp"]); // does not throw ``` ## Usage: Advanced Example ```ts import { enforceCrit, JwsError } from "@suaveplan/jws"; try { enforceCrit({ alg: "HS256", crit: ["exp", "tenant"] }, ["exp"]); } catch (err) { if (err instanceof JwsError && err.code === "JWS.CRIT_UNRECOGNIZED") { // Reject the token: a critical parameter is outside the allowlist. } } // Self-reference rejected: try { enforceCrit({ alg: "HS256", crit: ["crit"] }, ["crit"]); } catch (err) { if (err instanceof JwsError && err.code === "JWS.CRIT_MALFORMED") { // RFC 7515 §4.1.11 MUST. } } ``` ## API Reference - `enforceCrit(header: JoseHeader, acceptableCriticalHeaders: readonly string[] | undefined): void` - No-op when `header.crit` is absent. - Throws `JwsError(JWS.CRIT_MALFORMED)` for shape failures (non-array, empty, non-string entry, self-reference). - Throws `JwsError(JWS.CRIT_UNRECOGNIZED)` for entries not on the allowlist. ## Implementation Notes The allowlist is supplied at every verify call rather than configured globally; this is deliberate because the allowlist is fundamentally a property of the consumer's threat model, not the JWS library. Callers integrating an RFC 7797 `b64: false` token MUST add `"b64"` to their `acceptableCriticalHeaders` even though this package implements the RFC 7797 spec internally — the gate is "do you know what to do with this parameter," not "does the library implement it." This makes it impossible to accidentally accept a `b64: false` token through a verifier that wasn't expecting one.