/** * @typedef {Object} JwtIssuerConfig * @property {import('node:crypto').KeyObject | string | Uint8Array} signingKey private (asymmetric) or shared (HMAC) key * @property {import('node:crypto').KeyObject | string | Uint8Array} [verificationKey] public key for introspection; defaults to `signingKey` (HMAC) * @property {string} alg JWS alg, e.g. `'RS256'` / `'ES256'` / `'EdDSA'` * @property {string | number} [expiresIn] access-token lifetime (default `'10m'`) * @property {string} [kid] `kid` header, so a resource server can pick the key * * @typedef {Object} GrantContext * @property {string} issuer the AS issuer identifier (→ `iss`) * * @typedef {Object} AccessGrant * @property {string} subject resource owner (or client id for client_credentials) → `sub` * @property {string} clientId → `client_id` * @property {string[]} [scope] → space-delimited `scope` * @property {string | string[]} [audience] resource indicator(s) (RFC 8707) → `aud`; falls back to `clientId` * @property {string} [dpopJkt] DPoP key thumbprint → `cnf.jkt` (RFC 9449) * @property {Record} [extra] additional claims (e.g. `authorization_details`) */ /** * @param {JwtIssuerConfig} config */ export function jwtIssuer(config: JwtIssuerConfig): { /** * Mint an RFC 9068 JWT access token. * * @param {AccessGrant} grant * @param {GrantContext} ctx * @returns {Promise<{ accessToken: string, tokenType: string, expiresIn: number, jti: string }>} */ issue(grant: AccessGrant, ctx: GrantContext): Promise<{ accessToken: string; tokenType: string; expiresIn: number; jti: string; }>; /** * Verify a JWT access token for introspection (RFC 7662). A bad * signature / expired token is simply `{ active: false }` — never a * thrown error, since introspection reports inactivity, not failure. * * @param {string} token * @param {{ issuer: string }} ctx * @returns {Promise<{ active: boolean, claims?: Record }>} */ introspect(token: string, ctx: { issuer: string; }): Promise<{ active: boolean; claims?: Record; }>; }; export type JwtIssuerConfig = { /** * private (asymmetric) or shared (HMAC) key */ signingKey: any | string | Uint8Array; /** * public key for introspection; defaults to `signingKey` (HMAC) */ verificationKey?: any | string | Uint8Array; /** * JWS alg, e.g. `'RS256'` / `'ES256'` / `'EdDSA'` */ alg: string; /** * access-token lifetime (default `'10m'`) */ expiresIn?: string | number | undefined; /** * `kid` header, so a resource server can pick the key */ kid?: string | undefined; }; export type GrantContext = { /** * the AS issuer identifier (→ `iss`) */ issuer: string; }; export type AccessGrant = { /** * resource owner (or client id for client_credentials) → `sub` */ subject: string; /** * → `client_id` */ clientId: string; /** * → space-delimited `scope` */ scope?: string[] | undefined; /** * resource indicator(s) (RFC 8707) → `aud`; falls back to `clientId` */ audience?: string | string[] | undefined; /** * DPoP key thumbprint → `cnf.jkt` (RFC 9449) */ dpopJkt?: string | undefined; /** * additional claims (e.g. `authorization_details`) */ extra?: Record | undefined; };