Node.js quickstart
Node 18+, ESM, TypeScript types included.
npm install @latchvector/sso
1. Protect an API
Most integrations only need this. Your API verifies tokens locally — it does not call the SSO service on every request.
import express from 'express';
import { TokenVerifier } from '@latchvector/sso';
import { requireAuth, requirePermission, ssoErrorHandler } from '@latchvector/sso/express';
// Build once at startup — caches the discovery document and signing keys.
const verifier = new TokenVerifier({
issuer: 'https://sso.yourdomain.com',
audience: 'https://api.yourcompany.com', // your registered identifier
});
const app = express();
app.get('/invoices', requireAuth(verifier), (req, res) => {
res.json({ ownerId: req.principal!.uid });
});
app.post('/invoices/:id/approve',
requireAuth(verifier), requirePermission('invoice.approve'), handler);
app.use(ssoErrorHandler()); // register last
2. Log a user in
import { SsoClient } from '@latchvector/sso';
const sso = new SsoClient({ issuer: 'https://sso.yourdomain.com',
audience: 'https://api.yourcompany.com' });
const result = await sso.login(email, password);
if (result.status === 'authenticated') {
const { accessToken, refreshToken } = result.tokens;
} else if (result.status === 'mfa_required') {
await sso.verifyMfa(result.mfaToken, code);
}
Rotate with sso.refresh(refreshToken) and always persist the new refresh
token it returns. See Sessions & refresh.
3. Manage resources
import { ManagementClient } from '@latchvector/sso';
const mgmt = new ManagementClient({ issuer, token: () => currentAccessToken });
await mgmt.users.create({ organizationId, email, fullName, roleId });
await mgmt.applications.create({ organizationId, identifier, name });
Every endpoint is typed and grouped; anything new is reachable via
mgmt.request(...).
:::tip Full reference The npm README covers machine-to-machine, multitenancy (Prisma), webhooks, and go-live checks. The complete endpoint list is in the API reference. :::