TenancyJS
Core Concepts

How it works

The four pieces of TenancyJS and how tenant context flows from a request to a scoped query.

TenancyJS is a small set of composable pieces, each with one job. Understanding how they fit makes everything else in these docs click.

The four pieces

The flow of a request

Here's what happens on a normal request, end to end:

A request arrives

Your integration middleware runs first. It calls your resolver to turn the request into a tenant (from a subdomain, header, path, or claim).

Identity is validated

If the tenant is unknown, suspended, or ambiguous, the request fails closed with the right status (400/404) - before any handler runs. No unscoped request reaches your code.

A tenant scope opens

The integration calls manager.runWithTenant(tenant, …), which stores the tenant in AsyncLocalStorage for the lifetime of the request.

Queries are scoped automatically

Inside that scope, every query through a registered adapter is filtered to the tenant. On SQL, the database's forced RLS is a second backstop. Outside a scope, adapters throw.

The scope tears down

When the request ends - success or error - the scope is disposed. Nothing leaks to the next request.

Where isolation is actually enforced

TenancyJS deliberately enforces at more than one layer, so a single mistake can't cause a leak:

LayerWhat it does
ContextNo valid tenant scope → the adapter throws (fail-closed)
Adapter facadeInjects the tenant filter on reads, the tenant field on writes; rejects unsafe criteria
Database (SQL)Forced Postgres RLS rejects cross-tenant rows even under raw SQL
Store boundaryA bring-your-own store that returns the wrong tenant is rejected before anything acts on it

What TenancyJS does not own

  • Auth. Tenant identity is not authorization - your app decides what a user may do within a tenant.
  • Your database. It orchestrates and delegates (to your store and migrator); it doesn't host tenants.

Read on: Tenant context goes deep on the fail-closed model, and the Capability matrix shows exactly what's proven per adapter.

On this page