# 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](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](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 **`` 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 `` 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 ` 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 TARGET** — `felhom-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.