🗄️ Database

Multi-Schema Tenancy

Database-level tenant isolation strategies.

Tenant Isolation Models

ModelDescriptionIsolationComplexity
Shared SchemaAll tenants in one DBLowLow
Schema per TenantSeparate schema per tenantMediumMedium
DB per TenantSeparate databaseHighHigh

Gauzy's Approach: Shared Schema with Row-Level Security

Gauzy uses a shared schema model with tenantId on every entity:

export abstract class TenantBaseEntity extends BaseEntity {
  @MultiORMColumn()
  tenantId: string;

  @MultiORMManyToOne(() => Tenant)
  tenant: Tenant;
}

Automatic Tenant Filtering

Every query is automatically scoped to the current tenant via:

  1. TenantPermissionGuard — extracts tenantId from JWT
  2. RequestContext — stores tenant info for the request lifecycle
  3. Service base class — applies tenant filter to all queries
// In TenantAwareCrudService
async findAll(filter: any): Promise<IPagination<T>> {
  const tenantId = RequestContext.currentTenantId();
  return super.findAll({
    ...filter,
    where: { ...filter.where, tenantId },
  });
}

PostgreSQL Row-Level Security (Advanced)

For additional database-level enforcement:

ALTER TABLE employee ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON employee
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

Cross-Tenant Queries (Admin)

Super admin can query across tenants:

if (RequestContext.hasRole(RolesEnum.SUPER_ADMIN)) {
  // Skip tenant filter
  return super.findAll(filter);
}

Edit this page

Copyright © 2023-Present Ever Co. LTD.Docs by Sourcey