Multi-tenancy
for Node.js

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.

npm install @stratum-hq/lib @stratum-hq/core pg
CI statusTypeScript 100 percent

Built for hierarchical tenant architectures

Every feature maps to a real problem in multi-tenant SaaS, not a marketing checklist.

Tenant Hierarchy

Tree-structured tenants backed by a PostgreSQL ltree materialized path. Advisory locks serialize create and move so concurrent writes cannot corrupt the tree. Ancestor and subtree queries resolve from the path, not recursive joins.

Config Inheritance

Values flow root to leaf automatically. Children inherit, override, or are blocked by a locked key. Batch updates apply with partial success, so one bad key does not abort the whole transaction.

Three Isolation Strategies

Shared tables with RLS, schema-per-tenant, or database-per-tenant. Choose per tenant, and mix strategies in a single deployment as compliance requirements evolve.

isolation model
shared RLSrow_security = on · lowest cost
schemasearch_path = tenant_slug
databaseseparate PG instance · strongest
stratum.setIsolation(tenantId, "schema")
// switch strategies without a data migration

Permission Delegation

LOCKED, INHERITED, or DELEGATED modes. Cascade, soft, or permanent revocation. Fine-grained control at every node of the tree.

Field Encryption + GDPR

AES-256-GCM for sensitive values at rest. Data export (Article 20) and hard purge (Article 17). Consent tracking with an audit trail.

Audit + Observability

Every mutation logged with actor identity. Optional OpenTelemetry tracing. Redis-backed rate limiting and webhook delivery with a dead-letter queue.

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

setup.ts
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);
max_users: 1000, inherited: true, source: "acmesec"resolved from d0

13 packages. Pick what you need.

All published to npm under @stratum-hq/*

@stratum-hq/coreShared types, Zod schemas, error classes. Everything depends on it.foundationnpm →
@stratum-hq/libThe core library: tenants, config, ABAC, permissions, audit, GDPR, webhooks, crypto.start herenpm →
@stratum-hq/control-planeFastify v5 REST API with auth, scopes, OpenTelemetry, and Redis rate limiting.npm →
@stratum-hq/sdkHTTP client for the control plane, LRU cache, Express and Fastify middleware.npm →
@stratum-hq/db-adaptersPostgreSQL: raw pg, Prisma, Sequelize, Drizzle, plus RLS and schema isolation.npm →
@stratum-hq/mongodbMongoDB tenant isolation with a Mongoose plugin.npm →
@stratum-hq/mysqlMySQL isolation with TypeORM, Knex, and Sequelize helpers.newnpm →
@stratum-hq/nestjsNestJS guard, @Tenant() decorator, DI module.npm →
@stratum-hq/honoHono middleware with AsyncLocalStorage context.npm →
@stratum-hq/test-utilsCross-tenant isolation test assertions.npm →
@stratum-hq/reactReact admin components: tenant tree, config editor, permission editor.npm →
@stratum-hq/cliProject init, migrate, scaffold, doctor.npm →
@stratum-hq/createProject scaffolding: npx @stratum-hq/create my-app.npm →

Start building.

Get Started