The operator ruled the implementation repo's main (50c8719) the latest and accepted state. Sync the spec to it. Accepted changes are reflected: one bare-metal environment, TrueNAS bulk storage, R2 off-cluster backup, CloudNativePG, single-node VPN gateway with Cilium fail-closed, inbound WireGuard, per-app auth sidecars, Renovate, the CI gate as approver, and the pm-agent. New ADR-0017..0025; ADR-0016 corrected and accepted; R-* IDs unchanged, eight amended. Where the implementation has simply not met a requirement, the requirement stands and the shortfall is recorded in docs/16-known-gaps.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
76 lines
4.3 KiB
Markdown
76 lines
4.3 KiB
Markdown
# 12 — Command & Control (C2) Center UI
|
|
|
|
Serves: **R-C2-01/02**, surfaces **R-OBS-***, **R-GITOPS-***.
|
|
|
|
## Purpose
|
|
|
|
The root `home.keithjackson.dev` is the operator's front door: a single UI that shows what's running
|
|
in the cluster, links to every service, and surfaces platform health and safe operational actions
|
|
(R-C2-01/02).
|
|
|
|
## Composition (assemble, don't reinvent)
|
|
|
|
The C2 center is a curated composition of best-in-class UIs behind the root domain, not a bespoke
|
|
app to build from scratch:
|
|
|
|
- **Homepage (gethomepage.dev)** — the landing dashboard at the root: a live catalog of services
|
|
with links, status pings, and per-service widgets (many of the catalog services have native
|
|
Homepage widgets: Plex, Sonarr, Radarr, qBittorrent, PiHole, Gitea, etc.). This is the primary
|
|
R-C2-01 surface.
|
|
- **Grafana** — embedded platform + per-service dashboards (R-OBS-03) for health at a glance.
|
|
- **Headlamp** — a controlled Kubernetes console for viewing workloads/VMs and performing scoped
|
|
operational actions (restart, scale, inspect) — the R-C2-02 "controlled operational actions where
|
|
safe" surface. Each user acts under their own IdP identity and group-bound RBAC, never a shared
|
|
console identity.
|
|
- **Flux status** — GitOps reconciliation state (via Headlamp's Flux view, the Flux UI, or a
|
|
Homepage widget) so the operator sees drift/errors.
|
|
- **Hubble UI** (optional) — network flow visualization for isolation troubleshooting; deployed
|
|
with no route, so it is not reachable from outside the cluster.
|
|
|
|
Each sub-UI is itself a platform-managed or onboarded, TLS-protected, access-controlled service; the
|
|
root aggregates and links them. Status of this composition is tracked in
|
|
[known gaps](16-known-gaps.md).
|
|
|
|
## Data the C2 surfaces (R-C2-02)
|
|
|
|
- **Service catalog**: every running service, its URL, its health, its egress class, its exposure.
|
|
- **Platform health**: node status, Longhorn capacity/health, Flux reconciliation, cert expiry,
|
|
backup status, VPN tunnel state — sourced from the observability stack ([10](10-observability-and-alerting.md)).
|
|
- **Alerts**: current firing alerts (mirrors what email delivers).
|
|
|
|
## Actions (safe, audited)
|
|
|
|
Operational actions exposed through the C2 must be **scoped and audited**, never a raw cluster-admin
|
|
kubeconfig in a browser:
|
|
- Restart/scale a workload, start/stop a KubeVirt VM, trigger a Flux reconcile, acknowledge an
|
|
alert.
|
|
- Destructive actions (delete, offboard) require explicit confirmation and are logged.
|
|
- Onboarding itself remains a **git PR** (GitOps), not a C2 button — the C2 may *link* to the
|
|
catalog/PR flow but does not bypass GitOps ([05](05-gitops-and-delivery.md)).
|
|
|
|
## Access control
|
|
|
|
- C2 sub-UIs are `internal` exposure by default (LAN/VPN-only) unless the operator explicitly makes
|
|
a component `public`. The apex and Grafana are `public` as registered platform routes; Headlamp is
|
|
LAN/VPN-only because it holds a path to the Kubernetes API on the user's behalf.
|
|
- Prometheus, Alertmanager and Hubble UI have **no route** and are not exposed; operators reach
|
|
their data through Grafana. Any future exposure of them MUST be gated.
|
|
- Authentication is via **Keycloak SSO** ([15](15-identity-and-access.md), [ADR-0014](../decisions/adr-0014-idp-keycloak.md)):
|
|
Headlamp/Grafana use **native OIDC**; a UI without OIDC, such as Homepage, requires a per-app
|
|
**oauth2-proxy forward-auth gate** ([ADR-0022](../decisions/adr-0022-forward-auth-per-app-oauth2-proxy-sidecars.md)).
|
|
Access to the C2 and sensitive surfaces requires an authenticated user **in an authorized group**
|
|
with **MFA** (R-IDP-06).
|
|
- Trusted TLS on the root and all sub-UIs ([08](08-tls-and-certificates.md)).
|
|
|
|
## Acceptance gates
|
|
- `https://home.keithjackson.dev` serves the C2 landing UI over trusted TLS.
|
|
- Every running service appears with a working link and live status.
|
|
- Platform health (nodes, storage, Flux, certs, backups, VPN) is visible without leaving the C2.
|
|
- Safe operational actions work and are access-controlled + audited; destructive actions confirm.
|
|
|
|
## Resolved
|
|
- Auth mechanism — **Keycloak SSO** (native OIDC + per-app oauth2-proxy forward-auth gates),
|
|
[15](15-identity-and-access.md) / [ADR-0014](../decisions/adr-0014-idp-keycloak.md) /
|
|
[ADR-0022](../decisions/adr-0022-forward-auth-per-app-oauth2-proxy-sidecars.md).
|
|
- Root UI — **Homepage** at the apex. A custom portal would need an ADR.
|