fleet-manager: checkpoint 7 — deployment (compose, PKI, deploy runbook, design-doc updates)
Complete the deployment story for the server-side control plane: - docker-compose.yml: private InfluxDB (published to loopback only) + a host-networked fleet-manager (reaches the loopback enrol-broker on 127.0.0.1:9443 and binds a routable gRPC agent listener, like the broker). - .env.example: RP origin (diskless-server.bitasylum.org), Influx token/DB password, cert/PKI paths; the Influx token wires influxdb + manager with one value. - server-pki.sh: issue the agent-plane server cert from the fleet CA (step) and stage the fleet root as the client-verify CA. - DEPLOY.md: end-to-end runbook — three-cert PKI (fleet-CA agent cert, broker admin-client cert, Let's Encrypt DNS-01 UI cert), register-admin passkey bootstrap, compose up, hardware-free smoke test, backups. - .dockerignore: keep host node_modules/dist/pki/secrets out of the build context so the embedded SPA is the one built in-image. - .gitignore: never commit .env / issued PKI / data. Design docs marked as-built: fleet-management-design.md as-built note (resolved forks — gRPC bidi transport, InfluxDB metrics, SPA graphs, passkey admin auth, broker fold-in "alongside"); tpm-enrolment-design.md (broker fold-in + agent transport fork resolved); TODO.md #14 → partly built, with the on-host agent + per-host boot-version assignment (#6) called out as the remaining work.
This commit is contained in:
@@ -146,6 +146,18 @@ pinned for mTLS — one trust anchor across 802.1X, NVMe, and management.
|
||||
everything else on. Build the broker standalone first (fastest path to the state
|
||||
machine), but design it to fold into the mgmt service with no rewrite — same Go
|
||||
style, same step-ca anchor, same data model.
|
||||
- **AS-BUILT (2026-07): folded in "alongside", not merged.** The
|
||||
`serving/fleet-manager/` control plane drives the standalone broker's admin
|
||||
plane over mTLS (broker admin CA) rather than absorbing its code: the broker
|
||||
stays the enrolment **state machine + step-ca signer**, and gained an
|
||||
`Accept: application/json` approve response so the manager gets the decided
|
||||
enrolment back and **births the inventory record**, recording the human
|
||||
(passkey-authenticated) admin as approver. `verify-serving.sh` / browser
|
||||
callers are unchanged (still get the 204/redirect). The public
|
||||
`/enrol/request|status` edge is untouched. This keeps the one unauth,
|
||||
stdlib-only, reproducible pre-auth parser isolated while giving the manager
|
||||
the authenticated authorise pillar — same trust anchor, same data model, no
|
||||
rewrite. See `serving/fleet-manager/README.md` (Authorise pillar).
|
||||
- **host-api is not in the enrolment path** (it is loopback/post-boot; the host has
|
||||
no cert during enrolment). The tie is downstream: the fleet-manager **agent** (the
|
||||
push sibling of `fleet-hostapi`) authenticates with the *enrolled* cert over mTLS,
|
||||
@@ -200,11 +212,13 @@ fleet-manager agent) — one language, one build/posture story. Transport is spl
|
||||
- **Steady-state agent ↔ manager (telemetry + reconciliation) → gRPC over mTLS,
|
||||
host-dialed.** Streaming fits here, and it stays compatible with "no inbound port on
|
||||
hosts" because the **host dials out** and holds one long-lived mTLS stream (health
|
||||
up / desired-state down). OPEN FORK (a fleet-manager build decision, not enrolment):
|
||||
bespoke gRPC vs reuse **OTLP-gRPC for metrics + Wazuh for events** + a thin gRPC
|
||||
control stream — the latter gets VictoriaMetrics/Grafana/Wazuh for free. `Connect`
|
||||
(connectrpc.com) is an option if one protobuf IDL serving gRPC + JSON + browser is
|
||||
wanted across the authenticated surface.
|
||||
up / desired-state down). ~~OPEN FORK~~ **RESOLVED (2026-07):** a **bespoke gRPC
|
||||
bidi stream** (`serving/fleet-manager/proto/fleet_agent.proto` —
|
||||
`FleetAgent.Session`, health/metrics up + desired-state down), over the same
|
||||
reused TPM cert (fleet CA). Metrics land in **InfluxDB** via the manager (host
|
||||
holds no Influx credential), not OTLP→VictoriaMetrics; events stay on the Wazuh
|
||||
path. One stream, no polling, no inbound host port. (The on-host agent — the
|
||||
gRPC report/reconcile client that pairs with `fleet-hostapi` — is still to build.)
|
||||
- **host-api stays HTTP/JSON — locked**, because its consumer is the Chromium kiosk
|
||||
(a browser, which cannot speak native gRPC).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user