A web UI for managing Talos Linux clusters via the Talos machine API (apid gRPC). Single Go binary with an embedded React frontend.
- Dashboard — per-node cards: stage/readiness, Talos version, load, memory, uptime; discovered cluster members.
- Node detail — live CPU/memory sparklines, mounts, disks, network interfaces; services with start/stop/restart; streaming logs (service, container, kernel dmesg) over SSE; processes; CRI + system containers with restart; read-only file browser.
- etcd — members, leader, DB size, raft state, alarms; defrag / disarm / forfeit-leadership; remove member (typed confirmation); snapshot download.
- Machine config — Monaco YAML editor with diff view, secrets redacted by default (reveal is audited), dry-run first, apply with explicit mode (
AUTO/NO_REBOOT/REBOOT/STAGED/TRY). - Lifecycle — reboot, shutdown, upgrade (with stage), rollback, reset (wipe-mode selection), bootstrap — all behind typed confirmation dialogs and a server-enforced
confirm: truecontract. - Events — live cluster event feed with filtering; cluster health check streaming; kubeconfig download; audit log of every mutating action.
- Multi-context — upload a talosconfig in the browser (stored AES-GCM-encrypted at rest) or mount one via
TALOSCONFIG; switch contexts from the top bar.
# fixture mode: no cluster needed
make build
MOCK_MODE=true ./bin/talos-ui
# open http://localhost:8080
# against a real cluster
TALOSCONFIG=~/.talos/config ./bin/talos-ui
# ...or omit TALOSCONFIG and upload it through the setup screenDevelopment (Go API on :8080 + Vite dev server with proxy on :5173):
make dev| Env var | Default | Description |
|---|---|---|
TALOS_UI_LISTEN |
:8080 |
HTTP listen address |
TALOSCONFIG |
— | Path to a talosconfig; if unset, upload via the UI |
TALOS_UI_DATA_DIR |
~/.talos-ui |
Stores encrypted talosconfig, state, audit log |
TALOS_UI_PASSWORD |
— | Login password (bcrypt-hashed at startup) |
TALOS_UI_PASSWORD_HASH |
— | Pre-computed bcrypt hash (preferred over plaintext) |
TALOS_UI_ENCRYPTION_KEY |
autogenerated | 64-hex-char AES-256 key for talosconfig at rest |
MOCK_MODE |
false |
Serve fixture data without a cluster |
With neither password variable set, authentication is disabled (a warning is logged). Always set one outside local development. Sessions use HttpOnly cookies; mutating requests additionally require the X-CSRF-Token header issued at login.
- The UI's privileges are exactly those of the talosconfig cert it holds (
os:reader→ read-only,os:operator/os:admin→ full control). Generate a limited config withtalosctl config new --roles os:reader. - Uploaded talosconfigs are encrypted (AES-256-GCM) on disk; the key lives in
TALOS_UI_ENCRYPTION_KEYor a0600key file in the data dir. - Machine config secrets are redacted by default; unredacted views and every mutating action are written to the audit log (
audit.log, JSONL). - Destructive operations require a server-side
confirm: truefield, and the UI gates the scariest ones (reset, shutdown, bootstrap, member removal, config apply) behind type-the-node-name challenges. - Strict CSP (no inline/CDN scripts; Monaco is bundled and uses a same-origin worker).
make docker # builds talos-ui:latest (distroless, non-root)
kubectl apply -f deploy/k8s.yaml # see header comments for required secretsRun it on the same network as your nodes' apid (port 50000). Terminate TLS in front of it (ingress/reverse proxy) for production use.
The backend exposes a JSON REST API under /api/v1 (status, nodes, services, etcd, config, lifecycle, files, audit) and SSE streams under /api/v1/stream/{logs,dmesg,events,health}. gRPC errors map onto HTTP status codes (PermissionDenied→403, Unavailable→502, DeadlineExceeded→504, unconfigured→412).
cmd/talos-ui/ entrypoint
internal/talos/ Client interface + machinery-backed real client + mock
internal/api/ REST handlers, SSE streams, error mapping
internal/auth/ sessions, bcrypt, CSRF, login rate limiting
internal/store/ encrypted talosconfig, context state, audit log
web/ React + TypeScript + Vite frontend (embedded at build)
deploy/ Dockerfile, Kubernetes manifest
make test # Go tests (race) + TypeScript type-checkBackend tests run the full HTTP API against the mock client: auth/CSRF gating, confirm-required contract, error mapping, SSE framing, redaction, audit logging, and store encryption round-trips.
- No COSI resource explorer page (API groundwork exists in the machinery client).
- No Playwright end-to-end tests; backend integration tests + mock mode cover the API contract.
- Reboot/upgrade progress is observable via the Events page rather than a dedicated action tracker.