Files
skills/docs/security-stack/security/jws/src/header/crit.md
2026-05-29 08:20:56 +01:00

2.4 KiB

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

import { enforceCrit, parseHeader } from "@suaveplan/jws";

const header = parseHeader("eyJhbGciOiJIUzI1NiIsImNyaXQiOlsiZXhwIl0sImV4cCI6MTYwfQ");
enforceCrit(header, ["exp"]); // does not throw

Usage: Advanced Example

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.