Architecture

Authentication & multi-tenancy

Identity, roles, organization scoping, the operator vs GP contexts, plan gating, and the tenant lifecycle.

Authentication is built on better-auth (@repo/auth) with a Drizzle adapter. The same auth layer provides organizations, memberships, and the operator capabilities the Command Center relies on.

Identity & sessions

A signed-in user has a session row carrying a userId, an activeOrganizationId (the tenant the session is currently acting within), and optionally an impersonatedBy value for operator support sessions. On sign-in, activeOrganizationId is hydrated from the user's lastActiveOrganizationId so a returning user lands back in their organization.

Supported methods are email + password, magic links, passkeys, and two-factor; no third-party identity providers are offered. Self-serve signup is disabled. The platform is invitation-only, so new users arrive through an organization invitation.

Two kinds of role

The platform separates a global role from an organization role:

RoleWhereMeaning
user.role = 'admin'Global (on the user)Platform operator. Unlocks the Command Center and all cross-tenant procedures.
member.rolePer organizationowner, admin, or member within that organization. Gates fund-level actions like inviting members or managing policies.

A helper treats a user as an organization admin if they are an owner/admin member or a global platform admin.

Operator context vs GP workspace

Operator (Command Center)GP user (workspace)
Identifying roleGlobal adminOrganization member
Active organizationOrg-agnostic; acts across tenantsAlways scoped to one organization
Routes/operator/*, /admin/*/{organizationSlug}/*
Data reachAll tenants, via audited proceduresOnly their organization's data

Operator routes are guarded in the layout: a non-admin visiting /operator is redirected away.

Admin/operator access additionally requires two-factor authentication to be enabled on the account (enforced by default). A platform admin who hasn't set up 2FA is redirected to /admin-2fa-required instead of reaching /admin or /operator.

Organization scoping

Tenant isolation is enforced in the API, not left to the UI. Org-scoped procedures resolve an acting organization from the session (or, for operators, from an explicit context) and reject the call if the caller is not a member. Knowledge queries additionally filter on tenantScope and organizationId, so one tenant can never retrieve another tenant's documents.

Global knowledge (the operator-managed library) is readable by every tenant by design. It is the shared playbook. Organization-scoped knowledge is visible only within its own organization.

Plan-based feature gating

Each organization has a plan tier that gates features and sets usage limits:

PlanAdvisorPolicy HubLP ReportingMonthly run cap
bot_only✔ (global playbook only)——500
policy_hub✔ (org + global)✔—2,000
full✔ (org + global)✔✔ (flag also required)10,000

LP Reporting is gated twice: the full plan and the per-organization lp_reporting feature flag. Both the server (requireReportingPlan) and the navigation model check both, so a tenant with only one of the two never sees reporting routes it cannot use.

FlagControls
lp_reportingThe LP Reporting route group and its nav items
advisor_hubAdvisor hub surfaces, including operator Retrieval Preview
advisor_guidanceFolder Registry and Advisor Guide

Flags are resolved per organization and fail closed — an unset flag is off.

Gating is enforced in two places: API middleware (a plan backstop and a usage-cap check that runs before any metered AI call) and the workspace navigation, which only shows features the plan includes. A request that exceeds the monthly run cap is rejected before it spends; a request that cannot resolve an organization is rejected as well. The effective cap is the explicit usageCounter.runsCap if set, then the operator's per-organization allowance (organization.aiRunsCapOverride, set on the organization's Usage tab), otherwise the plan default.

Tenant lifecycle

An organization is active, inactive (no members), or suspended:

  • Suspend sets organization.suspendedAt. The workspace layout reads this and blocks entry for that tenant's users.
  • Reactivate clears suspendedAt.

Both actions are operator-only and recorded in the audit log. See the runbook on plans & lifecycle.

Support sessions (join as support)

Operators can open a support session to view the product as a specific user inside a tenant. The flow records support.impersonation_started in the audit log (with the operator's identity and an optional reason), sets session.impersonatedBy, and acts as the target user until the operator ends the session, which records support.impersonation_ended. The original operator is always the recorded actor, so impersonated actions remain attributable.

On this page