Tenancy
Tenancy
Tenant isolation is a first-class runtime concern. Many views depend on request.tenant, X-Tenant-ID, and tenant membership checks to determine what the caller can see or mutate.
Core building blocks
api.tenancy.middleware.TenantMiddlewareresolves the current tenant for the request.api.tenancy.middleware.TenantRequiredMiddlewareenforces tenant presence for paths that need it.api.tenancy.models.TenantandTenantMembershipown the workspace and membership records.api.permissions.IsTenantMemberandIsTenantManagerenforce role-based access.api/views/tenant_views/*expose the tenant CRUD and membership API.
Membership semantics
The repository uses tenant membership in several ways:
- Microsoft auth auto-creates membership when a user signs in with a Microsoft tenant.
- Billing and org invite endpoints require membership to the current tenant.
- Activity logs allow staff users or tenant managers/admins.
- Document processing and schema management are tenant scoped even when the route itself is global.
TenantMembership is the primary authorization record. The current tenant is usually pulled from middleware, not from ad hoc route parameters.
Tenant viewset family
The tenant route family is split by responsibility:
TenantViewSet— tenant CRUD and list/detail operations.TenantMembershipViewSet— membership list/create/update/delete and nested member routes.- tenant mixins — branding and tenant switching helpers.
This separation matters because membership operations use different authorization rules from tenant CRUD.
Request flow
flowchart TD A[HTTP request] --> B[TenantMiddleware] B --> C{X-Tenant-ID or session tenant?} C -->|resolved| D[request.tenant set] C -->|missing| E[TenantRequiredMiddleware may reject] D --> F[View checks membership/role] F --> G[Tenant-scoped queryset or mutation]Invariants
- Tenant-scoped endpoints should not assume the current tenant comes from the URL.
- Membership checks happen in permissions and sometimes again inside the view when the business rule is stricter than the permission class.
- Background workers do not have the request context that middleware provides, so worker code often has to use
all_objectsor explicit tenant keys.
Validation
tests/unit/auth/test_auth_and_tenancy_contracts.py— cross-checks auth and tenant isolation contracts.tests/unit/auth/test_ms_tenant_org.py— Microsoft-driven tenant creation and binding.tests/integration/test_viewsets.py— nested route behavior for tenant endpoints.
Scope boundary
This page documents the tenant isolation layer. For org invitations, read Organization settings. For billing usage, read Billing. For tenant-aware processing documents, read Document processing.