Scaling Onyx for Multiple Organizations
Multi-tenancy allows a single Onyx instance to serve multiple organizations (tenants) while keeping their data completely isolated. This architecture is perfect for SaaS deployments where each customer needs their own secure knowledge base.
Share infrastructure costs across multiple tenants while maintaining isolation
Complete data isolation between tenants at database and application level
Centralized admin portal for managing all tenants from one place

The top-level administrative interface that provides complete control over all tenants:
Core services that are shared across all tenants but maintain logical separation:
SSO/SAML integration with tenant-specific identity providers
Role-based access control (RBAC) scoped to each tenant
Tenant-isolated metrics with optional cross-tenant insights
Tenant-specific settings and customizations
Each tenant operates in complete isolation with dedicated resources:
Dedicated database schema with row-level security. Complete data isolation at the database level.
Separate search index for each tenant. No cross-tenant search contamination.
Isolated file storage with tenant-specific encryption keys.
Tenant-scoped API routes with automatic tenant context injection.
-- Example: Create tenant-specific schema
CREATE SCHEMA tenant_abc;
-- Set search path for tenant sessions
SET search_path TO tenant_abc, public;
-- Row-level security policies
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON documents
FOR ALL USING (tenant_id = current_setting('app.tenant_id'));# FastAPI middleware example
@app.middleware("http")
async def inject_tenant_context(request: Request, call_next):
tenant_id = extract_tenant_from_subdomain(request.url)
# or extract from JWT token
request.state.tenant_id = tenant_id
response = await call_next(request)
return response# Configure separate Vespa application per tenant vespa deploy --tenant tenant-abc --application-id onyx-abc # Or use namespace isolation within single Vespa cluster document.namespace = "tenant_abc"