Skip to main content

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. :::