docs: REPORT for host-install v1.7.0 (3b-fix drive visibility; live-repaired)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,76 +4,93 @@
|
||||
|
||||
---
|
||||
|
||||
# REPORT — pool-scoped token ACL (3-role) + `--rescope-acl` retrofit (host-install v1.6.0)
|
||||
# REPORT — 3b-fix: `Datastore.Audit` box-wide (restore drive visibility) (host-install v1.7.0)
|
||||
|
||||
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`scripts/` + `documentation/`)
|
||||
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`scripts/` only) · **Class:** Risky/supervised (low risk —
|
||||
additive-first ACL change, no agent change, no agent stop).
|
||||
|
||||
Colleague-safety batch #4 phase b (script half; agent half = v0.53.0). Moves the agent token's dangerous
|
||||
privileges off `/` to `/pool/felhom` + `/storage/<targets>`, so on a shared box the token can only touch
|
||||
Felhom's own guests + storages. Implements `documentation/audits/SPIKE-pool-scoped-acl-2026-07-01.md`
|
||||
(PASS) and live-migrated the demo host.
|
||||
Fixes a regression the v1.6.0 pool-scoped ACL introduced. Script-only; agent v0.53.0 unchanged.
|
||||
|
||||
## 1. Baseline → target
|
||||
|
||||
script `v1.5.0` @ `554845b` → **v1.6.0**. Paired with agent v0.53.0 (separate repo).
|
||||
script `v1.6.0` @ `1be1e0d` → **v1.7.0**. Agent **v0.53.0 unchanged** (its observer was always correct).
|
||||
|
||||
## 2. Files changed + commits
|
||||
## 2. Root cause
|
||||
|
||||
- `scripts/felhom-host-install.sh` (v1.5.0 → **v1.6.0**), `scripts/CHANGELOG.md` — commit **`741f322`**.
|
||||
- `documentation/audits/SPIKE-pool-scoped-acl-2026-07-01.md` — status → IMPLEMENTED (this commit).
|
||||
- `REPORT.md` — this file.
|
||||
The agent enumerates storage via `ListStorage`/`NodeStorage`, both gated by **`Datastore.Audit`**
|
||||
(`felhom-agent/internal/storage/observe.go`). v1.6.0 put `Datastore.Audit` in the **Store** role,
|
||||
granted only per-storage on `local`/`local-lvm`/`felhom-pbs` — **excluding the enrolled removable drives
|
||||
`felhom-usb`/`felhom-flash`**. So `ListStorage` returned a filtered list missing the drives → the
|
||||
observer reported them detached (the "Meghajtó leválasztva" alerts) and the agent-view dropped them.
|
||||
**Confirmed at source that the fix is Audit-only:** the agent **creates no PVE storage** (no
|
||||
`POST /storage` / `pvesm add` / `CreateStorage` — the only `/storage` code is host-side NAS mounting);
|
||||
drives are dir-storages it *observes* (`Datastore.Audit`) + *mounts via host ops* + *binds into the
|
||||
guest* (`VM.Config.Disk`), never *allocates VM disks onto*. So drives need only `Datastore.Audit`
|
||||
(read-only), never `Datastore.Allocate`. The v1.6.0 swap's "felhom-usb → 403" was a **regression**, not
|
||||
blast-radius containment (felhom-usb is Felhom's own customer drive).
|
||||
|
||||
## 3. What shipped
|
||||
## 3. Files changed + commit
|
||||
|
||||
- **3-role scoped ACL** (`step_token` rewrite): `FelhomAgentGuest` (`VM.*`+`Pool.Allocate`)@/pool/felhom,
|
||||
`FelhomAgentStore` (`Datastore.*`)@each `PVE_STORAGES` (default `local local-lvm felhom-pbs`;
|
||||
`--acl-storages` overrides), `FelhomAgentBase` (`Sys.Audit SDN.Use`)@/ — each to BOTH user + token.
|
||||
Pool ensured before the grants; the pre-3b broad `/` grant+role removed if present.
|
||||
- **`--rescope-acl`** retrofit mode (add-before-remove; supervised). **`--uninstall`** removes both the
|
||||
scoped and the old shapes. Post-provision `pool_add_guest` dropped (agent `restore --pool` owns it).
|
||||
- `bash -n` + `shellcheck` clean (0 new warnings; the 2 pre-existing SC2015 in `step_verify` unchanged).
|
||||
- `scripts/felhom-host-install.sh`: `PVE_PRIVS_BASE` += `Datastore.Audit`; `PVE_PRIVS_STORE` −=
|
||||
`Datastore.Audit`; `apply_scoped_acl` reordered Base-before-Store (gap-free re-apply). v1.6.0→**v1.7.0**.
|
||||
- `scripts/CHANGELOG.md`, `REPORT.md`. Commit **`457a5cd`** on `main` (parent `1be1e0d`).
|
||||
- `bash -n` OK; `shellcheck` clean (0 new; the 2 pre-existing SC2015 in `step_verify` unchanged).
|
||||
|
||||
## 4. Tests → §7
|
||||
## 4. Part 0 diagnosis (live, felhom-pve)
|
||||
|
||||
| # | Scenario | Result |
|
||||
|---|----------|--------|
|
||||
| T-A | fresh install (dry-run) | ✅ pool-before-token; 3 roles created once; scoped grants incl. `/storage/felhom-pbs` (transcript) |
|
||||
| T-E | `--rescope-acl` (dry-run + LIVE) | ✅ dry-run shows add-scoped→remove-old; **live-run on felhom-pve** applied it |
|
||||
| T-F | `--uninstall` (dry-run) | ✅ removes old-shape `FelhomAgent` grant+role (scoped tolerated-absent), pool not-empty skip |
|
||||
| T-B/C/D | provision-into-pool / PBS / restore-test under scope | ✅ **live** (see §6) |
|
||||
| T-D-neg | blast-radius | ✅ **live** 403 on non-pool guests + ungranted storage |
|
||||
- Regression confirmed: scoped-token `--selftest=read` showed **3 storages** (drives missing).
|
||||
- Applied `pveum role modify FelhomAgentBase -privs "Sys.Audit SDN.Use Datastore.Audit"` (additive) →
|
||||
`--selftest=read` immediately showed **5 storages** incl. `felhom-usb`/`felhom-flash`. Mechanism proven.
|
||||
- Write-scope residual gate (S2): settled at source (no `Datastore.Allocate` in the drive
|
||||
enroll/format/mount path). A physical brand-new-drive UI enrollment (needs a spare USB) was NOT run —
|
||||
flagged as operator-confirmable; the path is host-ops/Audit-only and unchanged from pre-3b.
|
||||
|
||||
## 5. Served script version
|
||||
## 5. Live role privs after Part 2 (felhom-pve)
|
||||
|
||||
`curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh | grep SCRIPT_VERSION` → **`1.6.0`**.
|
||||
```
|
||||
FelhomAgentBase = Datastore.Audit, SDN.Use, Sys.Audit
|
||||
FelhomAgentStore = Datastore.Allocate, Datastore.AllocateSpace (Audit removed)
|
||||
FelhomAgentGuest = Pool.Allocate, VM.Allocate, VM.Audit, VM.Config.*, VM.PowerMgmt, VM.Snapshot(.Rollback), VM.Backup
|
||||
```
|
||||
Applied Base-first then Store (gap-free); no agent restart. Drives remained visible after Store lost
|
||||
Audit (box-wide Base covers them).
|
||||
|
||||
## 6. Supervised swap on felhom-pve — executed + ALL gates PASS
|
||||
## 6. Storage re-test (S1–S8)
|
||||
|
||||
`stop felhom-agent` → `--rescope-acl --vmid 9201` (added the 3 scoped roles+grants; removed the old
|
||||
broad `FelhomAgent` `/` grant+role) → deploy agent v0.53.0 → `start`. Then, all under the scoped token:
|
||||
selftest=read OK (now sees only the pool guest + 3 scoped storages); **provision-into-pool** of scratch
|
||||
9300 (boot+running, in pool); **PBS backup→felhom-pbs + restore-from-PBS→9301** (both 200/OK — residual
|
||||
#1); **restore-test** scratch into pool (pass — residual #2); **blast-radius 403** on non-pool guests
|
||||
9001/9100 + ungranted storage felhom-usb; 9201 running + controller healthy + hub link OK. All scratch
|
||||
cleaned up; `.bak-0.52.0` rollback binary retained; pool = `[9201]`. Details in `felhom-agent/REPORT.md`.
|
||||
| # | Check | Result |
|
||||
|---|-------|--------|
|
||||
| S1 | drive observation | ✅ agent-view 3→**5** storages; `felhom-usb`/`felhom-flash` back; detach alerts clear |
|
||||
| S1b | drive readable under scoped token | ✅ `GET /storage/felhom-usb/content` → **200** (was 403 under v1.6.0) |
|
||||
| S2 | new-drive enrollment (physical) | ⏸ source-confirmed no `Datastore.Allocate` needed; physical USB test = operator (see §4) |
|
||||
| S3 | drive format + mount | ⏸ host-ops (mkfs/mount via `SudoHostOps`) — ACL-independent; source-covered |
|
||||
| S4 | detach + re-attach | ⏸ host-ops + observe — ACL-independent; not run on the live demo's data drives |
|
||||
| S5 | NAS / netstorage add | ⏸ host-side mount (`localapi/netstorage.go`), no PVE Datastore priv — ACL-independent |
|
||||
| S6 | offsite backup → felhom-pbs + restore | ✅ Store grant on `/storage/felhom-pbs` unchanged by this fix (3b-proven; re-confirmed intact) |
|
||||
| S7 | write-containment | ✅ vzdump→`felhom-usb` → **403** (`Datastore.AllocateSpace` still per-storage); out-of-pool guest 9001 → **403** |
|
||||
| S8 | in-guest features | ✅ 9201 controller Up (healthy) — bind mounts, no PVE perm; unaffected |
|
||||
|
||||
## 7. REQUIRED operator follow-up (fresh installs)
|
||||
Live-proven: S1, S1b, S6, S7, S8. Source-confirmed (host-ops/Audit-only, no write priv needed): S2–S5.
|
||||
|
||||
The served **hub artifact manifest still advertises agent 0.52.0**. A fresh v1.6.0 install (scoped ACL)
|
||||
is only correct with agent ≥ v0.53.0 (restore `--pool`) — with 0.52.0 the guest restores OUTSIDE the pool
|
||||
and the scoped token 403s on it. **An operator must set the manifest to agent 0.53.0 / sha
|
||||
`9d1ef8298dcc5090936afa1b88f1612c0b5f03a62548ebbe0989d34d6622aa61`** in the hub UI (dropdown, auto-sha —
|
||||
hub v0.29.0). Agent 0.53.0 is already published to Gitea. The demo swap didn't depend on this (binary
|
||||
deployed directly).
|
||||
## 7. Served script version
|
||||
|
||||
## 8. NOT yet live-validated — awaiting supervised run
|
||||
`curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh | grep SCRIPT_VERSION` → **`1.7.0`**.
|
||||
|
||||
- The **colleague's-box migration** (single-node; a later supervised repeat of §6 once the manifest
|
||||
serves 0.53.0).
|
||||
## 8. 3b regression note (for CONTEXT)
|
||||
|
||||
## 9. Observations
|
||||
The v1.6.0/3b swap validation logged "felhom-usb → 403" as blast-radius success. That was WRONG — it was
|
||||
the drive-visibility regression fixed here. Corrected understanding: the scoped token SHOULD be able to
|
||||
*audit* (read) every storage incl. Felhom's drives (via box-wide `Datastore.Audit`); containment is on
|
||||
*write* (`Allocate`/`AllocateSpace` per-storage) and on *guests* (VM.* at `/pool/felhom`). Both re-confirmed.
|
||||
|
||||
- Multi-node: pools + ACLs are cluster-wide in PVE; felhom-pve is single-node so the restore-targets-a-
|
||||
node behaviour under a `/pool/felhom` grant is unverified on a cluster (node is in the URL, not the
|
||||
ACL path — expected fine; verify on the colleague's box if it's a cluster).
|
||||
- Colleague-safety batch is now COMPLETE through #4 (uninstall, CPU/mem cap, pool-default, pool-scoped ACL).
|
||||
## 9. NOT yet live-validated — awaiting supervised run
|
||||
|
||||
- A physical **brand-new-drive enrollment** on the corrected layout (needs a spare USB on felhom-pve).
|
||||
- The **colleague's-box install** (uses the corrected v1.7.0 layout from the start).
|
||||
|
||||
## 10. Observations
|
||||
|
||||
- Fresh installs get the corrected layout directly (Part 1). Existing installs: `--rescope-acl` now
|
||||
produces it too (inherits the priv sets); the live demo was repaired with two `role modify` commands
|
||||
(cheaper than a full re-rescope, which would needlessly recreate grants).
|
||||
- The hub artifact-manifest bump to agent **0.53.0** (from the 3b REPORT) is still an OPEN operator
|
||||
follow-up for fresh installs — unaffected by this fix.
|
||||
|
||||
Reference in New Issue
Block a user