Users, Roles & Departments
RustPBX separates four identity concepts that other systems blur together. Understanding the mapping prevents most access-control mistakes.
| Identity | What it is | Authenticates via | Used for |
|---|---|---|---|
| Extension | SIP endpoint (phone, softphone, bot) | SIP digest / JWT | Calls, registration |
| User | Console login | Password / external IdP | Web console, REST API |
| Agent | CC agent profile bound to an extension | CC Phone auth (JWT / token / SIP) | ACD, desks, presence |
| API token | Machine credential | Bearer token | Automation, integrations |
An extension has no console login. A user has no queue presence. An agent is usually bound to an extension — but the binding is explicit, not implied.
1. Console users
The first registered user becomes the superuser. After bootstrapping your team, close self-registration:
[console]
allow_registration = false
Users carry two privilege flags:
| Flag | Meaning |
|---|---|
is_staff | May access admin console areas |
is_superuser | Full access, bypasses permission checks |
Permission checks are per section + action (extensions:write, trunks:write, routes:write, extensions:read, …) — a read-only NOC account can watch diagnostics without editing trunks.
2. Roles & permissions
Roles bundle permission sets so you assign people to jobs, not to endpoints:
| Role (example) | Grants |
|---|---|
| NOC / read-only | diagnostics, call records, reports, metrics |
| Telephony admin | extensions, trunks, routing, queues |
| Billing | wholesale billing, invoices, reports |
| CC supervisor | CC monitor, agents, skills, reports |
Mutation APIs enforce the same permissions as the console, so a billing role cannot PATCH a trunk even by calling the API directly.
3. Departments
Departments group extensions for filtering, reporting, and the directory:
- Many-to-many membership (
extension_departments) — an extension can belong to several - The extensions list filters by department
- Reports and directory views group by department
Use departments for organization, not for permissions — those are roles.
4. API tokens
Automation should never log in as a person. Define static tokens 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 system" },
]
- Sent as
Authorization: Bearer <token> - Scopes gate capabilities:
call.control,recording,diagnostics,routing,extension,sip_trunk, … - Token-authenticated requests skip CSRF checks (not cookie-based) and are audited
- Token requests are treated as a synthetic superuser for the console API tree — scope the token tightly
Rules of thumb: one token per integration, minimal scopes, rotate on personnel changes, never share across systems with different blast radii.
5. Wholesale tenant access
Wholesale adds a tenancy layer on top of roles: sales users can be scoped to specific tenant accounts (sales_tenant_access), so a partner manager sees their customers’ balances and CDRs — and nothing else. Combined with per-tenant rate decks and routing profiles, isolation is enforced at the data and configuration levels, not just in the UI.
6. Registration policy
| Setting | Effect |
|---|---|
| Open registration | Anyone reaching the console can sign up (bootstrap only) |
| First-user superuser | The first account gets full privileges |
| Registration closed | Only admins create users |
Close registration after creating your admin account. See Basic Setup for the first-boot flow.