Files
skills/docs/api-stack/api/api-auth-rolled/src/composition/composition.md
2026-05-29 08:20:56 +01:00

2.8 KiB

composition

(no submodules)

Purpose

Top-level factory createRolledAuthAdapter that wires the four sub-modules (token-rotator, session, principal-projection, security-schemes) into a single AuthAdapter ready for the host to register. Keeping the composition explicit (rather than letting each sub-module own its own host wiring) means the dependency graph is one arrow: options flow in, an adapter object flows out, no hidden state.

The returned value extends the AuthAdapter contract (resolver + securityScheme) with three additional surfaces the future provider half (api-auth-rolled-provider) will consume: issueToken, verifyToken, and the rotator handle so operators can wire setKeys(...) from an out-of-band rotation cron.

Features

  • Single entry point — createRolledAuthAdapter(rawOptions).
  • Options validated via the package's Zod schema before any wiring runs.
  • Defaults filled at the composition layer (cookie name, rotation period, session TTL) so individual sub-modules stay focused on their one concern.
  • Returned adapter is structurally a valid AuthAdapter so any host that accepts the contract will accept the rolled adapter.

Usage: Basic

import { createRolledAuthAdapter } from "@suaveplan/api-auth-rolled";

const adapter = createRolledAuthAdapter({
    store,
    keys: [
        { kid: "k1", privateJwk, publicJwk, active: true },
    ],
    issuer: "https://api.example.com",
    audience: "example-front",
});

host.registerAuthSession(adapter);

Usage: Advanced

import { createRolledAuthAdapter } from "@suaveplan/api-auth-rolled";

const adapter = createRolledAuthAdapter({
    store,
    keys: initialKeys,
    issuer: "https://api.example.com",
    audience: "example-front",
    cookieName: "acme.session",
    sessionTtlSec: 1800,
    rotationPeriodMs: 12 * 60 * 60 * 1000,
});

// Operator rotation cron — fetch new key from KMS, swap atomically.
setInterval(async () => {
    if (!adapter.rotator.decide().shouldRotate) return;
    const next = await kms.nextKeyset();
    adapter.rotator.setKeys(next);
}, 60_000);

API Reference

  • createRolledAuthAdapter(rawOptions: unknown): RolledAuthAdapter
  • RolledAuthAdapter extends AuthAdapter: adds id: "rolled", rotator, issueToken(userId), verifyToken(token).

Implementation Notes

The adapter intentionally keeps id as the literal "rolled" so a host running both Better-Auth and rolled can disambiguate by adapter id. The securityScheme slot points at the bearer contribution (the canonical single-scheme shape) but the .schemes map on the contribution exposes both the cookie and bearer entries — emitters aware of dual-transport adapters can register both names without a separate adapter property.