nest-tenant
Multi-tenant library for NestJS — RLS and schema-per-tenant isolation, AsyncLocalStorage context, ORM adapters, CLI.
View RepositoryAt a glance
Provide drop-in multi-tenancy for NestJS applications with multiple isolation strategies, automatic context propagation, and ORM integration.
NestJS developers building multi-tenant SaaS applications who want configurable tenant isolation without building it from scratch.
- • Row-Level Security (RLS) tenant isolation
- • Schema-per-tenant isolation strategy
- • AsyncLocalStorage-based context propagation
Context
Multi-tenancy is a solved problem, but implementing it correctly requires handling context propagation, database isolation, and ORM integration. Most NestJS projects implement this ad-hoc, leading to bugs and security gaps.
The Problem
Tenant context must flow through the entire request lifecycle without manual passing. Isolation strategies vary by use case—RLS for shared schemas, separate schemas for strict isolation. ORM integrations require middleware hooks.
Approach
nest-tenant uses AsyncLocalStorage to propagate tenant context automatically. Middleware extracts tenant identity from requests and sets context. ORM adapters apply isolation policies transparently. The library is published on npm for easy adoption.
Architecture
The library provides NestJS modules for tenant resolution, context storage, and database isolation. Middleware identifies the tenant from request headers, subdomains, or JWT claims. Context flows through AsyncLocalStorage without explicit passing.
ORM adapters intercept queries and apply tenant filtering. For RLS, they set session variables. For schema isolation, they switch schemas dynamically.
// Middleware sets tenant context
@Injectable()
export class TenantMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const tenantId = extractTenant(req);
TenantContext.run(tenantId, () => next());
}
}Isolation Strategies
RLS isolation uses PostgreSQL policies to filter rows by tenant. The adapter sets `app.tenant_id` session variable before queries. Schema isolation creates separate schemas per tenant—queries target the tenant's schema dynamically.
Both strategies are configurable per-module, allowing mixed isolation within an application.
ORM Integration
Adapters for Drizzle and Prisma apply isolation transparently. Developers query normally; the adapter injects tenant filtering. This prevents accidental cross-tenant data access at the ORM layer.
Tradeoffs
• **NestJS-only**: Tightly coupled to NestJS lifecycle and DI. • **PostgreSQL-focused**: RLS features assume PostgreSQL. Schema isolation works with other databases. • **Runtime overhead**: AsyncLocalStorage and middleware add small per-request overhead.