Files
skills/docs/identity/auth/oauth-client/src/utils/jwt.md
2026-05-29 08:20:56 +01:00

3.1 KiB

jwt

Purpose

Provides minimal JWT decoding utilities for extracting and validating ID-token claims on the client side. Signature verification requires fetching the authorization server's JWKS endpoint and is deliberately out of scope — this module focuses on the claim-level checks that can be performed without cryptographic key material: issuer, audience, expiry, and nonce.

Separating JWT decoding from signature verification follows the principle of least authority: most OAuth 2.0 client use-cases need only claim extraction for session management, and those that require full verification can layer a JWKS-backed verifier on top.

Features

  • decodeJwt — splits a JWT and base64url-decodes the header and payload; returns typed JwtHeader and IdTokenClaims.
  • validateIdTokenClaims — verifies iss, aud, exp (with configurable clock skew), and optional nonce.
  • Throws OAuthClientError(INVALID_ID_TOKEN) with structured context on every failure path.

Usage: Basic Example

import { decodeJwt } from "@suaveplan/oauth-client/utils/jwt";

const { header, claims } = decodeJwt(tokenSet.idToken!);
console.log(claims.sub);   // subject identifier
console.log(claims.email); // user email (if present)

Usage: Advanced Example

import { decodeJwt, validateIdTokenClaims } from "@suaveplan/oauth-client/utils/jwt";

const { claims } = decodeJwt(tokenSet.idToken!);

validateIdTokenClaims(claims, {
  issuer: "https://accounts.google.com",
  audience: "my-client-id",
  nonce: storedNonce,
  clockSkewSeconds: 60,
});

// Safe to trust claims after validation passes
const userId = claims.sub;

API Reference

decodeJwt(token: string): { header: JwtHeader; claims: IdTokenClaims; raw: { header: string; payload: string; signature: string } }

Decodes a JWT string without verifying its signature.

  • Throws OAuthClientError(INVALID_ID_TOKEN) when the token does not have exactly three .-delimited parts or when either the header or payload is not valid base64url-encoded JSON.

validateIdTokenClaims(claims: IdTokenClaims, options): void

Validates standard OIDC ID-token claims.

  • options.issuer — expected iss value; must match exactly.
  • options.audience — expected aud value; must be present in the aud array.
  • options.nonce? — when provided, must match claims.nonce.
  • options.clockSkewSeconds? — tolerance for clock drift, defaults to 30.
  • options.nowSeconds? — override for the current time (seconds since epoch); useful in tests.
  • Throws OAuthClientError(INVALID_ID_TOKEN) for any failed check.

Implementation Notes

The decodeJwt function uses base64UrlDecode from the pkce utility to avoid introducing a second base64url implementation. The TextDecoder API is universally available in all targeted runtimes. Claims are typed as IdTokenClaims which uses an index signature [key: string]: unknown to allow non-standard claims without compromising the strict types of standard fields. Clock-skew tolerance applies only to the exp check (not iat) to avoid accepting tokens from the future.