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
| Field | Type | Notes |
|---|---|---|
alg | string | REQUIRED. One of HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512/256K, EdDSA. |
kid | string | Shortcut for adding kid to the protected header. |
header | Record<string, unknown> | Extra protected header parameters. Merged after alg / kid. alg here is ignored (top-level wins). |
crit | string[] | Critical header list per RFC 7515 §4.1.11. Every entry must appear as a header member. |
b64 | boolean | RFC 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 bytesKey input
| Shape | When it works |
|---|---|
KeyObject (private) | Asymmetric algorithms — RSA, ECDSA, EdDSA. |
KeyObject (secret) | HMAC algorithms — HS256 / HS384 / HS512. |
Buffer / Uint8Array | HMAC 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
KeyObjector a JWK.
Both minimums raise INVALID_KEY at the sign call — never quietly
downgraded.
Modes
Compact
Standard compact serialisation — header.payload.signature.
const token = await sign({ userId: 1 }, key, { alg: 'ES256' })
// eyJhbGciOiJFUzI1NiJ9.eyJ1c2VySWQiOjF9.MEQC…Errors
| Code | When |
|---|---|
INVALID_ARGUMENT | Missing options object, missing alg, or malformed input shape. |
ALGORITHM_NONE_FORBIDDEN | alg: 'none' — refused unconditionally. |
UNSUPPORTED_ALGORITHM | alg outside the algorithm matrix above. |
INVALID_KEY | Key/alg mismatch, short HMAC secret, or public key supplied for signing. |
INVALID_PAYLOAD | signDetached given non-bytes, or b64: false payload contains .. |
INVALID_HEADER | crit is malformed (empty, listing itself, references a missing member). |
Last updated on