Multi-Tenancy
Use namespaces and principal-derived scope to keep tenant data isolated by default.
For SaaS apps, the recommended path is to derive tenant scope from the authenticated principal and let namespaces enforce it automatically.
entity Organization {
name: string,
slug: string @unique,
}
entity Project {
name: string,
organizationId: Organization.id,
}
namespace Tenant {
scope: principal.organizationId,
entities: [Project],
}Why Namespaces Matter
In a typical SaaS stack, developers remember to add tenant filters in some places and forget them in others. Namespaces change the model. Tenant scope is no longer a convention in application code. It becomes a platform-level rule applied everywhere the entity is used.
That means your app code can stay focused on product logic rather than repeating organizationId filters on every screen and server function.
Add The Scope To Principal
auth {
providers: [email],
principal {
organizationId: Organization.id @from(Profile.organizationId),
}
}If users can switch organizations, the current organization should still become a single principal value for the request or session context. That keeps the rest of the app deterministic.
Result
Any query against Project now inherits tenant scoping. You do not manually thread tenant filters through every handler and browser query.
Recommended Design Pattern
- create an explicit top-level tenant entity such as
Organization - use membership entities to connect users to tenants
- project the current tenant into the principal
- namespace the app entities that belong inside the tenant boundary
This is usually enough to support the first serious version of a SaaS product.