GloriousFlywheel Dashboard Operator Permission Policy 2026-04-16
Snapshot date: 2026-04-16
Purpose
Capture the first executable permission-policy layer for #172.
This note follows the tailnet operator identity work and turns role resolution into actual mutation controls.
Companion notes:
- gloriousflywheel-tailnet-operator-identity-2026-04-16.md
- gloriousflywheel-dashboard-mutation-authority-hold-2026-04-16.md
- gloriousflywheel-dashboard-control-authority-options-2026-04-16.md
- gloriousflywheel-program-surface-2026-04-15.md
- gloriousflywheel-milestone-execution-matrix-2026-04-15.md
Current Executed Policy
Current role meanings in the dashboard app:
viewer- can access monitoring and read-side visibility surfaces
- cannot pause or resume runners
- cannot submit dashboard config changes
operator- can use current compatibility mutation flows
- can pause and resume runners
- can submit runner configuration changes through the GitLab-backed flow
admin- inherits the current operator-capable mutation paths
- can view runtime auth-policy shape in Settings
- can inspect and revoke registered dashboard passkeys across users
- can inspect recent auth event history for interactive session and passkey lifecycle actions
- can inspect recent control event history for GitLab-backed compatibility mutations
Read-Side API Baseline
All non-public dashboard API routes now require an authenticated identity at the hook boundary.
That means:
- direct unauthenticated API calls no longer succeed by default
- unauthenticated dashboard page requests still redirect to
/auth/login - unauthenticated non-public API requests now return
401 /api/healthremains public through the existing public-path allowlist
Read-Side Data Tiers
The current executed read policy is now split into three data tiers:
- public
/api/health
- authenticated viewer-plus
- monitoring, metrics, cache, runner inventory, pod status, and event-stream surfaces
- operator-plus
- configuration detail and drift detail surfaces
- admin-only
- runtime auth-policy summary in Settings
- passkey inventory across users
- auth event history for interactive session and passkey lifecycle actions
- control event history for GitLab-backed compatibility mutations
Executed Enforcement
The repo now enforces the policy in the current mutation routes:
app/src/routes/api/runners/[name]/pause/+server.tsapp/src/routes/api/runners/[name]/resume/+server.tsapp/src/routes/api/gitops/submit/+server.ts
These routes now require operator or admin role resolution.
This matters because the dashboard API layer previously allowed these mutation paths without explicit authz checks.
Matching UI Behavior
The dashboard UI now reflects the same policy:
- the runner detail page disables pause and edit actions for read-only users
- the change-proposal page warns when the current user is read-only
- the UI no longer invites a viewer to attempt mutations that the server will reject
- the configuration and drift page now shows an explicit operator-only boundary instead of silently attempting restricted reads
What This Does Not Solve Yet
This is still a narrow first step.
It does not yet define:
- a finer-grained distinction between
operatorandadmin - a richer authorization story inside the authenticated viewer tier
- a non-GitLab mutation authority
- a passkey-registration path independent of the current GitLab interactive compatibility session
Practical Effect
#172 now has a real executed boundary:
- request identity is tailnet-first when trusted proxy auth is active
- current mutation authority remains GitLab-backed compatibility
- only operator-capable identities can drive that mutation path
- admin-capable identities can also inspect and revoke dashboard passkeys across users
- admin-capable identities can also review recent auth event history for interactive session establishment, logout, and passkey activity
Exit Condition
- current mutation routes enforce operator/admin role requirements
- dashboard UI reflects read-only versus operator-capable state honestly
- admin now has a real auth-administration workflow beyond passive policy introspection
- the next auth decision can focus on deeper admin scope and richer viewer-tier data policy