How does tenant isolation work?
Short answer
Section titled “Short answer”Every request to Notory runs in the context of exactly one tenant — derived from
the sign-in token, not from a selectable setting. Separation is enforced on two
layers: in the application (every query filters on tenant_id) and in the
database via row-level security (RLS). Even a faulty application filter couldn’t
expose another tenant’s data as a result. Only super admins deliberately bypass
this barrier.
Requirements
Section titled “Requirements”The isolation layers in detail
Section titled “The isolation layers in detail”1. The tenant is embedded in the token
Section titled “1. The tenant is embedded in the token”At login, your account’s tenant_id is written permanently into the session token
(JWT); for an API token, it’s stored fixed on the
token itself. The server reads the tenant exclusively from this proof — there is
no header and no parameter that could be used to “request” a different tenant.
2. Row-level security in the database
Section titled “2. Row-level security in the database”At the start of every request, Notory sets the database session’s RLS context to your tenant. PostgreSQL then hides all rows belonging to other tenants — at the database level, below the application. As a result, a bug in a query can’t return another tenant’s data: the database simply won’t hand it out.
3. Unique accounts, separate configuration
Section titled “3. Unique accounts, separate configuration”- Users belong to exactly one tenant (email is unique system-wide).
- SSO: an account may only sign in through an identity provider belonging to its own tenant — an attempt via a different provider is rejected (“This account does not belong to the selected provider’s tenant”).
- Roles: a role from a different tenant can never be assigned.
- Webhooks, API tokens, custom fields, branding, SSO providers — everything is stored and visible on a per-tenant basis.
4. License intersection
Section titled “4. License intersection”A tenant’s effective entitlements are the intersection of its own plan
(license_tier) and the installation’s product license — including the asset limit.
So a tenant can never obtain “more license” than the installation itself holds.
What happens behind the scenes?
Section titled “What happens behind the scenes?”- Request flow: authentication →
tenant_idextracted from the JWT/API token → RLS context set → only then is data read or written. For API tokens, the scope (read/write) is also checked. - Super admin exception: for super admins, the RLS bypass is set — they see and manage all tenants (e.g. in tenant and user management). This is exactly why there should be very few super admins.
- Auditing stays central: the audit log records actions with
tenant_id, so the instance operator can trace what happened across tenants — entries even survive the deletion of a tenant. - 2FA requirement per tenant:
require_2facan be enforced per tenant (only with a multi-tenant license); instance-wide and tenant-specific requirements are combined with OR. - Recycle bin & retention per tenant: tenants can override the instance defaults for the recycle bin and retention periods.