Skip to content
Jennifer Programming Language

jwt API reference

JSON Web Tokens (RFC 7519): sign, verify, and decode compact JWTs. Claims are a json.Value object; the token is the usual header.payload.signature of base64url segments. Ten algorithms across four families: HMAC (HS256 / HS384 / HS512, over a shared secret), RSA PKCS#1 v1.5 (RS256 / RS384 / RS512), ECDSA (ES256 / ES384 / ES512), and Ed25519 (EdDSA). The key is always bytes: an HMAC secret, a PEM-encoded RSA / EC key, or a raw Ed25519 key from crypto.signKeypair.

verify takes the algorithm you expect and rejects a token whose header disagrees - this closes the classic JWT algorithm-confusion attack (a forged HS256 token verified with an RSA public key as the HMAC secret). It also enforces the exp (expiry) and nbf (not-before) time claims when present.

RS* / ES* need the crypto library's RSA / ECDSA surface, which is on the default jennifer binary; HS* and EdDSA run on both binaries.

Import with import "jwt.j" as jwt;. See the jwt guide for prose and examples.

Functions

jwt.decode(token as string)

Decode a JWT's claims without verifying the signature or time claims - for inspecting a token you do not trust yet (e.g. to read its kid / issuer before fetching a key). Never trust these claims for authorization; use verify for that.

Parameters

  • token {string} - the compact JWT

Returns {json.Value} - the payload claims, unverified

Throws

  • {Error} - on a malformed token

jwt.header(token as string)

Read a JWT's header (also without verifying) - useful for the alg and kid fields when selecting a verification key.

Parameters

  • token {string} - the compact JWT

Returns {json.Value} - the token header

Throws

  • {Error} - on a malformed token

jwt.sign(claims as json.Value, key as bytes, alg as string)

Sign claims into a compact JWT with the given algorithm. The header is {"alg": alg, "typ": "JWT"}; the payload is the encoded claims. key is the HMAC secret, a PEM RSA / EC private key, or an Ed25519 private key, by family.

Parameters

  • claims {json.Value} - the claims object (the token payload)
  • key {bytes} - the signing key (HMAC secret / PEM / Ed25519 private)
  • alg {string} - the JOSE algorithm (e.g. "HS256", "RS256", "ES256", "EdDSA")

Returns {string} - the signed header.payload.signature token

Throws

  • {Error} - on an unsupported algorithm or a key the algorithm rejects

jwt.verify(token as string, key as bytes, alg as string)

Verify a JWT and return its claims. Checks that the token's header algorithm equals alg (rejecting algorithm-confusion), that the signature is valid for key, and - when present - that the exp (expiry) and nbf (not-before) NumericDate claims allow the token now.

Parameters

  • token {string} - the compact JWT
  • key {bytes} - the verification key (HMAC secret / PEM public / Ed25519 public)
  • alg {string} - the algorithm the caller requires (e.g. "HS256", "RS256")

Returns {json.Value} - the verified claims

Throws

  • {Error} - on a malformed token, an algorithm mismatch, a bad signature, or an expired / not-yet-valid token

jwt.verifyJwks(token as string, jwksJson as string, alg as string)

Verify a JWT against a JWKS (a JSON Web Key Set), selecting the key by the header's kid. Reads kid from the (unverified) header, finds the matching JWK in the set's keys array, converts it to a PEM public key with crypto.jwkToPem, and verifies. For asymmetric algorithms only (RS\* / ES\*): a JWKS carries public keys, so an HMAC alg is a jwt error (use verifyWithKeys with the shared secret instead).

alg is required and enforced against the header, exactly as verify / verifyWithKeys - selecting the key by kid does not select the algorithm, so the algorithm-confusion protection stays. Needs the default jennifer binary (crypto.jwkToPem is net-of-crypto/x509, off the TinyGo build).

Parameters

  • token {string} - the compact JWT
  • jwksJson {string} - the JWKS JSON ({"keys":[{...}, ...]})
  • alg {string} - the algorithm the caller requires (e.g. "RS256", "ES256")

Returns {json.Value} - the verified claims

Throws

  • {Error} - on a missing / unknown kid, an HMAC alg, a malformed JWK, or any verify failure

jwt.verifyLeeway(token as string, key as bytes, alg as string, leeway as int)

Verify a JWT exactly like verify, but widen the exp / nbf time-claim checks by leeway seconds on each side, tolerating a small clock difference between the token's issuer and this verifier. A token is accepted while now < exp + leeway and now >= nbf - leeway; the signature, the header algorithm, and the crit check are enforced exactly as in verify. leeway must be non-negative. verify(token, key, alg) is verifyLeeway(token, key, alg, 0).

Parameters

  • token {string} - the compact JWT
  • key {bytes} - the verification key (HMAC secret / PEM public / Ed25519 public)
  • alg {string} - the algorithm the caller requires (e.g. "HS256", "RS256")
  • leeway {int} - clock-skew tolerance in seconds (must be >= 0)

Returns {json.Value} - the verified claims

Throws

  • {Error} - on a malformed token, an algorithm mismatch, a bad signature, an out-of-window token, or a negative leeway

jwt.verifyWith(token as string, key as bytes, alg as string, policy as Policy)

Verify a JWT like verify, then additionally enforce the application-level claim policy: when policy.iss is non-empty the token's iss must equal it, and when policy.aud is non-empty the token's aud (a string or an array of strings) must include it. exp / nbf and the signature are checked exactly as in verify; issuer and audience are application policy the library cannot assume, hence the explicit opt-in.

Parameters

  • token {string} - the compact JWT
  • key {bytes} - the verification key (HMAC secret / PEM public / Ed25519 public)
  • alg {string} - the algorithm the caller requires (e.g. "HS256", "RS256")
  • policy {Policy} - the expected issuer / audience (empty string skips a check)

Returns {json.Value} - the verified claims

Throws

  • {Error} - on any verify failure, or a mismatched issuer / audience

jwt.verifyWithKeys(token as string, keysByKid as map of string to string, alg as string)

Verify a JWT, selecting the verification key by the header's kid (key id). Reads kid from the (unverified) header, looks it up in keysByKid, and verifies with the matching value - a shared secret for HS\, or, for RS\ / ES\*, either a PEM public key or a JWK (a JSON object with a "kty" member, converted to a PEM via crypto.jwkToPem). A token with no kid header, or a kid absent from the map, is a jwt error (never a silent skip). The map value is text (decoded UTF-8), so it holds an HS\* secret, PEM, or JWK - a raw binary Ed25519 key (from crypto.signKeypair) is not text-representable, so EdDSA is not supported on this kid-based path; pass its key to verify directly.

alg is still required and enforced against the header, exactly as in verify: selecting the key by kid does not select the algorithm, so this keeps the algorithm-confusion protection (an attacker cannot swap in HS256 and have your RSA public PEM read as an HMAC secret). Pin alg to what the issuer uses.

For a raw JWKS (a JSON set of {"kty","kid","n","e"|"x","y"} keys), use verifyJwks, which resolves the kid and converts the JWK to a key via crypto.jwkToPem. This keysByKid form stays useful for a kid -> secret (HMAC) map, or when you have already resolved keys to PEM out of band.

Parameters

  • token {string} - the compact JWT
  • keysByKid {map of string to string} - kid -> HMAC secret, PEM key text, or a JWK (RS\* / ES\*)
  • alg {string} - the algorithm the caller requires (e.g. "HS256", "RS256")

Returns {json.Value} - the verified claims

Throws

  • {Error} - on a missing / unknown kid, or any verify failure