The dashboard uses capability-based access control: every user has one role, and a role grants capabilities as a grid of section × action (view / edit). Manage it all under Settings → Roles and Settings → Users.
How access works
Access is decided by three things:
- Role — a named bundle of capabilities. Each user holds exactly one.
- Section — an area of config: Global, Service Groups, Tags, Pauses, Blocks, Scripts, Protobuf Schemas, Snapshots, Push, Stats, Status, Users, TestFlight, Devices.
- Action —
view(read the section) oredit(change it).editimpliesview.
Enforcement is server-side: every read and write is gated by Postgres Row-Level Security calling has_capability(section, action). The UI also hides sections you can't view, but that sits on top of real backend enforcement — hitting the API directly still goes through RLS.
Built-in roles
Two roles ship with the dashboard and cover most needs:
| Role | Access | Notes |
|---|---|---|
admin | Full view + edit on every section (grants all) | Protected — can't be edited or deleted. |
viewer | Their own devices + captured traffic only | The default for new users. No fleet config. |
A viewer can sign in, manage their own devices, read their own traffic, and use the per-user reference pages — but sees none of the fleet-wide configuration sections.
Custom roles
Admins build roles tailored to a team under Settings → Roles.
- Click New role and name it.
- Toggle
view/editper section — one row per section, a checkbox per action:
| Section | Covers |
|---|---|
| Global | Global settings + environment (inspect/MITM flags, connection defaults, DNS, external proxy, maintenance). |
| Service Groups | SSL-proxy domain bundles. |
| Tags | Colored URL-pattern labels. |
| Pauses | Passthrough hosts. |
| Blocks | Auto-block / drop / mock rules (block rules). |
| Scripts | Request/response JavaScript hooks (scripting) — view to read; edit (+ admin + confirm) to write arbitrary code. |
| Protobuf Schemas | Uploaded .proto files + host mappings. |
| Snapshots | Project backups. |
| Push | Push tokens + send-push. |
| Stats | Live capture metrics. |
| Status | Infrastructure health. |
| Users | Profiles + role assignment (and the Roles editor itself). |
| TestFlight | Beta testers + groups. |
| Devices | Fleet-wide device list + control. |
- Save. The role appears immediately and can be assigned.
Editing a role's capabilities takes effect live for everyone who holds it — affected sessions re-evaluate their nav and access on the next push.
Assigning a role
Two equivalent paths:
- Settings → Users — open a user and pick their role.
- Settings → Roles — open a role to see and edit its member list.
A user always has exactly one role; changing it re-scopes what they see immediately.
What a minimal role sees
The nav hides any section a role can't view. A role with no fleet capabilities still gets the per-user surfaces, always scoped to that user's own data:
- Account — profile, password, linked providers.
- Devices — but only the ones they own.
- CDP — their own CDP-connector devices.
- The REST / WebSocket / MCP explorers — read-only, with their own credentials pre-filled.
So even a minimal role is a fully usable account — just without fleet-wide configuration.
The admin role is protected
To stop you locking everyone out:
- The
adminrole can't be deleted or edited — its full-access set is fixed. - You can't strip admin's capabilities.
- You can't demote the last admin — there's always at least one.
To hand off, promote another user to admin first, then change your own role.
Troubleshooting
- A section is missing from the nav — your role lacks
viewon it; an admin can grant it. - A page loads but edits fail (403) — your role has
viewbut notedit; RLS rejects the write. - Can't change your own role — by design; another admin must do it.
- Role change didn't take — capabilities push live; if a stale tab shows old nav, hard-reload it.