Multi-Tenancy
VentureKit provides multi-tenancy support through @venturekit-pro/tenancy with flexible tenant resolution, data isolation, and quota enforcement.
npm install @venturekit-pro/tenancy@devTenant Resolution Strategies
Section titled “Tenant Resolution Strategies”VentureKit supports multiple ways to identify the current tenant:
| Strategy | Example | Use Case |
|---|---|---|
subdomain | acme.app.example.com | SaaS with subdomains |
custom-domain | app.acme.com | White-label support |
path | /t/acme/api/tasks | Shared domain |
header | X-Tenant-ID: acme | API-first apps |
jwt | tenant_id claim | Token-based |
Adding Tenant Middleware
Section titled “Adding Tenant Middleware”import { handler } from '@venturekit/runtime';import { createTenantMiddleware } from '@venturekit-pro/tenancy';
export const main = handler(async (_body, ctx, logger) => { const tenant = ctx.tenant!; logger.info('Request for tenant', { tenantId: tenant.id, slug: tenant.slug });
return { tenantId: tenant.id };}, { scopes: ['api.read'], middleware: [ createTenantMiddleware({ strategy: 'subdomain' }), ],});Quota Enforcement
Section titled “Quota Enforcement”Enforce per-tenant usage limits:
import { createQuotaMiddleware, checkQuotas } from '@venturekit-pro/tenancy';
// As middleware (automatic per-request)export const main = handler(async (_body, ctx, logger) => { return { ok: true };}, { scopes: ['api.read'], middleware: [ createTenantMiddleware({ strategy: 'subdomain' }), createQuotaMiddleware(), ],});
// Programmatic checkawait checkQuotas(tenantId, { apiRequests: { limit: 10000, period: 'month' }, storage: { limit: 5_000_000_000 }, // 5 GB});Tenant Context
Section titled “Tenant Context”Access tenant information anywhere in your handler:
import { getCurrentTenant } from '@venturekit-pro/tenancy';
const tenant = getCurrentTenant(ctx);// { id: 'acme', slug: 'acme', metadata: { plan: 'pro', ... } }Error Handling
Section titled “Error Handling”The tenancy package provides specific error types:
import { TenantNotFoundError, TenantSuspendedError, TenantInactiveError, QuotaExceededError,} from '@venturekit-pro/tenancy';These errors are automatically caught by the error boundary and returned as structured JSON responses with appropriate HTTP status codes.
WebSocket Multi-Tenancy
Section titled “WebSocket Multi-Tenancy”For real-time WebSocket apps, pass tenantId during authentication:
{ "action": "auth", "token": "<jwt>", "tenantId": "acme" }Then use the connectionStore for tenant-scoped messaging:
import { connectionStore } from '@venturekit/runtime';
// Broadcast within a tenantawait connectionStore.sendToTenant(domainName, stage, tenantId, data);
// Query tenant connectionsconst connections = await connectionStore.getByTenant(tenantId);