Overview
@guacamole_hbai/auth is the server-side Node client. Your application signs
people in with any conformant OIDC library — this library is not in the sign-in
path. It covers the surface either side: provisioning people, issuing enrolment
invitations, and receiving the signed events that say a session should no
longer be trusted.
npm install @guacamole_hbai/auth
Node 18+, ESM, TypeScript types included. Zero runtime dependencies —
fetch and node:crypto do everything, including RS256 verification, so there
is no jose to keep in step with whatever your OIDC stack already pins.
Someone else sits down. Your app finds out.¶
A complete, verified security-event endpoint:
import { Guacamole, SESSION_REVOKED, subjectOf } from "@guacamole_hbai/auth";
const gid = new Guacamole({
apiKey: process.env.GUACAMOLE_API_KEY!,
tenant: "acme",
baseUrl: "https://guacamole.ai",
});
const receiver = gid.receiver({ audience: "https://app.acme.com" });
receiver.on(SESSION_REVOKED, async (event, claims) => {
await sessions.revokeAllFor(subjectOf(claims));
});
export const POST = receiver.handler();
handler() reads the raw body, fetches and caches the provider's signing keys,
verifies the token, refuses a replay, dispatches to your callback, and answers
with the status the provider's retry policy depends on. It never throws.
export const POST is the Next.js, Hono, Bun, Deno and Workers route — there is no framework-named subpath to install. For Express, Connect, Fastify and raw node:http, use receiver.nodeHandler().
Then tell the provider where to send them¶
await gid.streams.ensure({
endpointUrl: `${process.env.PUBLIC_APP_URL}/api/events`,
receiver,
});
Passing the receiver rather than an aud string means the one value that has
to agree in two places cannot disagree. ensure is an upsert, so there is no
conflict to catch.
What is here¶
gid.subjects |
create, get by externalId or sub, list, iterate, suspend, deactivate, erase |
gid.enrollments |
invitations — one call, returns the hosted link — and a one-shot status check |
gid.credentials |
list and revoke passkeys |
gid.identifications |
hosted 1:N lookup. Issues no token and signs nobody in |
gid.audit |
the authentication log |
gid.streams |
register and test your security-event channel |
gid.receiver(…) |
verify and dispatch delivered events |
verifyClaims(…) |
the acr check no OIDC library does for you |
gid.tokens.verify(…) |
the whole ID-token check, where there is no OIDC library at all |
Where to go next¶
- Receiving events — the receiver in full: replay stores, status codes, what each event means.
- Verifying tokens — the
acrcheck, and the whole check where you have no OIDC library. - Managing people — subjects, enrolment, identification, the audit log.
- Reference — every export, grouped.