agent v0.24.0: role-gate the eject path (system/backup mounts unmount-protected at the agent)
handleDiskEject now resolves the authoritative role of the storage at `where` and refuses 403 (no Unmount) unless it is user-data. Fails safe to protected on ambiguity. Adds roleForMountPath + an injectable HostReader seam for testability. TestEject_RoleGated asserts protected mounts are refused with no Unmount. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,27 @@
|
||||
All notable changes to **felhom-agent** are recorded here. Update on every code
|
||||
change that gets pushed.
|
||||
|
||||
## v0.24.0 — role-gate the eject path (system/backup mounts are unmount-protected at the agent) (2026-06-12)
|
||||
|
||||
Closes the eject gap in the storage-authorization redesign: `POST /disks/eject` now **refuses to
|
||||
unmount a system or backup storage**, enforced at the agent — not just hidden in the controller UI.
|
||||
A direct API call (or a compromised controller) trying to `eject {where:"/var/lib/vz"}` or the PBS
|
||||
mount is refused 403; only `user-data` mounts are ejectable.
|
||||
|
||||
- **`handleDiskEject` (`internal/localapi/disks.go`)** — before `Unmount`, resolves the AUTHORITATIVE
|
||||
protection role of the storage mounted at `where` (the agent's own storage-view + host-topology
|
||||
classification, never the caller's claim) via the new `roleForMountPath`. Refuses (403, no
|
||||
`Unmount`) unless the role is `user-data`. **Fails SAFE**: an unresolvable mount (view error or no
|
||||
storage target at that path) → treated as protected → refused (the same most-protected-on-ambiguity
|
||||
default the wipe gate uses). Mirrors the wipe path's "protected — eject refused by role" logging.
|
||||
- **`roleForMountPath` + `hostReader` seam** — `roleForMountPath` keys `RoleForStorage` on the mount
|
||||
path (the eject input), mirroring `deviceRole`. `Options.HostReader` (optional; defaults to the
|
||||
production `*storage.ProcHostReader`) injects the root-free topology reader so the role-gate is unit-
|
||||
testable. `handleDisks`/`deviceRole` now share the same seam.
|
||||
- **Tests** — `TestEject_RoleGated` asserts a `system` and a `backup` mount are refused with **no
|
||||
`Unmount`**, a `user-data` mount ejects, and an unresolvable mount fails safe to refused (the same
|
||||
non-hollowness the wipe tests use). `TestEject_UnmountAndDependents` updated to a user-data target.
|
||||
|
||||
## v0.23.0 — device-ROLE classification + tiered storage-wipe gate (system/backup operator-only, user-data customer-confirmable) (2026-06-11)
|
||||
|
||||
The storage-authorization redesign (agent half). The gate's destructive-wipe path is now **tiered by
|
||||
|
||||
Reference in New Issue
Block a user