Api

verifyOidcToken

Low-level JWT verification helper. Use this when you need to verify a token outside of the IOServer middleware system.

verifyOidcToken

verifyOidcToken is the low-level function that OidcHttpMiddleware and OidcSocketMiddleware call internally. Export it if you need to verify a token in a context where the middleware system is not available — for example in a background job, a CLI tool, or a custom Fastify plugin.

Signature

async function verifyOidcToken(
  token: string,
  config: OidcConfig,
): Promise<OidcUserContext>

Parameters

ParameterTypeDescription
tokenstringRaw JWT access token string (without Bearer prefix)
configOidcConfigOIDC configuration — authServiceUrl, appSlug, and optional overrides

Return value

Returns a Promise<OidcUserContext> on success. See Types for the full interface.

Note: userId is set to the sub claim value at this stage. The OIDC middlewares replace it with the local DB user ID after calling users.findOrCreate. When using verifyOidcToken directly you receive the OIDC sub in both userId and sub.

Errors

Throws a jose JWTVerifyError (or a subclass) on any of:

  • Invalid or expired JWT signature
  • iss mismatch
  • aud mismatch (audience must match config.appSlug)
  • Expired token (exp in the past)
  • Not-yet-valid token (nbf in the future)

JWKS caching

verifyOidcToken maintains an in-process Map<jwksUri, RemoteJWKSet> shared across all calls. The first call for a given URI fetches the key set; subsequent calls reuse it. jose handles automatic key refresh on signature failures (key rotation) with a minimum 5-minute cooldown.

Example

import { verifyOidcToken } from "ioserver-oidc";

const config = {
  authServiceUrl: process.env.AUTH_SERVICE_URL!,
  appSlug: process.env.AUTH_SERVICE_APP_SLUG!,
};

async function processWebhook(authHeader: string | undefined) {
  if (!authHeader?.startsWith("Bearer ")) {
    throw new Error("Missing token");
  }
  const token = authHeader.slice(7);

  try {
    const ctx = await verifyOidcToken(token, config);
    console.log("Webhook from", ctx.sub, "role:", ctx.userRole);
  } catch (err) {
    console.error("Invalid token:", err);
    throw err;
  }
}

Source

src/jwks.ts

Copyright © 2026