docs: pool-effects no-mercy campaign — op-matrix 16/16, B1 rollback-destroy finding, fix list (F1-F6)
Full validation of the felhom pool + scoped-token migration on felhom-pve: - Track A: complete agent op surface under the scoped token — 16/16 pass - Track B: vmid origin traced (externally supplied); adversarial collision probes prove the compensating rollback/teardown attempts to destroy a guest the job never created (contained only by the pool ACL) - Track C: containment + 3b-fix intact; Track D: no pool leaks, adopt/ uninstall pool handling correct - Findings doc: documentation/audits/CAMPAIGN-pool-effects-2026-07-01.md No code change, no version bump. Demo left as found. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,55 +4,25 @@
|
||||
|
||||
---
|
||||
|
||||
# REPORT — Impl-1 Part B: install the guarded-mkfs wrapper (host-install v1.8.0)
|
||||
# REPORT — "no-mercy" campaign: full effects of the `felhom` pool + scoped-token migration
|
||||
|
||||
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`scripts/` only) · **Class:** Risky/supervised (paired with
|
||||
the destructive-path change in felhom-agent v0.54.0).
|
||||
**Date:** 2026-07-02 · **Class:** Runbook-style validation (aggressive, throwaway env) · **No code change, no version bump.**
|
||||
**Findings doc:** [`documentation/audits/CAMPAIGN-pool-effects-2026-07-01.md`](documentation/audits/CAMPAIGN-pool-effects-2026-07-01.md)
|
||||
|
||||
Companion to felhom-agent v0.54.0 (the format-safety foundation). Script-only change: host-install now
|
||||
installs the guarded-mkfs wrapper during agent install so every fresh box gets the safe format path.
|
||||
Executed the full pool-effects campaign on felhom-pve (agent v0.59.0 live, host-install v1.7.0 scoped ACL): source-traced every `ListLXC` consumer in felhom-agent (read-only), then ran the complete agent→PVE operation matrix under the scoped token on scratch pool guests 9310/9311, adversarial pool-blindness probes with non-pool decoys, blast-radius regression re-confirms, and pool-membership side-effect checks.
|
||||
|
||||
## 1. Baseline → target
|
||||
## Headline results
|
||||
|
||||
script `v1.7.0` @ `9e5bbc1` → **v1.8.0**. Paired with agent v0.54.0 (separate repo, `5209830`).
|
||||
1. **Track A — 16/16 ops PASS, zero surprise 403s.** The scoped token is functionally complete for the agent's real operation surface (incl. the previously untested Destroy+disk-reap, Snapshot/Rollback/Delete, SetConfig Network/CPU/Options, Resize, ListRunningTasks, TaskLogTail, and the full restore-test cycle).
|
||||
2. **B1 (the campaign's most important result):** the provision vmid is **always externally supplied** (no `nextid` scan in agent OR hub — collision-avoidance is operator-side). Adversarially provisioning onto an existing **non-pool** vmid: the pool-blind duplicate guard misses it, PVE refuses the restore (no clobber), **but the compensating rollback then attempts to DESTROY the innocent guest** — stopped only by the pool ACL (403). Same shape live-proven for the restore-test scratch band (a squatter at 990000 additionally makes the restore-test **permanently FAIL** with false "backup unrestorable" alerts). Safe-but-noisy under the scoped ACL; a genuine destroy-risk under any broad token.
|
||||
3. **Containment intact (Track C):** non-pool guest ops 403, non-granted-storage writes 403, drive audit readable (3b-fix holds).
|
||||
4. **Hub inventory is pool-only (B3, by design — now recorded as a decision):** operators must pick vmids from the host's real guest list, never the hub view. No pool-name leak into any customer/controller-facing field (Track D); `--adopt-pool` idempotent; uninstall never deletes a non-empty pool.
|
||||
|
||||
## 2. What changed
|
||||
## Fix list (full detail + severities in the findings doc)
|
||||
|
||||
- `scripts/felhom-host-install.sh` `step_agent_install`: new step (before the sudoers install) that
|
||||
`fetch_raw`s `configs/felhom-mkfs-guarded.sh` from Gitea, `bash -n`-validates it, and
|
||||
`install -m0755 -o root -g root` → `/usr/local/sbin/felhom-mkfs-guarded`. Wrapper-before-sudoers so
|
||||
the sudoers (which allowlists only the wrapper) is never installed ahead of the file it names.
|
||||
- The agent v0.54.0 sudoers (fetched by the same step) drops raw `mkfs.*` (allowlists only the wrapper)
|
||||
and adds read-only `pvs`/`zpool status -P` for the agent's unclaimed-disk guard.
|
||||
- `scripts/CHANGELOG.md`, version banner. Commit **`7ea36bc`** on `main`.
|
||||
- `bash -n` + `shellcheck` clean (0 new warnings; the 2 pre-existing SC2015 in `step_verify` unchanged).
|
||||
- **F1 (HIGH, blocks shared-box trial):** arm the bring-up/restore-test compensating destroy only after `RestoreLXC` returns a UPID — never destroy what the job didn't create.
|
||||
- **F2 (MED, blocks trial):** restore-test should advance past an "already exists" band vmid (or pre-verify via fenced root CLI); document 990000–990009 as reserved fleet-wide.
|
||||
- **F3 (MED, doc-only, blocks trial):** provisioning runbook must say vmid selection uses the host's full guest list, not the hub inventory.
|
||||
- F4/F5/F6 (LOW/INFO): non-pool source-config read in restore-test, pool-blind eject dependent-scan, latent reconcile desired-state rule.
|
||||
|
||||
## 3. Served-copy version
|
||||
|
||||
`curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh | grep SCRIPT_VERSION` → **`1.8.0`**.
|
||||
|
||||
## 4. Live validation (felhom-pve, agent v0.54.0 deploy)
|
||||
|
||||
The two-layer format guard (agent unclaimed-filter + this wrapper) validated on the demo — details in
|
||||
`felhom-agent/REPORT.md` §5:
|
||||
- wrapper REFUSES the OS disk `/dev/sda` and the LVM-PV partition `/dev/sda3`;
|
||||
- raw `sudo mkfs.ext4 /dev/sda` is DENIED (Part B — wildcard removed);
|
||||
- an unclaimed throwaway `/dev/sdd` FORMATS (the only real format);
|
||||
- the agent guard's sudo reads (`pvs`/`lsblk`/`zpool`) all work as the felhom-agent user.
|
||||
|
||||
**Deploy note:** installing the sudoers via a manual scp of the Windows working-copy failed `visudo`
|
||||
(CRLF line endings); fixed live by CR-stripping. The committed repo file is LF, and the host-install
|
||||
`fetch_raw`-from-Gitea path serves LF — so the shipped path is unaffected. (Lesson recorded.)
|
||||
|
||||
## 5. NOT yet live-validated / deferred
|
||||
|
||||
- A **fresh install** exercising the new `step_agent_install` wrapper-install step end-to-end (the demo
|
||||
was repaired in place; a clean box will exercise the fetch+install path — the code is dry-run-safe and
|
||||
mirrors the existing sudoers/unit install).
|
||||
- **Impl-2** (raw-device discovery + registry enrollment + wizard rewiring) and **Impl-3** (shared-box
|
||||
operator gate for self-serve format) are the separate follow-up specs.
|
||||
|
||||
## 6. Observations
|
||||
|
||||
- The guarded-mkfs wrapper is `configs/felhom-mkfs-guarded.sh` in the **felhom-agent** repo (co-located
|
||||
with the sudoers it pairs with); host-install fetches it the same way it fetches the unit/sudoers.
|
||||
Demo left exactly as found: pool `felhom` = {9201}, all scratch/decoy guests and campaign artifacts removed, agent active, controller healthy.
|
||||
|
||||
Reference in New Issue
Block a user