Files
2026-05-27 23:47:53 +01:00

1.7 KiB

claims

Purpose

Encode and decode RFC 8392 CBOR Web Token claim sets. The seven IANA- registered claims (iss, sub, aud, exp, nbf, iat, cti) are typed; private claims keyed by IANA-numeric label survive the round-trip unchanged.

Features

  • encodeCwt(claims) — deterministic claim-set encoding so token bytes are byte-stable across runs.
  • decodeCwt(bytes) — typed CwtClaims output with full validation at the field boundaries.
  • Time fields (exp, nbf, iat) accept Date on the input side; the decoder produces Date from raw integers, bigints, or values wrapped in CBOR tag 1 (epoch).
  • aud accepts both string and string[] per RFC 8392 §3.1.
  • Private claims threaded through claims.private keyed by integer label number — opaque to the typed claims but preserved on round-trip.

Usage

import { decodeCwt, encodeCwt } from "@suaveplan/cbor/cwt";

const wire = encodeCwt({
  iss: "https://issuer.example",
  exp: new Date("2030-01-01"),
  cti: new Uint8Array([0x01, 0x02]),
  private: { 100: "tenant-a" },
});

const claims = decodeCwt(wire);

API

  • encodeCwt(claims: CwtClaims): Uint8Array
  • decodeCwt(bytes: Uint8Array): CwtClaims

Throws CborError(UNEXPECTED_TYPE) for malformed claim labels, wrong inner types, non-string iss/sub, malformed aud, etc.

Notes

exp/nbf/iat always serialise as integer epoch seconds rather than Tagged(1, …) — both forms are valid on the wire per RFC 8392, but the integer form is shorter and the deterministic profile prefers shortest-form. Private claims must use integer labels per the CWT registry; non-integer keys are silently dropped on encode (the Object.entries walk filters them) — the typed private shape is keyed by number.