Stratum: multi-tenancy for Node.js

npm install @stratum-hq/lib pg
 d0 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.

  1. 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 ltree column, 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.

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

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

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

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

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

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

Start building.