Files
felhom.eu/REPORT.md
T

5.6 KiB

felhom.eu — task reports

Overwrite this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in hub/CHANGELOG.md; the scripts history lives in scripts/CHANGELOG.md.

TASK GL-7 — customer page: passphrase hardening + install-command generator (hub v0.36.0) — 2026-07-09

Shipped: felhom.eu 844fbfa7 (code) + 02c748eb (manifest bump); hub v0.36.0 LIVE on k3s (ArgoCD app felhom Synced/Healthy, rollout confirmed, live image felhom-hub:0.36.0, Listening on :8080). felhom.eu only — agent + host-install untouched. Two coupled, security-first changes to the operator customer page, plus the Peti tester agreement.

Part 1 — passphrase hardening (the security win, ships first)

The per-customer retrieval passphrase was in cleartext twice: the visible #retrieval-pw node and baked into the Option-3 debug curl's X-Retrieval-Password: header (a copyable command carrying the secret). Now:

  • #retrieval-pw renders a masked bullet run by default, with a Reveal (toggleSecret) and a copy (copySecret) control; the value lives in data-secret (the page's existing reveal model — the value still ships in the DOM, unchanged from before).
  • The Option-3 command carries a <YOUR-RETRIEVAL-PASSWORD> placeholder — the secret is never in a copyable command block.
  • A zero-secret-in-DOM reveal-on-demand fetch is a deliberate future follow-up, explicitly NOT scoped here (kept the change tight and reviewable).

Part 2 — interactive install-command generator

The three hard-coded install <code> blocks became a client-side builder (vanilla JS — no framework, CDN, or network call) that assembles a live-updating command from form controls:

  • Emits only real host-install v1.12.0 flags in a download-then-run shape (never curl | bash).
  • CustomerID prefilled from the server (pageData.ScriptVersion + data-customer-id); a byo selection requires --cores/--memory (client-side enforcement via .gen-req + a gen-msg prompt); caps/mode are placeholders, never silent defaults.
  • Graceful JS-off static fallback: the Option-1/2 code nodes retain a --customer-id … --mode <appliance|byo> command.
  • Curated control surface (mode/cores/memory/vmid/node/acl-storages/operator-pubkey-file/ preserve-state-from + skip-provision/dry-run/preflight-only/allow-new-leaf). The seven dangerous/operator-only flags (--force, --rotate-recovery, --enable-oob, --remove-golden, --uninstall, --adopt-pool, --rescope-acl) are never offered as controls.

configs.go: const hostInstallVersion = "1.12.0"; pageData.ScriptVersion added + populated. style.css: .gen-controls/.gen-radios/.gen-radio/.gen-check(s)/number-inputs/.gen-msg (dark palette, 2px radius).

Part 3 — tests (green gate passed on committed source)

  • TestTemplates_PassphraseHardened — the secret is NOT in the Option-3 command (placeholder is), #retrieval-pw is masked-by-default (bullet-entity run), data-secret populated, reveal+copy controls present. Red-proof: revert the Option-3 block to {{.Config.RetrievalPassword}} → the "not-in-command" / masked assertions fail.
  • TestTemplates_InstallGenerator — every curated control id renders, script version + data-customer-id present, the JS-off static fallback command present, and none of the seven excluded flags appear anywhere on the page.
  • go build ./... && go vet ./... && go test ./internal/web/ok on the committed source (844fbfa7).

Part 4 — deploy (GitOps)

Built felhom-hub:0.36.0 on 180 from the pushed source, bumped manifests/hub.yaml (0.35.0→0.36.0), ArgoCD hard-refresh + sync → Synced/Healthy, deploy/hub rolled out, live image + startup log confirmed. Gotcha caught: the first build produced a stale image because the Part-1/Part-2 commits were committed locally but not pushed before building (build.sh pulls origin) — fixed by pushing first, then rebuilding.

Part 5 — tester agreement + closeout

documentation/pilot/PETI-tester-agreement.md written: the BYO trust boundary (break-glass/OOB/WG all OFF, non-root agent, pool-scoped token, TLS+per-guest-token local API), the honest limitations (no offsite backup yet; physically-removable-drive caveat F2; pool-reassert-bring-up-only F7; :53-must-be-free F6), exit rights (uninstall keeps drives/data/hub-record), Peti's box facts (80c/128 GB → caps 12/32768, sajatfelhom.hu tunnel re-point), the byo install command, and the onboarding sequence (preflight → install → G9 password-set → tunnel → backup-green). GO-LIVE-PACKAGE updated: GL-7 ✔; G9/G10 → done, G11 → done (with the one open pilot question folded into the agreement's pre-install checklist); decision log + open-questions updated.

The one remaining pilot question (owned by the agreement)

Peti's local backup TARGETfelhom-pbs is unreachable from his LAN, so the default --acl-storages "local local-lvm felhom-pbs" is wrong for him. Confirm at onboarding whether his box has a second disk/pool: if yes it becomes the --acl-storages backup target (real local resilience); if no, backups share the guest's pool (degraded — one drive failure loses both, must be stated to him). Changes only the --acl-storages value, nothing structural.

Verification note

The hub UI is operator-password-gated — CC cannot log in, so per the repo policy UI changes are verified via the render tests (both green) plus the deploy checks (image/rollout/startup log), not a live browser session.