Skip to content

Quickstart — Node

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.

Before you begin
  • 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
Terminal window
pnpm add @intelliauth/node-sdk express
# or: npm install @intelliauth/node-sdk express

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