Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.5 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.
Hub v0.12.0 — retire Infra Backup, purge plaintext secrets, fix backup-deadline email
Date: 2026-06-16
Scope: Phase-1 of documentation/audits/SPIKE-infra-backup-2026-06-15.md (hub side).
Deployed: felhom-hub:v0.12.0 live on k3s (ArgoCD felhom app Synced); commit 0635640.
Companion repo: felhom-controller v0.69.0 (own REPORT there).
What shipped
-
Backup-deadline check repointed to PBS freshness (
internal/monitor/deadline.go). The backup half no longer queries for abackup_completedevent (nothing emits it post-slice-8C, so it fired daily for every healthy customer). It now reads the customer's latest agent host-report (store.GetLatestHostReportJSON) and raisesexpected_backup_missedonly on positive evidence: no PBS snapshot / successful vzdump at all, newest backup older than 26h, or the newest PBS snapshot'sverify_state == "failed". A fresh-but-unverified snapshot is not a failure (PBS verifies on its own cadence — alarming on it would recreate the false alarm). The db-dump half is unchanged. A customer with no host-report gets no backup alarm here (liveness is the host-staleness checker's job). -
Infra Backup feature removed (
api/handler.go,store/store.go,web/configs.go,templates/customer_unified.html,templates/customer.html): thePOST/GET /api/v1/infra-backup[…]endpoints + handlers, the store methods/types (SaveInfraBackup/GetInfraBackup/GetInfraBackupByID/GetInfraBackupMeta/ListInfraBackupVersions/pruneInfraBackups,InfraBackupMeta/InfraBackupVersion), and the operator "Infra Backup" panel.GET /api/v1/recovery/{id}now returns config_yaml only. The customer-page config-drift badge (diffed against the stored controller.yaml) is hidden; the live "Show Diff" path is unaffected. -
Plaintext secret purge (
store/store.go migrate()):DROP infra_backup_versions; DROP infra_backups; VACUUM; wal_checkpoint(TRUNCATE)— gated on table existence so normal restarts skip it. VACUUM physically reclaims the freed pages so the plaintext keys/tokens are not merely delinked.
Gate (STEP 1a) — PASSED before any change
The demo's latest host-report (id 699, agent v0.36.7) carried 5 PBS snapshots, all verify=ok,
newest 2026-06-15T18:41:29Z (13.9 h old, < 26 h) plus a matching successful vzdump. The repoint's
data source is present and fresh, so the repoint alone clears the email.
Verification (live, non-hollow)
- Build + tests:
go build ./... && go test ./...green.deadline_test.gocovers fresh+verified→ quiet (the companion), stale→alarm, failed-verify→alarm, no-host-report→quiet, db-dump half preserved, and a pureassessBackupFreshnesstable. Red-proof: with the old event-based half temporarily restored, the companion + no-report + db-dump-preserved tests fail, while the pure-helper test still passes — the behavioral tests are sensitive to the logic. - Deploy: hub v0.12.0 rolled out; startup log:
Retired infra-backup: dropped 2 table(s) and VACUUMed to reclaim plaintext pages. - Tables gone:
.tableson the live/data/hub.dbshows noinfra_backup*. DB shrank 65.8 MB → 52.2 MB; no-walsidecar lingers. - Secret purge proof (grep on the live post-VACUUM DB file): the infra-backup-exclusive markers
are gone —
encryption_key_b6417→0,controller_config_b6411→0, and the actual AES-key value from spike record 109 present→0 (physically reclaimed, not just delinked). The residualcf_api_token/cf_tunnel_tokenhits are incustomer_configs.config_json(the hub's legitimate config store), not the infra-backup blobs (which held CF tokens base64-encoded inside the now-zerocontroller_config_b64). - Endpoints retired:
POST /api/v1/infra-backupandGET …/versionsreturn 404; controlPOST /api/v1/reportstill returns 401 (routed, unauth) — confirming the 404s are route removal, not a blanket failure. - Demo email fix: the next 03:00 deadline run cannot be observed within this session, but the live
demo host-report (fresh verified PBS, 13.9 h) exercises the not-missed path, and demo emits
db_dump_completeddaily (never missed) — soexpected_backup_missedwill no longer fire.
Flagged for the operator (out of scope here)
- Rotate the exposed credentials that were in the dropped blobs (Cloudflare API + tunnel tokens
for
demo-felhom.eufirst; hub/session secrets if shared). They remain valid until rotated; the purge removes the at-rest copy but not their validity. - Separate historical leak: the legacy
reportstable holds thousands of rows with a plaintextrestic_passwordvalue from old controller versions. The live controller no longer sends it (removed in controller v0.69.0), but the historical rows persist — a distinct purge/rotation decision, deliberately not done here. peti-felhomis a defunct customer markedactive(no host-report or controller report since Feb 2026). Its dailyexpected_backup_missedstops with this change (no host-report → no backup alarm), but it should be marked inactive to silence all residual noise.
Out of scope (untouched)
Credential rotation; the Komga healthcheck; the secret-free DR "recipe" (the later DR slice).