Skip to content

Permissions

Describe how access is governed beyond authentication: roles, per-user capabilities, and tenant-level limits and features.

Access control has several layers:

  1. Rolesagent < supervisor < admin < platform_admin. The JWT carries the role; handlers check IsTenantAdmin() / IsPlatformAdmin(). Platform admins must be in the Platform tenant to wield cross-tenant power.
  2. Capabilities — a per-user JSONB map (users.capabilities) of resource → none/read/write, seeded from a role preset and individually overridable by a platform admin. Used for finer gating than the role alone.
  3. Tenant limitstenants.limits JSONB, platform-admin-only resource ceilings enforced in control-plane handlers (CheckTenantQuota); nothing on the call path.
  4. Tenant featurestenants.features JSONB, boolean entitlements, deny-by-default (e.g. self_service_carriers).

Roles, capabilities, limits and features are managed through the admin/tenant UIs and their endpoints (/users/{id}/capabilities, /tenants/{id}/limits, /tenants/{id}/features) — not environment variables. Assign the narrowest role that lets a user do their job.

Role Can Cannot
Agent Handle calls, set dispositions, read own CDRs Manage campaigns or users
Supervisor Monitor live, run reports, QA scorecards Provision tenants
Admin Manage campaigns, users, routing, carriers Touch other tenants
Platform admin Provision tenants + edges, set limits/features
  • Enforce least privilege; capability overrides let you grant a single extra resource without changing the role.
  • Permission checks are server-side (in handlers) — never rely on UI hiding.
  • Most role enforcement lives inside handlers, so a route’s required role isn’t always visible from the route table alone.