Users, Roles & Departments

RustPBX separates four identity concepts that other systems blur together. Understanding the mapping prevents most access-control mistakes.

IdentityWhat it isAuthenticates viaUsed for
ExtensionSIP endpoint (phone, softphone, bot)SIP digest / JWTCalls, registration
UserConsole loginPassword / external IdPWeb console, REST API
AgentCC agent profile bound to an extensionCC Phone auth (JWT / token / SIP)ACD, desks, presence
API tokenMachine credentialBearer tokenAutomation, 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:

FlagMeaning
is_staffMay access admin console areas
is_superuserFull 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-onlydiagnostics, call records, reports, metrics
Telephony adminextensions, trunks, routing, queues
Billingwholesale billing, invoices, reports
CC supervisorCC 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

SettingEffect
Open registrationAnyone reaching the console can sign up (bootstrap only)
First-user superuserThe first account gets full privileges
Registration closedOnly admins create users

Close registration after creating your admin account. See Basic Setup for the first-boot flow.