Skip to Content
@exortek/jwssign — compact + detached + b64:false

jws.sign / jws.signDetached

Sign a payload and emit a JWS compact serialisation (header.payload.signature), or a detached-content JWS where the payload rides out of band.

alg is mandatory on every call. none is refused up front.

import { sign, signDetached } from '@exortek/jws' const token = await sign( { userId: 1, role: 'admin' }, key, { alg: 'ES256', kid: 'signing-key-2026' }, )

Signature

sign(payload, key, options) → Promise<string> signDetached(payloadBytes, key, options) → Promise<{ token, detached }>

Options

FieldTypeNotes
algstringREQUIRED. One of HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512/256K, EdDSA.
kidstringShortcut for adding kid to the protected header.
headerRecord<string, unknown>Extra protected header parameters. Merged after alg / kid. alg here is ignored (top-level wins).
critstring[]Critical header list per RFC 7515 §4.1.11. Every entry must appear as a header member.
b64booleanRFC 7797 unencoded-payload switch. Default true. See below.

Payload types

Buffers and Uint8Array are signed byte-for-byte. Strings are UTF-8. Anything else goes through JSON.stringify.

await sign({ user: 'u1' }, key, { alg: 'HS256' }) // JSON await sign('opaque payload', key, { alg: 'HS256' }) // string (UTF-8) await sign(Buffer.from([1,2,3]), key, { alg: 'HS256' }) // raw bytes

Key input

ShapeWhen it works
KeyObject (private)Asymmetric algorithms — RSA, ECDSA, EdDSA.
KeyObject (secret)HMAC algorithms — HS256 / HS384 / HS512.
Buffer / Uint8ArrayHMAC only. Rejected for asymmetric algs with INVALID_KEY.
JWK object ({ kty, ... })All algorithms. Must include the private component (d / k) for signing.

Minimum key material:

  • HMAC (RFC 7518 §3.2) — HS256 ≥ 32 B, HS384 ≥ 48 B, HS512 ≥ 64 B.
  • RSA (RFC 7518 §3.3 / §3.5) — RS/PS keys must have a modulus of at least 2048 bits. Enforced whether the key arrives as a KeyObject or a JWK.

Both minimums raise INVALID_KEY at the sign call — never quietly downgraded.

Modes

Standard compact serialisation — header.payload.signature.

const token = await sign({ userId: 1 }, key, { alg: 'ES256' }) // eyJhbGciOiJFUzI1NiJ9.eyJ1c2VySWQiOjF9.MEQC…

Errors

CodeWhen
INVALID_ARGUMENTMissing options object, missing alg, or malformed input shape.
ALGORITHM_NONE_FORBIDDENalg: 'none' — refused unconditionally.
UNSUPPORTED_ALGORITHMalg outside the algorithm matrix above.
INVALID_KEYKey/alg mismatch, short HMAC secret, or public key supplied for signing.
INVALID_PAYLOADsignDetached given non-bytes, or b64: false payload contains ..
INVALID_HEADERcrit is malformed (empty, listing itself, references a missing member).
Last updated on