LangWatch RBAC has two layers, two surfaces, and one stitching mechanism:Documentation Index
Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
- Two layers: organization roles (org-wide capabilities, e.g.
ADMIN,MEMBER,EXTERNAL) and team roles (per-team capabilities, e.g.ADMIN,MEMBER,VIEWER). - Two surfaces:
/settings/roles(the role catalog: pre-built + custom) and/settings/role-bindings(who is bound to what role at what scope). - One stitching mechanism: a
RoleBindingrow glues a user to a role at a scope (organization, team, project, or governance subscope).
aiTools:manage without granting full organization:manage, or when an audit asks “who can read the audit log” and you want a screen instead of a Slack thread.
Pairs with: Members & invites (assigning roles when inviting), Audit log (every role binding mutation records a row), and AI Gateway → RBAC (the gateway-side enforcement of permissions).
Organization roles
The three pre-built org roles. Each user in the org has exactly one.| Org role | Defaults | What it grants by default |
|---|---|---|
| ADMIN | First user to sign in becomes admin | organization:view, organization:manage, organization:delete; the full governance surface (governance:view, governance:manage, ingestionSources:*, anomalyRules:*, complianceExport:view, activityMonitor:view); aiTools:view + aiTools:manage. |
| MEMBER | Default for invitees | organization:view, aiTools:view. No governance permissions, no member-list reads, no audit log access by default. The team-role (below) is what gives them anything beyond /me. |
| EXTERNAL | Lite-member shape, opt-in via the invite drawer | Same as MEMBER. EXTERNAL also has stricter team-level defaults: even when on a team they default to view-only on most resources. |
ORGANIZATION role binding for a MEMBER does not grant team-level access. Team-level permissions come from team-role bindings (next).
Team roles
The four pre-built team roles. A user can have different team roles on different teams (ADMIN on Engineering, VIEWER on Marketing).
| Team role | What it grants by default |
|---|---|
| ADMIN | The full team-scoped permission set: project:create/update, analytics:manage, traces:create, virtualKeys:create/update/rotate/manage, gatewayBudgets:view/manage, gatewayProviders:view/update/manage, routingPolicies:view/manage, gatewayGuardrails:view/attach/detach/manage, gatewayLogs:view, auditLog:view, gatewayUsage:view, gatewayCacheRules:*. |
| MEMBER | Same shape minus the *:manage permissions. Read + create + update on most resources; can’t delete or reconfigure providers, policies. |
| VIEWER | View-only across the team. No create, update, delete on anything. The right shape for stakeholders who need read access to a team’s traces but should never reconfigure anything. |
| CUSTOM | Empty by default. Permissions come from the CustomRolePermissions JSON column on the RoleBinding row, see Custom roles below. |
Permission catalog
Every gate in the codebase is a string of the shape<resource>:<verb>. The full catalog (abridged):
- Organization:
organization:view,organization:manage,organization:delete. - Governance:
governance:view,governance:manage,ingestionSources:*,anomalyRules:*,complianceExport:view,activityMonitor:view. - AI Tools Portal:
aiTools:view(everyone),aiTools:manage(admin). - Audit log:
auditLog:view(team-level by default; note the audit log UI page is gated toorganization:manage, the underlying procedure is onauditLog:view). - Per-team resources:
project:*,analytics:*,traces:*,virtualKeys:*,gatewayBudgets:*,gatewayProviders:*,routingPolicies:*,gatewayGuardrails:*,gatewayLogs:*,gatewayUsage:*,gatewayCacheRules:*,evaluations:*,datasets:*,workflows:*,prompts:*,scenarios:*,secrets:*.
What organization:manage gates today
After this PR’s RBAC defense-in-depth pass, the legacy /settings/{audit-log, teams, members, roles, groups} pages all require organization:manage (admins only). Underlying tRPC procedures match, role.getAll, organization.getAllOrganizationMembers, organization.getOrganizationPendingInvites, team.getTeamsWithRoleBindings, organization.getMemberById, group.getById, group.listForMember, group.listAll, limits.checkAndSendUsageLimitNotification are all gated to organization:manage server-side.
Picker procedures (team.getTeamsWithMembers, team.getTeamWithMembers, organization.getOrganizationWithMembersAndTheirTeams) intentionally stay on organization:view so non-admin pickers (the AddAutomationDrawer, GroupBindingInputRow, project pickers, onboarding flows) continue working, but they redact other members’ email addresses to null for non-admin callers and strip other users’ Personal Workspaces from the result entirely.
The role catalog at /settings/roles
The catalog page lists every role available in the org:
- 4 pre-built org roles (ADMIN, MEMBER, EXTERNAL, VIEWER).
- 4 pre-built team roles (ADMIN, MEMBER, VIEWER, CUSTOM).
- Any custom roles your admin has authored (see below).
MEMBER does, because the gateway and the control plane both encode those defaults. Custom rows are editable.
Custom roles
Custom roles are how you say “letbob@acme.test manage the AI Tools Portal but not the rest of the org.” They’re a RoleBinding row whose role = "CUSTOM" and whose customRoleId references a CustomRole row whose permissions JSON column lists exactly the gates that role grants.
To create one:
- Open
/settings/roles→ + New custom role. - Name the role (e.g.
aitools-curator). - Tick the permissions to grant. Permissions are scope-aware, granting
aiTools:manageat organization scope is different from granting it at team scope. - Save.
- Open
/settings/role-bindings→ + New binding. - Pick the user, pick the role (
aitools-curatorfrom the catalog), pick the scope (Organization, a specific team, a specific project, a governance subscope). - Save.
- Their org-role defaults (e.g. MEMBER →
organization:view+aiTools:view). - Their team-role defaults for every team they’re on.
- The new custom binding (
aiTools:manageat org scope).
Role bindings at /settings/role-bindings
The bindings page is a deep table: every active RoleBinding row in the org. Filter by user, role, scope, or scope target. The most common admin questions:
| Question | Filter |
|---|---|
| Who can manage the AI Tools Portal? | Role = aiTools-curator (or any custom role granting aiTools:manage). |
| Who has admin on the Marketing team? | Role = ADMIN, Scope = Team, Scope target = Marketing. |
What does bob@acme.test actually have access to? | User = bob. Cross-reference with the permission catalog for what each role grants. |
Has anyone been bound at Organization scope to MEMBER? | Role = MEMBER, Scope = Organization. (Note: org-scoped MEMBER bindings do NOT imply team- or project-level access, the resolver is hierarchical.) |
How permissions resolve at request time
A request hitting any*:manage-gated procedure flows through checkOrganizationPermission (or checkTeamPermission for team-scoped procs), which:
- Walks the user’s role bindings.
- Builds the effective permission set as the union of: org-role defaults + every team-role default the user has + every custom-role permission via active bindings.
- Returns
trueif the requested permission is in the set.
Where to next
- Invite someone with a specific role: Members & invites.
- Audit who did what: Audit log.
- Gateway-side enforcement: AI Gateway → RBAC.
- Workspace scoping: Workspaces (where org, team, project sit relative to each other).