Agency RBAC Model
Purpose
This document describes the org RBAC model that is actually implemented today for the client-work slice.
Use it as a current-state contract, not as an aspirational permission matrix.
Implemented Role Model
The active org membership roles stored in orgUsers are:
owneradminaccount_managerstaff
These roles are real and are already used in membership resolution and client-scope checks.
Implemented Visibility Model
The current org client-work slice uses a two-part access model.
1. Org membership
The user must have an active orgUsers membership in the organization.
Without that, the org surface is not accessible.
2. Client visibility scope
Client visibility is resolved through clientAccessAssignments.
Current rule set:
ownerhas global client visibility in the organizationadmin,account_manager, andstaffare scoped by active assignment rows- there is no currently implemented non-owner
all_clientsmode in the client-work slice - if a non-owner has no active assignment rows, they see no client accounts in this slice
This is the key org visibility assumption the docs must preserve.
What The Current Capability System Actually Covers
The repo already has a real org capability system through:
orgRolePolicies- per-membership
capabilityMode - per-membership
capabilityOverrides
That system is currently strongest in these areas:
- org settings and admin actions
- billing access and billing write authority
- portal/admin configuration actions
Important limitation:
The new client-work routes do not yet use a full dedicated client-work permission grammar. Older product docs that describe clients.view, project.updates.publish, or documents.request as enforced today are ahead of the implementation.
Current Client-Work Action Rules
These are the current rules in code.
Client accounts
- visible to any active org member inside their client scope
- create and edit are currently allowed for
owner,admin, andaccount_manager - client-access assignment management is currently
owneronly
Projects
- visible to any active org member inside their client scope
- project creation is currently allowed for
owner,admin, andaccount_manager - project detail and update publishing are not yet surfaced
Time
- visible to any active org member inside their client scope
- any active org member can create their own draft time entries in that scope
- approval-style distinctions are not yet surfaced
Documents
- visible to any active org member inside their client scope
- any active org member can upload documents in that scope
- richer document-management permissions are not yet surfaced
Billing
- billing route access is controlled by the existing org capability system
- client scope still applies after billing access is granted
- billing is the most mature area of capability-based enforcement in this slice
Current Default Shape By Role
This is the real behavior to document today.
| Behavior | Owner | Admin | Account Manager | Staff |
|---|---|---|---|---|
| Global client visibility | Yes | No | No | No |
Visible clients require clientAccessAssignments | No | Yes | Yes | Yes |
| Create/edit client accounts | Yes | Yes | Yes | No |
| Manage client assignments | Yes | No | No | No |
| Create projects | Yes | Yes | Yes | No |
| Create own time entries | Yes | Yes | Yes | Yes |
| Upload documents | Yes | Yes | Yes | Yes |
| Billing access | Yes | Depends on org capabilities | Depends on org capabilities | Depends on org capabilities |
What Is Not Yet True
Do not document these as shipped behavior yet:
- dedicated client-work capability keys for every route and action
- separate view/create/edit/publish rules for project updates
- separate document request, visibility, and metadata-management permissions
- separate time approval authority surfaced in the app
Those may still be the next design target, but they are not the current implementation contract.
| projects.archive | Yes | Yes | No | No |
| project.updates.view | Yes | Yes | Yes | Yes |
| project.updates.create | Yes | Yes | Yes | No |
| project.updates.edit | Yes | Yes | Yes | No |
| project.updates.publish | Yes | Yes | Yes | No |
Files And Docs
| Capability | Owner | Admin | Account Manager | Staff |
|---|---|---|---|---|
documents.view | Yes | Yes | Yes | Yes |
documents.upload | Yes | Yes | Yes | Yes |
documents.edit | Yes | Yes | Yes | No |
documents.manage | Yes | Yes | No | No |
documents.request | Yes | Yes | Yes | No |
documents.visibility.manage | Yes | Yes | No | No |
Time
| Capability | Owner | Admin | Account Manager | Staff |
|---|---|---|---|---|
time.view_own | Yes | Yes | Yes | Yes |
time.view_all | Yes | Yes | No | No |
time.create | Yes | Yes | Yes | Yes |
time.edit_own | Yes | Yes | Yes | Yes |
time.edit_all | Yes | Yes | No | No |
time.approve | Yes | Yes | No | No |
Billing
| Capability | Owner | Admin | Account Manager | Staff |
|---|---|---|---|---|
billing.view | Yes | Yes | Yes | No |
billing.invoice.create | Yes | Yes | Yes | No |
billing.invoice.edit | Yes | Yes | Yes | No |
billing.invoice.send | Yes | Yes | No | No |
billing.invoice.void | Yes | No | No | No |
billing.subscription.view | Yes | Yes | Yes | No |
billing.subscription.manage | Yes | Yes | No | No |
billing.connection.manage | Yes | No | No | No |
Override Guidance
The owner can change non-owner defaults when the agency needs it.
Most common override examples:
- allow an admin to remove staff or assign roles
- allow an account manager to lose portal invite ability
- allow a staff member to draft project updates
- remove billing visibility from account managers in agencies that keep finance tightly restricted
Recommended Default Shape
A common starting point should look like this:
- owner: all capabilities
- admin: most operational capabilities, with financial and destructive capabilities based on owner choice
- account manager: assigned-client operations with separate view, edit, publish, and finance toggles where those distinctions matter
- staff: assigned-client work capabilities only, with read and write permissions split where operational risk differs
Hard Guardrails
Even with configurable permissions, some guardrails should remain.
- owner always has full oversight
- no billing permission means no billing visibility
- client access does not automatically grant billing authority
- a user should not manage clients they cannot access
- permission design should stay understandable for a 1-to-10 person agency
Product Bias
Bias toward the most common small-agency pattern:
- simple role templates
- owner-controlled toggles
- occasional user-specific exceptions
Do not start with blank-slate custom roles, deep inheritance trees, or enterprise policy builders.
Do start with capability names that are clean enough to survive implementation without a six-month refactor.