Who Can Touch What: Users, Roles, Departments and API Tokens
“Who can see the billing page?” sounds like a one-line question. Answering it in a PBX means distinguishing four very different identity concepts that other platforms happily blur together. RustPBX keeps them separate, and knowing the difference prevents most access-control mistakes.
The Four Identities
| Identity | What it is | Used by |
|---|---|---|
| Extension | A SIP endpoint (phone/softphone/bot) | Calls, registration |
| User | A console login | The web console / REST |
| Agent | A CC agent profile bound to an extension | ACD, desks |
| API token | A machine credential with scopes | Automation |
An extension is not a user (no console login). A user is not an agent (no queue presence). An agent may be bound to an extension — usually is — but the binding is explicit. Getting this mapping right is step one.
Console Users
Users authenticate with a local password (or an external provider via Enterprise Auth). The first registered user becomes the superuser; beyond that, the registration policy controls self-signup and should be closed once your team exists:
[console]
allow_registration = false
Users carry flags (is_staff, is_superuser) that gate console sections, and permissions are checked per section + action (extensions:write, trunks:write, routes:write, …). That’s why a read-only NOC account can watch diagnostics without being able to edit a trunk.
Roles & Permissions
Rather than flags scattered per user, console RBAC pairs roles with permission sets — a role grants write/read on named sections, and users are assigned roles. Practical roles that map to real teams:
| Role | Grants |
|---|---|
| NOC / Read-only | diagnostics, call records, reports, metrics |
| Telephony admin | extensions, trunks, routing, queues |
| Billing | wholesale billing, reports, invoices |
| CC supervisor | CC monitor, agents, skills, reports |
Mutation APIs enforce permissions consistently, so a billing role cannot quietly PATCH a trunk — the API rejects it the same way the console hides the button.
Departments
Departments are organizational groupings of extensions — used for filtering (the extensions list filters by department), reporting, and directory display. Membership is many-to-many (extension_departments), so an extension can sit in more than one department without duplicating the endpoint.
Departments also give you a clean answer to “show me all sales lines” without naming conventions in the extension number.
API Tokens with Scopes
Automation should not log in as a person. Static tokens live in config with explicit scopes:
[console]
api_tokens = [
{ token = "pbx-api-token-xxxx", scopes = ["call.control", "recording"], description = "CRM integration" },
{ token = "pbx-monitor-token-yyyy", scopes = ["diagnostics"], description = "Monitoring" },
]
- Sent as
Authorization: Bearer <token> - Scopes gate what the token can do (
call.control,recording,diagnostics,routing, …) - Token requests skip CSRF (they’re not cookie-based) and are audited like any other mutation
Rule of thumb: one token per integration, minimal scopes, rotate on people changes — and never reuse a token across systems that have different blast radii.
Multi-Tenant on the Wholesale Side
Wholesale layers tenant access on top: sales users can be scoped to specific tenant accounts (sales_tenant_access), so a partner-manager sees their customers’ balances and CDRs without seeing the carrier’s. Combined with per-tenant rate decks and routing profiles, tenancy is enforced at data and configuration levels, not just in the UI.
The Checklist
- Map every human to a user; every device to an extension
- Give users the smallest role that does the job
- Close self-registration after bootstrapping
- Give automation its own scoped token
- Use departments for reporting, not as a substitute for permissions
Guides: Basic Setup → API tokens and Extension Management.