@drmhse/authos-node

Node.js adapter for AuthOS.

Updated Dec 31, 2025 Edit this page

@drmhse/authos-node

npm version License: MIT

Node.js server adapter for AuthOS - the multi-tenant authentication platform. Provides JWT verification, webhook signature validation, and Express middleware.

Installation

npm install @drmhse/authos-node

For Express middleware:

npm install @drmhse/authos-node express

Quick Start

JWT Token Verification

Verify JWT tokens issued by AuthOS:

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']
// }

TypeScript Integration

The req.auth type is automatically augmented when you import from @drmhse/authos-node/express. No manual setup required!

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:

import { TokenClaims, VerifiedToken } from '@drmhse/authos-node';

function processUser(auth: VerifiedToken) {
  console.log(auth.claims.email);
}

Express Middleware

Protect your Express routes with AuthOS authentication:

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

Middleware Reference

requireAuth(options?)

Requires a valid JWT token. Adds req.auth with verified token info.

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

requirePermission(permission, options?)

Requires the user to have a specific permission.

app.post('/admin/users',
  requireAuth(),
  requirePermission('users:create'),
  (req, res) => { ... }
);

Options:

Option Type Default Description
message string “Insufficient permissions” Custom error message

requireAnyPermission(permissions, options?)

Requires the user to have at least one of the specified permissions.

app.get('/reports',
  requireAuth(),
  requireAnyPermission(['reports:read', 'reports:admin']),
  (req, res) => { ... }
);

requireAllPermissions(permissions, options?)

Requires the user to have all of the specified permissions.

app.post('/admin/settings',
  requireAuth(),
  requireAllPermissions(['admin:access', 'settings:write']),
  (req, res) => { ... }
);

requirePlatformOwner(options?)

Requires the user to be a platform owner.

app.get('/platform/settings',
  requireAuth(),
  requirePlatformOwner(),
  (req, res) => { ... }
);

requireOrganization(slug, options?)

Requires the user to belong to a specific organization.

app.get('/org/:slug/data',
  requireAuth(),
  requireOrganization((req) => req.params.slug),
  (req, res) => { ... }
);

Understanding JWT Context

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()
Multi-tenant (baseURL + org + service) org: 'slug' requireOrganization()
With permissions permissions: ['users:write', ...] requirePermission()

How It Works

  1. Client-side: User logs in via @drmhse/sso-sdk or @drmhse/authos-react
  2. JWT issued: AuthOS embeds context (org, service, is_platform_owner) in claims
  3. Server-side: This package verifies the JWT and middleware checks the claims
// Example: Route for organization admins only
app.get('/org/:slug/settings',
  requireAuth(),                                    // 1. Verify JWT signature
  requireOrganization((req) => req.params.slug),   // 2. Check org claim matches URL
  (req, res) => {
    // User is authenticated AND belongs to this org
    res.json({ org: req.auth?.claims.org });
  }
);

// 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: '...' });
  }
);

Webhook Verification

Verify webhooks from AuthOS:

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' });
  }
});

Creating Webhook Signatures

If you need to verify webhooks from your own services:

import { createWebhookSignature } from '@drmhse/authos-node';

const payload = JSON.stringify({ event: 'user.created' });
const signature = createWebhookSignature(payload, 'your_secret');

API Reference

createTokenVerifier(options)

Creates a JWT token verifier that fetches JWKS from AuthOS.

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 claims
  • Claims include: sub, email, is_platform_owner, org, permissions

Error Codes

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

License

MIT © DRM HSE