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

20 KiB

@suaveplan/jws - RFC 7515 JSON Web Signature (verify + sign). Compact, JSON-flattened, and JSON-general (multi-signature) serializations; HS/RS/PS/ES/EdDSA algorithms; JWK + x5c + kid key resolution; crit allowlist enforcement; detached payload (§A.5); RFC 7797 b64 header support.

Summary

RFC 7515 JSON Web Signature (verify + sign). Pure TypeScript over Uint8Array + DataView plus the workspace crypto primitives (@suaveplan/crypto-rsa, @suaveplan/crypto-curve, @suaveplan/crypto-hash, @suaveplan/crypto-utils) and @suaveplan/x509 for x5c chain validation. Zero browser globals, zero Node built-ins, zero external JOSE/JWT/jws-npm dependencies.

Documentation tree

  • builtin — Seeds the default AlgorithmRegistry with the 13 built-in algorithm implementations required by RFC 7518 §3 and RFC 80…
  • ecdsa — RFC 7518 §3.4 ECDSA signing and verification over NIST P-256, P-384, and P-521. The signing input is hashed with the cu…
  • eddsa — RFC 8037 §3.1 EdDSA over Ed25519. The signing input is signed directly by Ed25519 (no caller-side pre-hash — Ed25519 ha…
  • hmac — RFC 7518 §3.2 HMAC-with-SHA-2 signing and verification. The signing input is HMAC'd with the caller-supplied symmetric…
  • none — RFC 7518 §3.6 "none" algorithm. The none value declares "no integrity protection," which is virtually never what a…
  • registry — In-package mapping from alg identifier to the concrete AlgorithmImpl that knows how to verify and (optionally) sign…
  • rsa-pss — RFC 7518 §3.5 RSASSA-PSS signing and verification. The signing input is hashed, EMSA-PSS-encoded with a random salt, an…
  • rsa — RFC 7518 §3.3 RSASSA-PKCS1-v1_5 signing and verification. The signing input is hashed with SHA-256/SHA-384/SHA-512 resp…
  • base64url — (no submodules)
  • detached — (no submodules)
  • errors — (no submodules)
  • header — (no submodules)
    • b64 — RFC 7797 §3 implements the b64 header parameter, allowing JWS producers to embed unencoded payloads directly into the…
    • crit — RFC 7515 §4.1.11 enforcement: every entry in header.crit MUST be in the caller's acceptableCriticalHeaders allowlis…
    • header — (no submodules)
  • jwk — Parse an RFC 7517 §4 / RFC 7518 §6 JSON Web Key into the typed key shape expected by the JWS algorithm impl for the dec…
  • resolver — Caller-supplied key-resolution function consulted when header.kid is present and no key has been supplied via `opts.k…
  • x5c — Decode an RFC 7515 §4.1.6 x5c certificate chain, delegate trust-path validation to @suaveplan/x509.validateChain, a…
  • observability — (no submodules)
  • schemas — (no submodules)
  • compact — (no submodules)
  • flat — (no submodules)
    • flat — (no submodules)
  • general — (no submodules)
  • sign — (no submodules)
  • verify — (no submodules)
- [base64url](./src/base64url/base64url.md) — _(no submodules)_- [detached](./src/detached/detached.md) — _(no submodules)_- [detached](./src/detached/detached.md) — _(no submodules)_- [errors](./src/errors/error-codes.md) — _(no submodules)_- [error-codes](./src/errors/error-codes.md) — _(no submodules)_- [header](./src/header/header.md) — _(no submodules)_- [b64](./src/header/b64.md) — RFC 7797 §3 implements the `b64` header parameter, allowing JWS producers to embed unencoded payloads directly into the…
  • crit — RFC 7515 §4.1.11 enforcement: every entry in header.crit MUST be in the caller's acceptableCriticalHeaders allowlis…
  • header — (no submodules)- jwk — Parse an RFC 7517 §4 / RFC 7518 §6 JSON Web Key into the typed key shape expected by the JWS algorithm impl for the dec…
  • resolver — Caller-supplied key-resolution function consulted when header.kid is present and no key has been supplied via `opts.k…
  • x5c — Decode an RFC 7515 §4.1.6 x5c certificate chain, delegate trust-path validation to @suaveplan/x509.validateChain, a…
  • observability — (no submodules)- metrics — (no submodules)- schemas — (no submodules)- schemas — (no submodules)- compact — (no submodules)- compact — (no submodules)- flat — (no submodules)- flat — (no submodules)- general — (no submodules)- general — (no submodules)- sign — (no submodules)- sign-pipeline — (no submodules)- verify — (no submodules)- verify-pipeline — (no submodules)- base64url — (no submodules)- detached — (no submodules)- detached — (no submodules)- errors — (no submodules)- error-codes — (no submodules)- header — (no submodules)- b64 — RFC 7797 §3 implements the b64 header parameter, allowing JWS producers to embed unencoded payloads directly into the…
    • crit — RFC 7515 §4.1.11 enforcement: every entry in header.crit MUST be in the caller's acceptableCriticalHeaders allowlis…
    • header — (no submodules)- jwk — Parse an RFC 7517 §4 / RFC 7518 §6 JSON Web Key into the typed key shape expected by the JWS algorithm impl for the dec…
  • resolver — Caller-supplied key-resolution function consulted when header.kid is present and no key has been supplied via `opts.k…
  • x5c — Decode an RFC 7515 §4.1.6 x5c certificate chain, delegate trust-path validation to @suaveplan/x509.validateChain, a…
  • observability — (no submodules)- metrics — (no submodules)- schemas — (no submodules)- schemas — (no submodules)- compact — (no submodules)- compact — (no submodules)- flat — (no submodules)- flat — (no submodules)- general — (no submodules)- general — (no submodules)- sign — (no submodules)- sign-pipeline — (no submodules)- verify — (no submodules)- verify-pipeline — (no submodules)- base64url — (no submodules)- detached — (no submodules)- detached — (no submodules)- errors — (no submodules)- error-codes — (no submodules)- header — (no submodules)- b64 — RFC 7797 §3 implements the b64 header parameter, allowing JWS producers to embed unencoded payloads directly into the…
    • crit — RFC 7515 §4.1.11 enforcement: every entry in header.crit MUST be in the caller's acceptableCriticalHeaders allowlis…
    • header — (no submodules)- jwk — Parse an RFC 7517 §4 / RFC 7518 §6 JSON Web Key into the typed key shape expected by the JWS algorithm impl for the dec…
  • resolver — Caller-supplied key-resolution function consulted when header.kid is present and no key has been supplied via `opts.k…
  • x5c — Decode an RFC 7515 §4.1.6 x5c certificate chain, delegate trust-path validation to @suaveplan/x509.validateChain, a…
  • observability — (no submodules)- metrics — (no submodules)- schemas — (no submodules)- schemas — (no submodules)- compact — (no submodules)- compact — (no submodules)- flat — (no submodules)- flat — (no submodules)- general — (no submodules)- general — (no submodules)- sign — (no submodules)- sign-pipeline — (no submodules)- verify — (no submodules)- verify-pipeline — (no submodules)- base64url — (no submodules)- detached — (no submodules) - detached — (no submodules)- errors — (no submodules) - error-codes — (no submodules)- header — (no submodules) - b64 — RFC 7797 §3 implements the b64 header parameter, allowing JWS producers to embed unencoded payloads directly into the…
    • crit — RFC 7515 §4.1.11 enforcement: every entry in header.crit MUST be in the caller's acceptableCriticalHeaders allowlis…
    • header — (no submodules)- jwk — Parse an RFC 7517 §4 / RFC 7518 §6 JSON Web Key into the typed key shape expected by the JWS algorithm impl for the dec…
  • resolver — Caller-supplied key-resolution function consulted when header.kid is present and no key has been supplied via `opts.k…
  • x5c — Decode an RFC 7515 §4.1.6 x5c certificate chain, delegate trust-path validation to @suaveplan/x509.validateChain, a…
  • observability — (no submodules) - metrics — (no submodules)- schemas — (no submodules) - schemas — (no submodules)- compact — (no submodules) - compact — (no submodules)- flat — (no submodules) - flat — (no submodules)- general — (no submodules) - general — (no submodules)- sign — (no submodules) - sign-pipeline — (no submodules)- verify — (no submodules) - verify-pipeline — (no submodules)

Install

bun add @suaveplan/jws

Quick start

import { compactSign, compactVerify } from "@suaveplan/jws";

const secret = new TextEncoder().encode("a-shared-32-byte-secret-pls-rotate");
const token = await compactSign("hello", secret, "HS256");
const result = await compactVerify(token, secret, { algorithms: ["HS256"] });
// result.payloadString === "hello"

Capabilities

Feature Status
RFC 7515 §3.1 compact form ✓
RFC 7515 §7.2.2 JSON-flattened ✓
RFC 7515 §7.2.1 JSON-general ✓ (multi-signature)
RFC 7515 §A.5 detached payload ✓
RFC 7797 b64: false header ✓
HS256 / HS384 / HS512 ✓ (constant-time tag compare)
RS256 / RS384 / RS512 ✓ (@suaveplan/crypto-rsa)
PS256 / PS384 / PS512 ✓ (hash-length salt)
ES256 / ES384 / ES512 ✓ (@suaveplan/crypto-curve; DER rejected)
EdDSA (Ed25519) ✓ (RFC 8037)
alg: "none" ✓ (dual-flag opt-in only)
Embedded jwk header ✓ (allowEmbeddedJwk: true)
Embedded x5c chain ✓ (@suaveplan/x509.validateChain)
kid resolver ✓ (caller-supplied async fn)
crit allowlist ✓
AbortSignal end-to-end ✓
Zod boundary at every entry ✓
OpenTelemetry histograms+counters ✓

Security defaults

  • Algorithm allowlist is mandatory at verify time. There is no default — callers MUST pass opts.algorithms. Tokens whose alg is not on the list are rejected before any cryptography runs (defence against the JWT "alg confusion" CVE class).
  • alg: "none" requires dual-flag opt-in. Both algorithms: ["none"] AND acceptNone: true are required.
  • crit parameters must be allowlisted. Per RFC 7515 §4.1.11.
  • ECDSA signatures must be fixed-length R||S. DER-encoded signatures in the JOSE position throw JWS.SIG_FORMAT_INVALID.
  • HMAC tag comparison is constant-time. Via @suaveplan/crypto-utils.constantTimeEqual.
  • PSS salt length is fixed at the hash output length. Per RFC 7518 §3.5.

Modules

Module Doc
base64url src/base64url/base64url.md
Compact serialization src/serialization/compact/compact.md
Flat serialization src/serialization/flat/flat.md
General serialization src/serialization/general/general.md
Detached payload src/detached/detached.md
Header parse / serialize src/header/header.md
crit enforcement src/header/crit.md
RFC 7797 b64 src/header/b64.md
Algorithm registry src/algorithms/registry.md
Built-in seeding src/algorithms/builtin.md
HMAC (HS256/384/512) src/algorithms/hmac.md
RSA-PKCS1-v1_5 (RS*) src/algorithms/rsa.md
RSA-PSS (PS*) src/algorithms/rsa-pss.md
ECDSA (ES*) src/algorithms/ecdsa.md
EdDSA (Ed25519) src/algorithms/eddsa.md
alg: "none" src/algorithms/none.md
JWK → key src/keys/jwk.md
x5c chain src/keys/x5c.md
KeyResolver src/keys/resolver.md
Verify pipeline src/verify/verify-pipeline.md
Sign pipeline src/sign/sign-pipeline.md
Error registry src/errors/error-codes.md
Schemas src/schemas/schemas.md
Metrics src/observability/metrics.md

License

MIT.