Five minutes from npm install to a Node API that validates IntelliAuth sessions on every request. This covers the server-side half of an IntelliAuth integration — pair it with the React quickstart for the browser side.
- An IntelliAuth tenant URL
- An application registered in the tenant (the same one your frontend uses, or a separate M2M application for backend-only)
- The application's audience identifier (the value tokens issued for your API will carry as
aud) - Node 18+ and an Express 4 or 5 project
1. Install the SDK
Section titled “1. Install the SDK”pnpm add @intelliauth/node-sdk express# or: npm install @intelliauth/node-sdk express2. Mount the session-validation middleware
Section titled “2. Mount the session-validation middleware”The Node SDK ships an Express middleware that:
- Reads the
Authorization: Bearer <token>header. - Validates the token's signature against your tenant's JWKS (cached after first fetch).
- Confirms the audience matches your API.
- Confirms the token isn't expired or revoked.
- Attaches the verified claims to
req.user.
import express from 'express'import { requireSession } from '@intelliauth/node-sdk/express'
const app = express()
app.use( requireSession({ tenantUrl: process.env.INTELLIAUTH_TENANT_URL!, audience: 'api.banking.cymmetri.com', }),)
app.get('/me', (req, res) => { // req.user is fully typed and validated res.json({ sub: req.user.sub, email: req.user.email })})
app.listen(3000)That's the full server-side integration. Any route mounted after requireSession rejects requests without a valid bearer token with 401; routes get a typed req.user for the rest.
3. (Optional) Protect specific routes only
Section titled “3. (Optional) Protect specific routes only”If you don't want every route to require auth, mount the middleware per-route instead of globally:
import { requireSession } from '@intelliauth/node-sdk/express'
const auth = requireSession({ tenantUrl: process.env.INTELLIAUTH_TENANT_URL!, audience: 'api.banking.cymmetri.com',})
app.get('/public', (req, res) => res.send('open to anyone'))app.get('/private', auth, (req, res) => res.json({ user: req.user }))Both shapes are fine. App-wide is simpler when most routes need auth; per-route is clearer when you have a public-by-default API with a few protected endpoints.
4. Make programmatic calls with the management client
Section titled “4. Make programmatic calls with the management client”The session middleware validates incoming tokens. For outbound programmatic calls into the integrator REST surface — look up a user, list applications, manage groups, register a federation connection from a B2B onboarding flow — use the management client. It uses a separate machine-to-machine credential, not your end-user tokens. (Operations that are tenant-admin web-driven — suspending an account, reading audit logs, configuring flows — are not on this surface; those are done by humans in the IntelliAuth admin console.)
import { ManagementClient } from '@intelliauth/node-sdk'
const mgmt = new ManagementClient({ tenantUrl: process.env.INTELLIAUTH_TENANT_URL!, clientId: process.env.INTELLIAUTH_M2M_CLIENT_ID!, clientSecret: process.env.INTELLIAUTH_M2M_CLIENT_SECRET!,})
const user = await mgmt.users.get('usr_01HZX...')const apps = await mgmt.applications.list({ limit: 50 })The client credentials grant runs at construction time; the resulting access token is cached and refreshed transparently.
The management-client credential pair (clientId + clientSecret) is for backend use only. Never ship it to a browser bundle — anyone who reads the bundle can issue tokens against your tenant.
What's next
Section titled “What's next”- Install the Node SDK — full options + environment-variable conventions.
- OAuth flows — the machine-to-machine grant in detail.
- API reference — the underlying HTTP endpoints the SDK calls.