Node.js SDK
@guardhouse/node is the Guardhouse beta backend SDK for Node.js 18 and later.
Use it to:
- request and cache Client Credentials access tokens
- make authenticated JSON requests from trusted backend code
- validate bearer tokens in Express with JWT signatures or introspection
Do not use this package for browser login. Use the React SDK for a React application.
Install
npm install @guardhouse/node express
Keep the client secret in server-side secret storage. Never include it in a browser bundle, mobile application, source repository, or log.
Request A Machine Token
Create a Backend / Service client and grant it access to the API scope it needs.
import { GuardhouseNodeClient } from '@guardhouse/node';
const authority = 'https://your-tenant.guardhouse.cloud';
const client = new GuardhouseNodeClient({
authority,
clientId: process.env.GUARDHOUSE_CLIENT_ID!,
clientSecret: process.env.GUARDHOUSE_CLIENT_SECRET!,
scope: 'orders.read',
});
const accessToken = await client.getAccessToken();
The client caches tokens in memory and reacquires them before expiry. Create one long-lived client per process instead of constructing one for every request.
Call The System API
A client with System API Access enabled must request the system_api scope. This is a high-privilege credential.
const systemClient = new GuardhouseNodeClient({
authority,
clientId: process.env.GUARDHOUSE_SYSTEM_CLIENT_ID!,
clientSecret: process.env.GUARDHOUSE_SYSTEM_CLIENT_SECRET!,
scope: 'system_api',
});
const users = await systemClient.get(
`${authority}/api/v1/users?pageSize=20&offset=0`,
);
Use the routes and payloads in the System API reference. The Node SDK does not provide current typed models for those operations.
Responses Without JSON
The generic SDK helpers always read a successful response as JSON. Several System API actions return 204 No Content. For those operations, obtain a token with getAccessToken() and use platform fetch; check response.ok before reading a body.
Protect An Express API
Introspection checks each token with Guardhouse. Configure an API resource with introspection credentials and keep them on the resource server.
import express from 'express';
import {
guardhouseMiddleware,
TokenValidationMode,
} from '@guardhouse/node';
const app = express();
app.use('/api', guardhouseMiddleware({
authority: 'https://your-tenant.guardhouse.cloud',
audience: 'orders_api',
validationMode: TokenValidationMode.Introspection,
introspectionClientId: process.env.GUARDHOUSE_INTROSPECTION_ID,
introspectionClientSecret: process.env.GUARDHOUSE_INTROSPECTION_SECRET,
requiredScopes: ['orders.read'],
}));
JWT mode validates signatures and claims locally. Set validationMode: TokenValidationMode.JwtSignature and keep the expected audience and scopes configured.
Local JWT validation in this beta requires a tenant-compatible JWKS endpoint. Confirm it works in your environment before choosing JWT mode; otherwise use introspection.
Main APIs
| API | Purpose |
|---|---|
GuardhouseNodeClient.getAccessToken() | Return a cached or newly requested access token |
requestToken() / refreshToken() | Make an explicit token request |
get(), post(), put(), patch(), delete() | Make an authenticated request whose success response contains JSON |
clearCache() | Clear this client's in-memory token cache |
guardhouseMiddleware() | Validate Express bearer tokens and populate request.user |
GuardhouseResourceService.validateToken() | Validate a token without Express middleware |
Current Beta Boundaries
- The exported legacy admin client is not compatible with the current System API contract. Use the generic authenticated client with the documented System API routes.
- Generic request helpers expect a JSON success body. Use platform
fetchfor204 No Contentoperations. - Confirm local JWT validation compatibility in each environment; use introspection when it is unavailable.
- Token caches are process-local and are not shared between replicas.
- The SDK has no interactive login UI and no typed role or permission clients.
Errors And Retries
Token failures and non-success API responses reject with Error. Treat its message as diagnostic text, not a stable machine-readable contract. Inspect the HTTP response directly when your application needs a status code or error body.
The generic client retries failed authenticated requests. Design write operations to be idempotent or use platform fetch when automatic retry would be unsafe.
See Errors and limits for server error envelopes and retry guidance.