Getting Started

Introduction

What ioserver-oidc is, how it fits into the IOServer ecosystem, and when to use it.

Introduction

ioserver-oidc is a middleware package that adds OIDC/OAuth2 JWT authentication to IOServer applications. It provides ready-to-use classes that slot directly into IOServer's middleware system without requiring changes to your business logic.

IOServer primer

If you are not familiar with IOServer, the key concept to understand is the middleware chain. Every addController and addService call accepts an optional middlewares array. Middlewares run before each HTTP handler or WebSocket connection is established. ioserver-oidc provides middleware classes designed to live in that array.

import { IOServer } from "ioserver";
import { OidcHttpMiddleware, OidcSocketMiddleware } from "ioserver-oidc";

const server = new IOServer({ port: 3000 });

// HTTP: OidcHttpMiddleware runs before every route in ApiController
server.addController({
  name: "api",
  controller: ApiController,
  middlewares: [OidcHttpMiddleware],
});

// WebSocket: OidcSocketMiddleware runs before each new connection to ChatService
server.addService({
  name: "chat",
  service: ChatService,
  middlewares: [OidcSocketMiddleware],
});

await server.start();

The IOServer component model and middleware documentation are the recommended starting point if this is your first time working with the framework.

What ioserver-oidc provides

ExportTypeRole
OidcConfigManagerBaseManagerReads environment variables, exposes OidcConfig to sibling middlewares
OidcHttpMiddlewareBaseMiddlewareVerifies JWT Bearer tokens on HTTP requests
OidcSocketMiddlewareBaseMiddlewareVerifies JWT tokens on Socket.IO connections
OidcSocketAdminMiddlewareBaseMiddlewareRole guard — rejects non-admin Socket.IO connections
verifyOidcTokenfunctionLow-level JWT verification helper
OidcConfiginterfaceConfiguration shape
OidcUserContextinterfaceAuth context injected onto request/socket
OidcFeaturestypeFeature flags decoded from the features JWT claim

Authentication flow

Client                   IOServer                  auth-service
  │                         │                           │
  │ POST /api/resource       │                           │
  │ Authorization: Bearer …  │                           │
  │────────────────────────►│                           │
  │                         │ OidcHttpMiddleware         │
  │                         │  verifyOidcToken()         │
  │                         │   getJwks(jwksUri) ───────► GET /api/auth/jwks
  │                         │   jwtVerify(token, keyset)  ◄──── { keys: [...] }
  │                         │  → OidcUserContext         │
  │                         │  users.findOrCreate(sub)   │
  │                         │ handler(request, reply)    │
  │ 200 OK                  │                           │
  │◄────────────────────────│                           │

JWKS keys are cached in-process per URI. jose refreshes them automatically on signature failure (key rotation) with a minimum 5-minute cooldown, so normal traffic does not trigger repeated round-trips to auth-service.

auth-service compatibility

The package is designed to work with BetterAuth acting as an OAuth2 provider. It expects:

  • iss — set to AUTH_SERVICE_URL
  • aud — set to the OAuth2 client_id (= AUTH_SERVICE_APP_SLUG)
  • sub — stable user identifier
  • Custom claims: roles, permissions, features (all optional; default to empty array/object)
  • JWKS endpoint available at <AUTH_SERVICE_URL>/api/auth/jwks (or overridden via AUTH_SERVICE_JWKS_URI)

The verification logic in jwks.ts uses jose.jwtVerify with issuer + audience validation.

Copyright © 2026