Scale
Enterprise
Optional governance layered above Workspace. Every organization-level dashboard is read-aggregation only — zero write paths into workspace-scoped tables.
Organizations & Departments
One Organization row per enterprise customer, aggregating workspaces. Departments are unlimited and fully custom (free-text name), each owning zero or more workspaces, with managers/members and an optional cost center + monthly budget for billing rollups. A workspace is attached only when the caller holds org.manage_workspaces on the organization and is OWNER of the workspace — an organization can never annex a workspace its admin doesn't own.
Cross-workspace aggregation (read-only)
org-console.ts / org-analytics.ts / org-billing.ts / org-security.ts / org-audit.ts / org-search.ts
→ orgWorkspaceIds(organizationId)
→ filter every Prisma query by { workspaceId: { in: wsIds } }
→ zero write pathsSSO
Every identity provider is a metadata entry over the same IdentityProvider row — adding a provider is a registry entry, never a code branch:
All seven OIDC-family providers run the live interactive login flow today; SAML is fully declared (metadata URL, entity ID, SSO URL, signing certificate) but its interactive AuthnRequest/Response codec is not yet wired. Login-time domain discovery and the ticket-exchange flow are covered on the Authentication page.
SCIM
Provider-agnostic SCIM 2.0 (RFC 7643/7644) for automated user/group lifecycle from any compliant IdP (Okta, Entra ID, OneLogin, JumpCloud…). Every request needs Authorization: Bearer <token> — tokens are minted per-organization, shown once, and stored only as a SHA-256 hash.
| GET | /api/scim/v2/Users | List/filter users |
| POST | /api/scim/v2/Users | Provision a user |
| GET | /api/scim/v2/Users/{id} | Fetch one user |
| PATCH | /api/scim/v2/Users/{id} | SCIM PatchOp — active (deactivate) / displayName |
| DELETE | /api/scim/v2/Users/{id} | Deactivate (soft) |
| GET | /api/scim/v2/Groups | List/filter groups |
| POST | /api/scim/v2/Groups | Create a group (→ Department) with initial members |
| PATCH | /api/scim/v2/Groups/{id} | Add/replace members operations |
Groups map to Departments. Deactivating a user via SCIM kills their live sessions.
RBAC
Two independent ladders: WorkspaceRole (9 roles, permission matrix below) governs one workspace; OrganizationRole is a separate system governing the organization itself. Org permissions never grant workspace access, and vice versa — the only bridge is the ownership check in attachWorkspaceToOrg.
| Role | Permissions |
|---|---|
| OWNER | All permissions |
| ADMIN | view_analytics, manage_bots, manage_modules, view_customers, manage_commerce, manage_broadcast, manage_tickets, manage_referrals, manage_inbox, view_audit, manage_ai, manage_settings, manage_api, manage_prompts, manage_knowledge_base, manage_agents |
| DEVELOPER | view_analytics, manage_bots, manage_modules, manage_api |
| MODERATOR | view_analytics, view_customers, manage_tickets, manage_inbox, manage_broadcast, manage_referrals |
| SUPPORT_AGENT | manage_tickets, manage_inbox, view_customers |
| AFFILIATE_MANAGER | view_analytics, manage_referrals |
| VIEWER | view_analytics |
| AUDITOR | view_audit |
Policies
Enterprise policies (e.g. AI provider/model allow-lists enforced by assertOrgAiPolicy in the AI Runtime) are declared as registry metadata in src/lib/enterprise/policy-registry.ts and apply consistently across every workspace in the organization — never configured per-workspace.