Stratum: multi-tenancy for Node.js
npm install @stratum-hq/lib pgd0 AcmeSec / root tenant [DB] d1 NorthStar MSP / reseller [SCHEMA] >> data_region LOCKED at d1 << d2 client-alpha / client [SCHEMA] d2 client-beta / client [RLS] d3 team-eng / team [RLS] d3 team-ops / team [RLS] [DB] database per tenant [SCHEMA] schema per tenant [RLS] shared RLS locked key
When customers need tenants inside tenants, resellers, agencies, enterprise org trees, a tenant_id column stops working. Stratum is the full tenant layer: hierarchy, config inheritance, isolation strategies, and compliance. Start flat, grow deep.
The layers
Built for hierarchical tenant architectures. Every feature maps to a real problem in multi-tenant SaaS, not a marketing checklist.
Tenant hierarchy
Nest tenants as deep as your customers need: resellers, their clients, and the teams inside them. Concurrent writes cannot corrupt the tree.
Each tenant stores its path from the root in a PostgreSQL
ltreecolumn, a materialized path. Ancestor and subtree queries read that path instead of running recursive joins. Advisory locks, held for one transaction, serialize create and move.Config inheritance
Set a value once and every descendant gets it. A parent can lock a key so that no child can change it.
Values flow root to leaf. Children inherit, override, or are blocked by a locked key. Batch updates are atomic: if one key is locked or invalid, nothing is written, and the result names that key.
Permission delegation
Decide at every node of the tree what the tenants below it can change.
A LOCKED permission holds for every descendant. INHERITED and DELEGATED permissions flow down, and a descendant can override them. Revocation is cascade (remove it from the whole subtree), soft (remove it only where it was set), or permanent (it cannot be revoked).
Three isolation strategies
Give each tenant the isolation its compliance requirements call for, and mix strategies in one deployment.
Shared tables with RLS (row-level security, where PostgreSQL filters every row by tenant) cost the least. Schema-per-tenant gives a tenant its own schema. Database-per-tenant gives it its own database, the strongest separation.
- [RLS]SHARED_RLSrow_security = on
- [SCHEMA]SCHEMA_PER_TENANTsearch_path = tenant_slug
- [DB]DB_PER_TENANTdedicated database
Audit, GDPR and encryption
Know who changed what, and answer GDPR export and erasure requests without building the tooling yourself.
Every mutation is logged with the actor's identity. Data export (Article 20) and hard purge (Article 17) are built in, with consent tracking and an audit trail. AES-256-GCM encrypts sensitive values at rest. Optional OpenTelemetry tracing, Redis-backed rate limiting, and webhook delivery with a dead-letter queue.
Eight lines
Eight lines to a working hierarchy. Connect a Postgres pool, create tenants with parent references, and config resolves automatically up the tree. No migrations to hand-write, no join tables to manage.
import { Pool } from "pg";
import { Stratum } from "@stratum-hq/lib";
const stratum = new Stratum({ pool: new Pool(), autoMigrate: true });
await stratum.initialize();
// Create a hierarchy
const root = await stratum.createTenant({ name: "AcmeSec", slug: "acmesec" });
const msp = await stratum.createTenant({ name: "NorthStar", slug: "northstar", parent_id: root.id });
// Config resolves up the ancestry chain
await stratum.setConfig(root.id, "max_users", { value: 1000, locked: false });
const config = await stratum.resolveConfig(msp.id);→ config.max_users = { value: 1000, inherited: true, source_tenant_id: root.id } resolved from d0
File area
14 packages, all published to npm under @stratum-hq/*. Pick what you need.
| Name | Description | Link |
|---|---|---|
| @stratum-hq/core | Shared types, Zod schemas, error classes. Everything depends on it.[ foundation ] | npm » |
| @stratum-hq/lib | The core library: tenants, config, ABAC, permissions, audit, GDPR, webhooks, crypto.[ start here ] | npm » |
| @stratum-hq/control-plane | Fastify v5 REST API with auth, scopes, OpenTelemetry, and Redis rate limiting. | npm » |
| @stratum-hq/sdk | HTTP client for the control plane, LRU cache, Express and Fastify middleware. | npm » |
| @stratum-hq/db-adapters | PostgreSQL: raw pg, Prisma, Sequelize, Drizzle, plus RLS and schema isolation. | npm » |
| @stratum-hq/mongodb | MongoDB tenant isolation with a Mongoose plugin. | npm » |
| @stratum-hq/mysql | MySQL isolation with TypeORM, Knex, and Sequelize helpers. | npm » |
| @stratum-hq/nestjs | NestJS guard, @Tenant() decorator, DI module. | npm » |
| @stratum-hq/hono | Hono middleware with AsyncLocalStorage context. | npm » |
| @stratum-hq/test-utils | Cross-tenant isolation test assertions. | npm » |
| @stratum-hq/compliance | Compliance kernel: coverage scoring, a finding state machine, control types. No runtime dependencies. | npm » |
| @stratum-hq/react | React admin components: tenant tree, config editor, permission editor. | npm » |
| @stratum-hq/cli | Project init, migrate, scaffold, doctor. | npm » |
| @stratum-hq/create | Project scaffolding: npx @stratum-hq/create my-app. | npm » |
Start building.
- MIT licensed, with every line of the source on GitHub.
- Integration tests run against real PostgreSQL, MongoDB and MySQL in CI.
- Try it in the browser Playground before you install anything.