Skip to content

Enterprise: User & Organization Management (Org/Team + advanced RBAC) on the #847 seam #995

Description

@dolho

Summary

Add Enterprise User Management — multi-tenant Organizations/Teams plus advanced RBAC — as the second concrete enterprise module on the #847 entitlement seam (after the audit dashboard, #941). Entitlement id: user_management.

Today OSS ships a flat 4-tier role model (user < operator < creator < admin, ROLE-001) with admin-only per-user role CRUD and a single user namespace. Enterprise customers need org/team scoping, custom roles, and a permission matrix beyond the 4 built-ins (called out as a reserved-but-unbuilt seam in docs/planning/OSS_ENTERPRISE_SPLIT_RESEARCH.md and requirements §35).

Open-core split (private-first)

Per the enterprise architecture (docs/planning/ENTERPRISE_ARCHITECTURE.md, feature-flows/enterprise-modules.md) and the explicit directive to keep enterprise logic in the private repo, the split is:

  • Private — Abilityai/trinity-enterprise submodule (src/backend/enterprise/backend/user_management/): owns everything with IP — its own private tables (created idempotently on register_enterprise, via from db.connection import get_db_connection), Pydantic models, db ops, service/business logic, and the FastAPI router gated by requires_entitlement("user_management"). Registers the module via entitlement_service.register_module("user_management").
  • Public — Abilityai/trinitydev: only the unavoidable seam. The enterprise Vue view ships in the OSS bundle (documented: enterprise Vue carries no algorithmic IP; gated purely by the server GET /api/settings/feature-flagsenterprise_features list) + nav/route + store getter. No public schema/model/router changes — the entitlement plumbing (requires_entitlement, list_entitled_features, feature-flag exposure) already exists from Spike: enterprise edition architecture — private module strategy for compliance features (SSO, SCIM, SIEM) #847.

Phases

Phase 1a — Organizations + membership (this issue's starting slice)

  • Private tables: enterprise_organizations, enterprise_org_members (created on registration).
  • CRUD orgs (create/list/get/update/delete) + add/remove/list members, admin + requires_entitlement("user_management") gated.
  • register_enterprise() mounts the router and calls register_module("user_management").
  • Public: gated Enterprise → User Management Vue view + nav/route, hidden unless user_management entitled.
  • Unit tests (private): entitlement gate (403 when not entitled), org CRUD, membership.

Phase 1b — Teams

  • enterprise_teams, enterprise_team_members; nested team membership within an org.

Phase 1c — Advanced RBAC

  • Custom role definitions + permission matrix (enterprise_custom_roles, enterprise_role_permissions); a requires_permission(...) resolution path layered over the OSS role hierarchy when entitled.

Later (separate issues, reserved seams)

  • SSO (OIDC/SAML) — sso entitlement; SCIM 2.0 — scim entitlement. Org/team model here is the identity target they provision into.

Architectural invariants to respect

  • Router → Service → DB layering, mirrored inside the private module.
  • Entitlement gating via requires_entitlement("user_management") on every enterprise endpoint; register_module(...) in register_enterprise.
  • Frontend gates on the server feature-flag (enterprise_features), never a client constant.
  • TRINITY_OSS_ONLY=1 must hide the whole surface (entitlement returns []).
  • OSS-only build (submodule absent) must be unaffected — endpoints 404, UI hidden, no import errors.

Out of scope

Related to #847, #941, ROLE-001 (requirements §35, §2.5).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions