Multi-tenancy & isolation
Ticketra is multi-tenant: each tenant is an isolated workspace. This page explains the isolation model so you can reason about who can see what.
Two kinds of users
| User kind | tenant_id | Scope |
|---|---|---|
| Tenant user | a tenant's ID | Restricted to that tenant's data, at both the API and database level. |
| System user | NULL | Operates across all tenants (e.g. a central security team or MSSP). |
What's isolated
Users, cases, schemas, observables, and their related records are scoped per tenant. A tenant user cannot read or write another tenant's data — isolation is enforced in the query layer, not just the UI.
How tenant context is resolved
The effective tenant for a request is resolved server-side:
- Tenant users are pinned to their own
tenant_idfrom their session — they cannot escape it. - System users select a tenant to operate in. For normal REST calls this is passed as an
X-Tenant-Idheader; for real-time SSE streams (where the browser cannot set custom headers) it is passed as a?tenantId=query parameter and validated server-side.
System users can view tenant cases, and their presence/avatars are visible across tenants (so analysts can see who's helping). Tenant users can see system users' avatars for presence, but never another tenant's data.
Logging in to a specific tenant
A tenant user logs in with a tenant-qualified username of the form tenant_slug/username. A bare username is treated as a system user login.
Why this design
Whether you run a single team or many — an enterprise SOC with separate business units, or an MSSP serving multiple clients — hard tenant isolation with a thin cross-tenant operator layer gives the benefits of a shared deployment (one stack to run and back up) without the data-bleed risk of a single shared workspace.