Node.js server adapter for AuthOS authentication - Express middleware and token verification
npm install @drmhse/authos-node

Node.js server adapter for AuthOS - the multi-tenant authentication platform. Provides JWT verification, webhook signature validation, and Express middleware.
``bash`
npm install @drmhse/authos-node
For Express middleware:
`bash`
npm install @drmhse/authos-node express
Verify JWT tokens issued by AuthOS:
`ts
import { createTokenVerifier } from '@drmhse/authos-node';
const verifier = createTokenVerifier({
baseURL: 'https://sso.example.com'
});
// Verify a token
const verified = await verifier.verifyToken(token);
console.log(verified.claims);
// {
// sub: 'user_123',
// email: 'user@example.com',
// is_platform_owner: false,
// org: 'acme-corp',
// permissions: ['users:read', 'users:write']
// }
`
The req.auth type is automatically augmented when you import from @drmhse/authos-node/express. No manual setup required!
`ts
import { createAuthMiddleware } from '@drmhse/authos-node/express';
// TypeScript knows about req.auth automatically
app.get('/profile', requireAuth(), (req, res) => {
const userId = req.auth?.claims.sub; // ✓ Typed correctly
res.json({ userId });
});
`
If you need access to the token claims type directly:
`ts
import { TokenClaims, VerifiedToken } from '@drmhse/authos-node';
function processUser(auth: VerifiedToken) {
console.log(auth.claims.email);
}
`
Protect your Express routes with AuthOS authentication:
`ts
import { createAuthMiddleware } from '@drmhse/authos-node/express';
import express from 'express';
const app = express();
const { requireAuth, requirePermission } = createAuthMiddleware({
baseURL: process.env.AUTHOS_URL!
});
// Public route
app.get('/', (req, res) => {
res.json({ message: 'Hello world' });
});
// Protected route - requires valid JWT
app.get('/profile', requireAuth(), (req, res) => {
// req.auth contains verified token info
res.json({ user: req.auth?.claims });
});
// Protected route - requires specific permission
app.delete('/users/:id',
requireAuth(),
requirePermission('users:delete'),
(req, res) => {
res.json({ message: 'User deleted' });
}
);
app.listen(3000);
`
The middleware looks for a Bearer token in the Authorization header:
``
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Requires a valid JWT token. Adds req.auth with verified token info.
`ts`
app.get('/protected', requireAuth(), (req, res) => {
const userId = req.auth?.claims.sub;
res.json({ userId });
});
Options:
| Option | Type | Description |
|--------|------|-------------|
| getToken | (req) => string | Custom token extractor |
Requires the user to have a specific permission.
`ts`
app.post('/admin/users',
requireAuth(),
requirePermission('users:create'),
(req, res) => { ... }
);
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| message | string | "Insufficient permissions" | Custom error message |
Requires the user to have at least one of the specified permissions.
`ts`
app.get('/reports',
requireAuth(),
requireAnyPermission(['reports:read', 'reports:admin']),
(req, res) => { ... }
);
Requires the user to have all of the specified permissions.
`ts`
app.post('/admin/settings',
requireAuth(),
requireAllPermissions(['admin:access', 'settings:write']),
(req, res) => { ... }
);
Requires the user to be a platform owner.
`ts`
app.get('/platform/settings',
requireAuth(),
requirePlatformOwner(),
(req, res) => { ... }
);
Requires the user to belong to a specific organization.
`ts`
app.get('/org/:slug/data',
requireAuth(),
requireOrganization((req) => req.params.slug),
(req, res) => { ... }
);
Requires the user's JWT to have a matching service claim. Use this for service-scoped endpoints.
`ts`
app.get('/services/:slug/data',
requireAuth(),
requireService((req) => req.params.slug),
(req, res) => { ... }
);
Requires the user to belong to a specific org AND service. Provides complete tenant isolation.
`ts`
app.get('/orgs/:org/services/:service/data',
requireAuth(),
requireTenant(
(req) => req.params.org,
(req) => req.params.service
),
(req, res) => { ... }
);
The middleware functions check claims embedded in the JWT by the client SDK during login:
| SDK Initialization | JWT Claims | Middleware to Use |
|-------------------|-----------|------------------|
| Platform-level (baseURL only) | is_platform_owner: true | requirePlatformOwner() |baseURL
| Org-level ( + org) | org: 'slug' | requireOrganization() |baseURL
| Service-level ( + org + service) | org: 'slug', service: 'app' | requireTenant() or requireService() |permissions: ['users:write', ...]
| With permissions | | requirePermission() |
1. Client-side: User logs in via @drmhse/sso-sdk or @drmhse/authos-reactorg
2. JWT issued: AuthOS embeds context (, service, is_platform_owner) in claims
3. Server-side: This package verifies the JWT and middleware checks the claims
`ts
// Example: Route for tenant-specific data
app.get('/orgs/:org/services/:service/data',
requireAuth(), // 1. Verify JWT signature
requireTenant( // 2. Check org + service claims
(req) => req.params.org,
(req) => req.params.service
),
(req, res) => {
// User is authenticated AND belongs to this org+service
res.json({
org: req.auth?.claims.org,
service: req.auth?.claims.service
});
}
);
// Example: Route for platform owners only
app.get('/platform/analytics',
requireAuth(), // 1. Verify JWT signature
requirePlatformOwner(), // 2. Check is_platform_owner: true
(req, res) => {
// User is a platform owner
res.json({ data: '...' });
}
);
`
Verify webhooks from AuthOS:
`ts
import { verifyWebhookSignature } from '@drmhse/authos-node';
app.post('/webhooks/authos', (req, res) => {
const signature = req.headers['x-authos-signature'];
const payload = JSON.stringify(req.body);
try {
const isValid = verifyWebhookSignature(payload, signature, {
secret: process.env.WEBHOOK_SECRET!
});
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook
res.json({ received: true });
} catch (err) {
res.status(400).json({ error: 'Webhook verification failed' });
}
});
`
If you need to verify webhooks from your own services:
`ts
import { createWebhookSignature } from '@drmhse/authos-node';
const payload = JSON.stringify({ event: 'user.created' });
const signature = createWebhookSignature(payload, 'your_secret');
`
Creates a JWT token verifier that fetches JWKS from AuthOS.
`ts
import { createTokenVerifier, clearJWKSCache } from '@drmhse/authos-node';
const verifier = createTokenVerifier({
baseURL: 'https://sso.example.com',
// Optional: cache time in seconds
cacheTimeSeconds: 300
});
const verified = await verifier.verifyToken(token);
// Clear cache to force JWKS refresh
clearJWKSCache();
`
Returns:
- verifyToken(token) - Verifies a JWT and returns claimssub
- Claims include: , email, is_platform_owner, org, permissions
| Code | Description |
|------|-------------|
| MISSING_TOKEN | No Bearer token provided |INVALID_TOKEN
| | Token is malformed or expired |NOT_AUTHENTICATED
| | No auth info on request |PERMISSION_DENIED
| | User lacks required permission |NOT_PLATFORM_OWNER
| | User is not a platform owner |WRONG_ORGANIZATION` | User is not in required organization |
|
MIT © DRM HSE