Roles, capabilities and pages
The five fixed roles, the capability matrix in shadow mode, and which dashboard pages each role may open.
- Type: reference
The five fixed roles, the 60-capability model, and the dashboard pages each role may open.
Regenerate with make docs-generate.
Shadow mode. The capability model is computed and compared on every request but enforces nothing yet (
GET /admin/rbac/shadow-report). What is enforced today is@Roleson the controller plus the page baselines below. Read the capability matrix as the design the decorators are being reconciled against, not as live policy.
superadminandviewerare supersets:superadminholds every capability, andviewerreaches every read but is refused every mutation globally withREAD_ONLY_ROLE.
Roles
| Role | What it is | Data scope | Read-only | Assignable |
|---|---|---|---|---|
superadmin | The appliance owner. Holds every capability by superset, cannot be denied anything, and is the only role that may edit the access matrices or manage accounts. | global | no | yes |
admin_user | The day-to-day administrator: security policy, detections, compliance, governance, channels and platform operations. Reads its own tenant and the members of groups it owns. Account management stays with superadmin. | owned_groups | no | yes |
normal_user | An end user of the gateway. Holds no administrative capability; reads only its own data. | self | no | yes |
viewer | A read-only demo account. Satisfies any role requirement on a safe HTTP method and is refused every mutating request globally, by property of the request rather than by which endpoints it may call. | global | yes | yes |
auditor | An external reviewer. Reads compliance and governance evidence across every tenant, verifies frozen snapshots, and reads the audit trail. Cannot change anything, cannot read message content, and does not use the browser extension. Two recorded choices come with the role. (a) Its global read deliberately includes system rows (tenant_id IS NULL — unattributed SWG inspection traffic and org-wide governance assets) and the rows of users who have since left, because evidence an auditor cannot see is evidence they cannot sign off. (b) With no capability layer, endpoints that carry no @Roles at all stay reachable by any authenticated account, auditor included. That is an accepted property of a decorator-based model, not an oversight: closing it in general needs a rule that applies to undecorated handlers, which is what the cancelled capability phase was for. The one place it was not acceptable is chat: an auditor holding a session spends the customer's tokens and writes rows into the evidence it is signing off, so ChatRoleGuard refuses that role on ChatController and on the two SessionsController handlers that create, with 403 ROLE_NOT_FOR_CHAT (design §4.7, decided 2026-09-06). Session reads are untouched. | global | no | yes |
Capabilities (72)
● = the API admits the role. — = refused.
security policy (11)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
filters.manage | Change what the gateway blocks: input filter groups, filters, regex patterns, and the import/export of a filter bundle. | ● | ● | — | ● | — | 25 |
filters.overrides.manage | Per-tenant and per-family overrides of the shipped filter set, and the detection-count escalation that refuses bulk sensitive data. | ● | ● | — | ● | — | 8 |
output_filters.manage | Response-side filter groups and filters. | ● | ● | — | ● | — | 11 |
filter_testing.run | The filter-testing lab: test cases, groups, runs, and the DeepTeam red-team benchmarks. | ● | ● | — | ● | — | 31 |
ml_engine.manage | Detection-engine status and the side-by-side engine comparison. | ● | ● | — | ● | — | 2 |
ml_tuning.manage | Detection thresholds. Restarts ML services, so it stays with superadmin. | ● | — | — | — | — | 3 |
ocr_settings.configure | Which one OCR engine image analysis runs, and its right-edge rescan. | ● | — | — | — | — | 2 |
document_redaction.configure | How documents are redacted before they leave the gateway. | ● | — | — | — | — | 2 |
code_safety.configure | Model-redaction settings for the code-safety auditor. | ● | — | — | — | — | 2 |
prompt_compression.configure | Input-token reduction before the provider call. | ● | — | — | — | — | 2 |
attack_knowledge.manage | The attack-knowledge entries the analyst reasons with: create, change, enable or disable, import, and promote a review into one. | ● | ● | — | ● | — | 8 |
detection evidence (15)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
detections.view | The detection query API: list, statistics, and one detection. | ● | ● | — | ● | ● | 3 |
all_detections.view | The unified detection feed across chat, proxy, ICAP and extension — without message content. | ● | ● | — | ● | ● | 4 |
all_detections.view_content | Read the message body of a detection. The one capability in this inventory with no endpoint of its own, and the single line standing between an external auditor and customer conversation content. | ● | — | — | — | — | no endpoint |
risk_analysis.view | Read asynchronous risk analyses and their statistics. | ● | ● | — | ● | — | 5 |
risk_analysis.decide | Approve, reject or reopen a risk analysis — the review decision itself. | ● | ● | — | ● | — | 2 |
risk_analysis.run | Start an on-demand risk analysis of a session, or cancel one that is queued. | ● | ● | — | ● | — | 2 |
llm_review.view | Read LLM review verdicts, statistics, current locks, pending unlock requests, notifications and the review configuration. | ● | ● | — | ● | — | 7 |
llm_review.manage | Unlock a locked account, approve or deny an unlock request, and change the review configuration. | ● | ● | — | ● | — | 4 |
analyst.chat | Talk to the risk analyst, and list, read or delete your analyst chats. | ● | ● | — | ● | — | 5 |
threat_knowledge.view | Browse the shipped MITRE ATLAS and OWASP reference tables. | ● | ● | — | ● | — | 8 |
threat_knowledge.reload | Reload the ATLAS and OWASP tables from the shipped snapshot. | ● | — | — | — | — | 2 |
event_logs.view | The audit trail: event logs, request traces, per-object audit history, and the Claude Code activity views. | ● | ● | — | ● | ● | 14 |
retention.view | Read how long evidence is kept, and what is already past the window. The survey only — changing a window or running the sweep is retention.manage. | ● | ● | — | ● | ● | 1 |
retention.manage | Change how long evidence is kept, and run the retention sweep. Withheld from auditor — shortening a window or sweeping deletes the evidence being audited. Split from retention.view in the CID-33 rework: refusing the READ as well denied the role its own headline question. | ● | ● | — | ● | — | 2 |
logs.purge | Delete log rows outright. The sharpest separation-of-duties line in the product: an auditor must never be able to delete the evidence they are auditing. | ● | — | — | — | — | 1 |
compliance (10)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
compliance.view | The substance of a compliance review: statistics, regulations, mapped detections, financial impact, entity mappings, the mapping version ledger those mappings are pinned to, and the FX rates every cross-currency total is computed from. | ● | ● | — | ● | ● | 9 |
compliance.configure | CHANGING the FX rates, the entity→regulation mappings and the per-regulation fine structures. Deliberately withheld from auditor: these change the fine figures in the report the auditor is signing off. Reading the rate table is compliance.view — the split is the whole point, and collapsing it back would either blind the auditor or let it author the numbers it verifies. | ● | ● | — | ● | — | 4 |
compliance.export | Download the four compliance PDFs: impact, regulations, detections, executive summary. | ● | ● | — | ● | ● | 4 |
compliance.reports.view | The graded per-subject scorecard and the leaderboard. | ● | ● | — | ● | ● | 3 |
compliance.snapshots.view | The auditor's core: list frozen periods, open one, read its per-regulation dossier, verify it without trusting us, download the artefact and its evidence pack, and see the snapshot schedule. | ● | ● | — | ● | ● | 9 |
compliance.snapshots.manage | Freeze a period and change the schedule. Withheld from auditor by design: verifying evidence and producing it are the two halves separation of duties exists to keep apart. | ● | ● | — | ● | — | 3 |
compliance.findings.view | List and read recorded compliance findings. | ● | ● | — | ● | ● | 2 |
compliance.findings.manage | Record a finding and change its state. | ● | ● | — | ● | — | 2 |
grc.view | Read the GRC/CRQ simulation: policy impact, baseline, controls, coverage, history and thresholds — plus the two POSTs that compute and persist nothing (the what-if and the PDF). | ● | ● | — | ● | ● | 9 |
grc.manage | Run a simulation, record control observations, and set control thresholds. The customer's act, not the auditor's. | ● | ● | — | ● | — | 4 |
governance (4)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
governance.view | The AI asset inventory: overview, assets, one asset and its consumers, findings, and the governance policy as read. | ● | ● | — | ● | ● | 6 |
governance.register | Register a discovered AI asset into the sanctioned inventory. | ● | ● | — | ● | — | 1 |
governance.decommission | Retire an AI asset from the inventory. | ● | ● | — | ● | — | 1 |
governance.policy.manage | Change the governance policy and run asset discovery. | ● | ● | — | ● | — | 2 |
identity access (9)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
tenants.view | List accounts and read one. | ● | ● | — | ● | — | 2 |
tenants.manage | Create, change and delete accounts, and generate a password-reset link. The method-level superadmin override on a class decorated admin_user — the case a class-decorator reading gets wrong. | ● | — | — | — | — | 4 |
tenant_groups.manage | Tenant groups and their membership. | ● | ● | — | ● | — | 8 |
capability_access.manage | Edit the capability matrix. Superadmin-locked and undeniable: a role that can edit the matrix can grant itself anything, and a table that can hide the page holding the table can lock out the last administrator. | ● | — | — | — | — | 3 |
page_access.manage | Edit the page-visibility matrix. | ● | — | — | — | — | 2 |
credentials.manage | Provider API keys and the LLM readiness ledger. | ● | ● | — | ● | — | 10 |
api_keys.manage | Gateway API keys (cid_key_*). | ● | ● | — | ● | — | 8 |
ldap.configure | AD/LDAP connection, directory browsing, and the sync scopes that place accounts. | ● | ● | — | ● | — | 11 |
password_delivery.configure | How password-reset links reach a user (admin link, SMTP, EmailJS). | ● | — | — | — | — | 3 |
platform ops (11)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
deployment.connectivity.set | Declare whether this appliance is internet-connected or air-gapped. One key, deployment-wide, and it changes the guidance on every LLM surface. | ● | — | — | — | — | 1 |
license.view | This appliance's license status, its activation request, and uploading a license file. | ● | ● | — | ● | — | 3 |
licenses.issue | The owner console: issue, renew and revoke licenses for customers. | ● | ● | — | ● | — | 9 |
system.update | Install a new appliance version: upload, verify, install, roll back. | ● | ● | — | ● | — | 12 |
system.certificates | The appliance's own HTTPS certificate: names, CSR, upload, switch to the appliance CA, and the outbound site CA. Every change is a host reconcile; no private key is readable here. | ● | ● | — | ● | — | 7 |
setup.run | The first-boot setup wizard, after an admin exists. Deliberately excludes GET /setup/status and POST /setup/admin, the pre-admin bootstrap that must work before any account does. | ● | ● | — | ● | — | 10 |
models.manage | The model inventory: models, their statistics, providers and aggregated usage. | ● | ● | — | ● | — | 4 |
model_routing.view | Read the routing policy and refresh it. | ● | ● | — | ● | — | 2 |
model_routing.manage | Choose the judge model and run a routing measurement. | ● | — | — | — | — | 3 |
help.configure | The in-product assistant's settings, and uploading a policy document for analysis. | ● | ● | — | ● | — | 3 |
diagnostics.view | The appliance self-diagnostics snapshot and support bundle: host sizing, container health, service reachability, licence and TLS state, egress tests and the derived findings. Read-only; the bundle redacts every secret. | ● | ● | — | ● | — | 3 |
channels endpoints (8)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
inspection.configure | The inline-proxy/ICAP inspection policy, its event and coverage views, and the proxy's status and CA material. | ● | ● | — | ● | — | 9 |
attribution.manage | Workstation→user attribution records for proxy traffic. | ● | ● | — | ● | — | 5 |
extension.manage | Browser-extension deployment, enrolled devices, and the filter/threshold policies pushed to them. | ● | ● | — | ● | — | 6 |
extension.events.view | The extension event feed and its statistics. | ● | ● | — | ● | — | 2 |
edl_tokens.manage | Tokens the firewall uses to fetch the external dynamic list. | ● | ● | — | ● | — | 3 |
endpoint_agent.manage | The OS-level endpoint agent fleet: policy, rollout, kill switch, devices, installers. Superadmin-only for writes; viewer retains global read-only visibility, as everywhere. | ● | — | — | — | — | 11 |
repo_connector.manage | Repository tracking for the code-safety auditor: connectors, assignments, analyses and reports. | ● | — | — | — | — | 21 |
ai_usage.view | The Shadow-AI usage report: apps, people, riskiest activity, timeline and its PDF. | ● | ● | — | ● | — | 6 |
analytics cost (4)
| Capability | What it governs | superadmin | admin_user | normal_user | viewer | auditor | Handlers |
|---|---|---|---|---|---|---|---|
analytics.view | Tenant usage statistics and their PDF. | ● | ● | — | ● | — | 2 |
cost_report.view | Token cost and savings. Admin-only (CID-133, decided 2026-09-06 by the product owner): these seven handlers previously sat under a class-level RolesGuard with no @Roles, admitting every signed-in account — data was already scoped per actor inside the service, so it was not a leak, but the access policy is now tightened to match cost_report.teams.view below. | ● | ● | — | ● | — | 7 |
cost_report.teams.view | Per-team cost breakdown — the one cost handler that does carry a role requirement. | ● | ● | — | ● | — | 1 |
integrations.manage | Outbound SIEM and ITSM destinations. One row rather than two: the destination type lives in the request body, so splitting needs a body-level check — a different mechanism from a decorator. Split when a customer asks to separate their SIEM team from their ITSM team (design §8.4). | ● | ● | — | ● | — | 8 |
Pages by role (38)
A page whose Licence key the installed licence lacks is subtracted for every role,
superadmin included — /license itself is the deliberate exception.
| Page id | Path | Section | superadmin | admin_user | normal_user | viewer | auditor | Licence key | API |
|---|---|---|---|---|---|---|---|---|---|
dashboard | / | overview | ● | ● | — | ● | — | — | tenant-analytics.controller.ts |
ai-chat | /playground | overview | ● | ● | ● | — | — | — | chat.controller.ts (CombinedAuthGuard) |
my-team | /my-team | overview | ● | ● | ● | ● | ● | risk.llm_review | team/team.controller.ts |
models | /ai-inventory/models | inventory | ● | ● | — | ● | — | — | models.controller.ts |
mcp-servers | /ai-inventory/mcp-servers | inventory | ● | ● | — | ● | — | — | models.controller.ts |
filters | /filters | detection | ● | ● | — | ● | — | — | filters.controller.ts |
all-detections | /all-detections | detection | ● | ● | — | ● | ● | — | inline-proxy-inspect/all-detections |
ai-usage | /ai-usage | detection | ● | ● | — | ● | — | ext.browser | browser-extension/admin-events.controller.ts |
claude-code | /claude-code | detection | ● | ● | — | ● | — | — | event-logging.controller.ts |
inspection | /inspection | detection | ● | ● | — | ● | — | icap | inline-proxy-inspect/inspection-admin |
file-redaction | /file-redaction | detection | ● | ● | — | ● | — | — | inline-proxy-inspect/file-redaction.controller.ts |
llm-review | /llm-review | detection | ● | ● | — | ● | — | risk.llm_review | llm-review/admin-llm-review.controller.ts |
analyst | /analyst | detection | ● | ● | — | ● | — | risk.llm_review | llm-review/admin-llm-review.controller.ts |
compliance | /compliance | compliance | ● | ● | — | ● | ● | compliance | compliance.controller.ts |
compliance-reports | /compliance-reports | compliance | ● | ● | — | ● | ● | compliance | compliance/reports/compliance-report.controller.ts |
event-logs | /event-logs | compliance | ● | ● | — | ● | ● | — | event-logging.controller.ts |
governance | /governance | governance | ● | ● | — | ● | ● | governance | governance/governance.controller.ts |
governance-inventory | /governance/inventory | governance | ● | ● | — | ● | ● | governance | governance/governance.controller.ts |
governance-risk | /governance/risk | governance | ● | ● | — | ● | ● | governance | governance/governance.controller.ts |
governance-ownership | /governance/ownership | governance | ● | ● | — | ● | ● | governance | governance/governance.controller.ts |
tenants | /tenants | access | ● | — | — | ● | — | — | tenants.controller.ts (method-level superadmin overrides) |
access-control | /access-control | access | ● | — | — | ● | — | — | rbac/rbac.controller.ts |
tenant-groups | /tenant-groups | access | ● | ● | — | ● | — | — | tenant-groups.controller.ts |
credentials | /credentials | access | ● | ● | — | ● | — | — | credentials.controller.ts |
access-keys | /access-keys | access | ● | ● | — | ● | — | — | api-keys.controller.ts |
endpoint-agent | /endpoint-agent | endpoints | ● | — | — | ● | — | endpoint.agent | endpoint-agent/endpoint-agent-admin.controller.ts |
browser-extension | /browser-extension | endpoints | ● | ● | — | ● | — | ext.browser | browser-extension/browser-extension-management.controller.ts |
repo-connector | /repo-connector | endpoints | ● | ● | — | ● | — | codesafety | repo-connector admin controllers |
tenant-analytics | /tenant-analytics | reporting | ● | ● | — | ● | — | — | tenant-analytics.controller.ts |
cost-savings | /cost-savings | reporting | ● | ● | — | ● | — | cost.calculator | cost-report.controller.ts |
filter-testing | /filter-testing | lab | ● | ● | — | ● | — | — | filter-testing.controller.ts |
ocr-benchmark | /ocr-benchmark | lab | ● | ● | — | ● | — | — | filter-testing / ocr benchmark |
key-testing | /key-testing | lab | ● | ● | — | ● | — | — | credentials.controller.ts |
ml-engine | /ml-engine | lab | ● | ● | — | ● | — | — | guardrails admin |
settings | /settings | system | ● | ● | ● | ● | ● | — | configuration.controller.ts + per-pane controllers |
license | /license | system | ● | ● | — | ● | — | — | license.controller.ts |
system-update | /system-update | system | ● | ● | — | ● | — | — | system-update.controller.ts |
license-admin | /license-admin | system | ● | ● | — | ● | — | — | license-admin.controller.ts |
Edge cases
- Held by everyone (0): — — the governed handlers carry no
@Rolesat all, so every signed-in account reaches them. Recorded, not silently promoted. - No endpoint (1):
all_detections.view_content— service-level gates with no route. - Planned handlers (1):
capability_access.manage— declared before the endpoints exist; the boot assertion skips them.