The GUI Operations area
Included from Basic tier
The GUI's Operations area (Administration, /admin) is the
operator console: one tab set covering the deployment, the runner and agent
fleets, emergency controls, licence, maintenance, identity and the
operational event stream. It is operational admin only: the governance
feature surfaces (controls, review campaigns, evidence ledger, waivers,
classification register, notification mandates + delivery evidence) live
under the GUI's own /governance route, gated by
pack entitlement and governance roles rather than admin status. The GUI is developed in a separate repository but
ships inside the opschain binary; this page covers how it is
served and maps each panel to the server endpoints that feed it and to the
component page that explains the behaviour behind it — read those pages for
semantics, this one to find them.
Serving: the embedded GUI at the root origin
The server embeds a vendored snapshot of the GUI's production bundle
(refreshed by make vendor-gui, provenance in the snapshot's
manifest.json) and serves it at /: one download, one process, one port,
with the API under /api on the same origin — no CORS, no proxy, no
version skew (the gui block on GET /api/admin/status and the overview
names the exact GUI commit the binary carries).
- Precedence:
/api/*,/healthz,/readyz,/metrics,/logs/tail, the/admin/*operational endpoints and the/opschain.runner.*//opschain.agent.*RPC services always win; every other unknown path servesindex.html, so client-side routes (e.g./admin/runners) deep-link correctly. Fingerprinted/assets/*are served immutable (long-cache);index.htmlandversion.jsonareno-cacheso a new release is picked up on reload. gui.enabled(config.yaml, default true in every posture):falsestops serving the GUI for deployments that front it separately; unknown root paths then 404 exactly as before the GUI was embedded. Seeopschain docs config.- A build vendored with no snapshot serves a one-page "GUI not bundled"
notice at
/instead of a bare 404.
Access: the tabs show for superusers (or an admin-rule probe of the admin
surface); maintenance, triggers, artifacts and settings screens ride path
RBAC rather than the admin gate. The admin routes return plain JSON, not
JSON:API. The GUI's /admin/* screen routes share exact paths with the
server's unprefixed admin support endpoints; a browser navigation (no
bearer, HTML Accept) to one of those paths serves the SPA rather than the
endpoint's 401, so refreshes and deep links into the admin screens work
(see opschain docs cli/admin-status).
Panel map
| Panel | What it shows | Fed by | Component page |
|---|---|---|---|
Overview (/admin) | The whole deployment on one screen: server card, runner-group cards with per-group demand, agents card, unsatisfiable-queue card, halt/licence/maintenance banners | GET /api/admin/overview (snapshot), composed from the same truths as GET /api/admin/status, GET /api/runners, GET /api/runner_groups (+ /{name}/demand), GET /api/fleet/queue, GET /api/agents, GET /api/platform/posture | opschain docs dispatch, opschain docs runner-registry, opschain docs agent-plane |
| Emergency controls (on Overview) | The two-plane halt console: posture, reason, suspended attempts, resume; the system-quiesce posture | GET /api/platform/posture, POST /api/platform/halt, POST /api/platform/resume, POST /api/platform/halt/attempts; GET/POST /api/platform/quiesce (+ /abort, /resume) | opschain docs platform-halt |
Runners (/admin/runners) | Runner groups and members with derived STATE (stopped/draining/quiesced/ready), drain/resume/forget verbs, the fleet-queue backlog with placement verdicts | GET /api/runners, GET /api/runners/{id}, POST /api/runners/{id}/drain|resume|forget, GET /api/runner_groups, PUT/DELETE /api/runner_groups/{name}, POST /api/runner_groups/{name}/drain|resume, GET /api/runner_groups/{name}/demand, GET /api/fleet/queue, POST /api/fleet/quiesce|drain|resume | opschain docs runner-registry, opschain docs fleet-queue, opschain docs runner |
| Registration tokens (panel on Runners and Agents) | Minted runner/agent registration tokens: scope, uses, expiry, derived status; mint dialog showing the token once | GET /api/registration_tokens?kind=runner|agent, POST /api/registration_tokens | opschain docs runner-registry, opschain docs agent-plane |
Server (/admin/server) | Build/replicas/leader, readiness checks and active changes — single-responsibility: the replicas table carries the server-computed live/stale split and defaults to live + recently-dead rows with a show-all toggle, and a queue-depth line links to the Queue page (which owns the dispatch view; licence and the support bundle live on their own pages too) | GET /api/admin/status, GET /readyz, GET /api/admin/changes/active | opschain docs dispatch |
Diagnostics (/admin/diagnostics) | The support-bundle download (redacted tar.gz) and the service-manager stop note — moved off the Server page | GET /api/admin/support_bundle | opschain docs support-bundle |
Configuration (/admin/config) | The config.yaml surface, exclusively: the full documented key catalog with set/default state (secrets redacted), a read-only file view, and a compose-and-download assist with server-side validation — never a write-back path | GET /api/admin/config, POST /api/admin/config/validate | opschain docs config |
Settings (/admin/settings) | The runtime, database-authoritative settings editor (CAS by version) with history/diff | GET /api/system_configuration, GET/PATCH /api/settings/{id}, GET /api/settings/{id}/versions[/{version}] | opschain docs settings |
Agents (/admin/agents) | The agent fleet: online/channel/halt state, drain/halt/forget/revoke verbs, trust summary and activity in the detail drawer | GET /api/agents, GET /api/agents/{id}, POST /api/agents/{id}/drain|resume|forget|revoke|halt, POST /api/agents/{id}/halt/resume, plus the trust and activity reads | opschain docs agent-plane |
Maintenance (/admin/maintenance) | The estate console for maintenance windows: active/scheduled/ended, schedule/start/extend/end/cancel, deferred trigger firings per window | GET /api/maintenance, GET /api/maintenance/{window_id}/deferred_firings, POST /api/<node>/maintenance[/schedule|extend|end|cancel] (node-RBAC'd writes) | opschain docs maintenance-windows, opschain docs triggers |
Users & Groups (/admin/users) | Local identity: users (provider chip, break-glass, disabled state, email), create/disable/enable/reset-password, an Edit user dialog for local users (stored email + per-user local group membership — directory users' details are read-only, though enable/disable work for them too: OpsChain-local state), local groups and membership (members added through the provider-aware user picker, so a same-named local/ldap pair is picked apart explicitly); both tabs filter server-side (debounced q substring + limit; users match username/email/group, groups match name/member, with the client-side pass kept so older servers degrade gracefully), a Show ghosts toggle lists the hidden ghost rows with a muted ghost badge (include_ghosts=true), and the groups tab creates groups (empty allowed; the first member is optional) and deletes them (refused verbatim while policy assignments reference the group), with member chips carrying each account's provider | GET/POST /api/admin/users, GET/PATCH /api/admin/users/{username} (+ /disable, /enable, /reset_password), GET /api/admin/groups, POST/DELETE /api/admin/groups/{groupname}/members[/{username}] | opschain docs identity |
Activity (/admin/activity) | The operational event stream, lensed over the ops vocabulary (warnings default; platform, licence, maintenance, agents, automation, auth) | GET /api/events (JSON:API, filterable) | opschain docs events |
Database (/admin Database panel — landing with board row) | Database maintenance status (per-table stats, autovacuum/analyze recency) and on-demand ANALYZE / VACUUM (ANALYZE) runs with per-table timings; quiesce state and export download | GET /api/admin/database, POST /api/admin/database/analyze, POST /api/admin/database/vacuum | opschain docs database-maintenance |
Conventions the panels share
- Derived runner STATE is a GUI concern — the server exposes booleans
and timestamps (
online,draining,stopped_at,last_seen_at); the GUI derives the same labels as the CLI so support conversations line up. - Honest liveness —
online: falsemeans "has not polled for 3 minutes", not "dead"; every liveness dot is paired with a last-seen age, and a clean goodbye (stopped) renders distinctly from aged-out silence. - Reason-first destructive flows — halt and per-agent halt 422 without
a
reason; the dialogs make it a required field, because the reason is the audit record. - Every action proves itself — each verb's confirm names the telemetry (event, status field) that will show it took effect.
Related pages
opschain docs cli/admin-status,opschain docs cli/admin-queue,opschain docs cli/admin-runners-list,opschain docs cli/admin-licence-show,opschain docs cli/admin-platform-status,opschain docs cli/admin-database-status,opschain docs cli/maintenance-status,opschain docs cli/events— the CLI views of the same endpoints, sharing the panels' vocabulary.