basalt / prisma/src / TenancyExtensionOptions
Interface: TenancyExtensionOptions
Defined in: prisma/src/extension.ts:358
Properties
getTenantId?
> optional getTenantId?: () => string | undefined
Defined in: prisma/src/extension.ts:362
How to obtain the current tenant id. Default: reads ctx().tenant.id
Returns
string | undefined
onMissingTenant?
> optional onMissingTenant?: "error" | "bypass"
Defined in: prisma/src/extension.ts:374
Behavior when there is no tenant in scope:
- 'error' (default): throw PRISMA_TENANT_MISSING — fail closed, so a query that runs without a tenant can never leak/mutate across tenants.
- 'bypass': run the query UNSCOPED — opt-in, for explicit central/admin code paths only (wrap them in a context with no tenant deliberately).
Security
Defaults to 'error'. Do NOT set 'bypass' globally — it disables tenant isolation whenever a tenant isn't resolved (a forgotten job context, an unauthenticated route), returning every tenant's rows.
onRawInTenant?
> optional onRawInTenant?: "error" | "allow"
Defined in: prisma/src/extension.ts:389
Behavior for raw methods ($queryRaw/$queryRawUnsafe/$executeRaw/ $executeRawUnsafe/$queryRawTyped/$runCommandRaw, every other client-level operation, and the MongoDB model-level findRaw/aggregateRaw) invoked WHILE a tenant is in scope — these bypass the model-level scoping and would touch every tenant's rows:
- 'error' (default): throw PRISMA_RAW_IN_TENANT — fail closed.
- 'allow': run the raw query as-is (only for queries you have already scoped by tenant by hand).
Raw queries with NO tenant in scope are always allowed (central/admin code).
Security
Defaults to 'error'. Do not set 'allow' globally.
rls?
> optional rls?: boolean | RlsExtensionOptions
Defined in: prisma/src/extension.ts:406
Postgres Row-Level Security, applied automatically. With rls on, every model operation in tenant scope runs as a batch transaction whose first statement is set_config('<setting>', <tenantId>, true) — so the policies installed by rlsPolicySql filter the rows in the database too, even for a query the application layer cannot scope (an include that follows a cross-tenant foreign key, for example).
Costs: one extra statement per operation (same round-trip batch), and every tenant-scoped operation becomes a (short) transaction. Operations already inside a transaction are NOT wrapped again — open interactive transactions with tenantTransaction, and lead a batch $transaction([...]) with the set_config statement yourself.
true uses the default setting app.tenant_id.
tenantField?
> optional tenantField?: string
Defined in: prisma/src/extension.ts:360
Column holding the tenant id. Default: 'tenantId'