host-install v1.7.0: 3b-fix — Datastore.Audit box-wide (restore drive visibility)
v1.6.0 put Datastore.Audit in the per-storage Store role, hiding the enrolled drives (felhom-usb/felhom-flash) from the agent's storage enumeration → false detach alerts. Move Datastore.Audit (read-only) to box-wide Base; keep write privs (Allocate/AllocateSpace) per-storage → visibility restored, write containment unchanged. apply_scoped_acl reordered Base-before-Store (gap-free re-apply). Live-repaired felhom-pve (role modify, no agent stop): drives back, alerts cleared, write-containment + guest-403 re-confirmed. bash -n + shellcheck clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,33 @@
|
||||
# Felhom scripts — Changelog
|
||||
|
||||
## felhom-host-install.sh v1.7.0 — 3b-fix: `Datastore.Audit` box-wide (restore drive visibility) (2026-07-01)
|
||||
|
||||
Fixes a regression the v1.6.0 pool-scoped ACL introduced: `Datastore.Audit` was placed in the
|
||||
per-storage `Store` role (granted only on `local`/`local-lvm`/`felhom-pbs`), which **excluded the
|
||||
enrolled removable drives** `felhom-usb`/`felhom-flash`. The agent enumerates storage via
|
||||
`ListStorage`/`NodeStorage` (both gated by `Datastore.Audit` — `internal/storage/observe.go`), so it
|
||||
could no longer SEE the drives → false "Meghajtó leválasztva" (drive detached) alerts + drives absent
|
||||
from the agent-view. (The v1.6.0 swap's "felhom-usb → 403" was mis-read as blast-radius success;
|
||||
felhom-usb is Felhom's OWN customer drive, not an out-of-scope object.)
|
||||
|
||||
- **`Datastore.Audit` moved from Store → Base** (`PVE_PRIVS_BASE` now `"Sys.Audit SDN.Use
|
||||
Datastore.Audit"`; `PVE_PRIVS_STORE` now `"Datastore.Allocate Datastore.AllocateSpace"`). Audit is
|
||||
read-only metadata, so box-wide Audit restores visibility of ALL storages (incl. dynamically-enrolled
|
||||
drives — no per-drive grant ever needed) while the **write** privs (`Allocate`/`AllocateSpace`) stay
|
||||
per-storage → write/allocate blast-radius containment is UNCHANGED. Confirmed at source: the agent
|
||||
creates no PVE storage (no `POST /storage`/`pvesm add`); drives are dir-storages it observes + mounts
|
||||
via host ops, so they need only Audit, never Allocate.
|
||||
- **`apply_scoped_acl` reordered** Base-before-Store (role + grant) so a RE-APPLY on a live box adds
|
||||
`Audit@/` before Store drops its per-storage Audit → gap-free (the agent never loses enumeration).
|
||||
- `remove_scoped_acl` / `--uninstall` / `--rescope-acl` operate by role NAME and inherit the corrected
|
||||
privs automatically (no other change).
|
||||
- **Live-repaired felhom-pve** (two `pveum role modify`, Base first — no agent stop/restart): drives
|
||||
reappeared (agent-view 3→5 storages), detach alerts cleared. Re-tested under the scoped token: drives
|
||||
readable (was 403), write-containment intact (vzdump→felhom-usb still 403; out-of-pool guest 403),
|
||||
PBS Store grant unchanged. `bash -n` + `shellcheck` clean (0 new warnings).
|
||||
- **NOT physically run** (source-confirmed, no `Datastore.Allocate` in the path): a brand-new-drive UI
|
||||
enrollment (needs a spare USB) — the host-ops/Audit path is unchanged from pre-3b.
|
||||
|
||||
## felhom-host-install.sh v1.6.0 — pool-scoped token ACL (3-role) + `--rescope-acl` retrofit (2026-07-01)
|
||||
|
||||
Colleague-safety batch #4 phase b (script half; agent half = v0.53.0). Moves the agent token's dangerous
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#===============================================================================
|
||||
# felhom-host-install.sh v1.6.0
|
||||
# felhom-host-install.sh v1.7.0
|
||||
# Day-0 host-bootstrap for a Felhom Proxmox host (operator-deploy model).
|
||||
#
|
||||
# Run by the operator on a FRESHLY-PVE-INSTALLED box (after a manual PVE install
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_VERSION="1.6.0"
|
||||
SCRIPT_VERSION="1.7.0"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Logging (mirrors felhom-controller/scripts/docker-setup.sh)
|
||||
@@ -172,14 +172,17 @@ PVE_ROLE="FelhomAgent" # the PRE-3b single broad role (removed on rescope/unin
|
||||
# across THREE roles applied at scoped paths so the token can only touch Felhom's own guests + storages
|
||||
# (blast-radius containment). `pveum acl` grants a whole role per path, hence 3 roles not 1. Each role is
|
||||
# granted to BOTH the user AND the token (privsep intersection). Guest privs (incl. Pool.Allocate so the
|
||||
# agent restores INTO the pool) live at /pool/felhom; Datastore privs at each agent-touched storage; only
|
||||
# Sys.Audit+SDN.Use box-wide at /.
|
||||
# agent restores INTO the pool) live at /pool/felhom; Datastore WRITE privs at each agent-touched storage.
|
||||
# `Datastore.Audit` is box-wide in Base (3b-fix v1.7.0): the agent must ENUMERATE every storage incl. the
|
||||
# dynamically-enrolled removable drives (felhom-usb/felhom-flash) it observes but never registers — a
|
||||
# per-storage Audit grant hid them → false "drive detached" alerts. Audit is read-only, so box-wide Audit
|
||||
# keeps WRITE containment (Allocate/AllocateSpace stay per-storage). Only Sys.Audit/SDN.Use/Datastore.Audit box-wide.
|
||||
PVE_ROLE_GUEST="FelhomAgentGuest"
|
||||
PVE_ROLE_STORE="FelhomAgentStore"
|
||||
PVE_ROLE_BASE="FelhomAgentBase"
|
||||
PVE_PRIVS_GUEST="VM.Allocate VM.Audit VM.Config.Disk VM.Config.CPU VM.Config.Memory VM.Config.Network VM.Config.Options VM.PowerMgmt VM.Snapshot VM.Snapshot.Rollback VM.Backup Pool.Allocate"
|
||||
PVE_PRIVS_STORE="Datastore.Allocate Datastore.AllocateSpace Datastore.Audit"
|
||||
PVE_PRIVS_BASE="Sys.Audit SDN.Use"
|
||||
PVE_PRIVS_STORE="Datastore.Allocate Datastore.AllocateSpace"
|
||||
PVE_PRIVS_BASE="Sys.Audit SDN.Use Datastore.Audit"
|
||||
# Storages the agent reads/writes (archive+dump=local, restore=local-lvm, offsite DR=felhom-pbs). The
|
||||
# offsite felhom-pbs MUST be included or the agent's DR backup 403s (SPIKE residual #1). --acl-storages overrides.
|
||||
PVE_STORAGES=(local local-lvm felhom-pbs)
|
||||
@@ -406,17 +409,20 @@ _grant() {
|
||||
}
|
||||
|
||||
# apply_scoped_acl — create the 3 scoped roles and grant each at its path(s). Requires the pool to exist.
|
||||
# ORDER (3b-fix): Base (which holds box-wide Datastore.Audit) is ensured + granted BEFORE Store, so a
|
||||
# RE-APPLY on a live box adds Audit@/ before Store drops its per-storage Audit → the agent never loses
|
||||
# storage-enumeration visibility mid-apply (gap-free).
|
||||
apply_scoped_acl() {
|
||||
_ensure_role "$PVE_ROLE_BASE" "$PVE_PRIVS_BASE"
|
||||
_ensure_role "$PVE_ROLE_GUEST" "$PVE_PRIVS_GUEST"
|
||||
_ensure_role "$PVE_ROLE_STORE" "$PVE_PRIVS_STORE"
|
||||
_ensure_role "$PVE_ROLE_BASE" "$PVE_PRIVS_BASE"
|
||||
_grant / "$PVE_ROLE_BASE"
|
||||
_grant "/pool/$PVE_POOL" "$PVE_ROLE_GUEST"
|
||||
local s
|
||||
for s in "${PVE_STORAGES[@]}"; do
|
||||
_grant "/storage/$s" "$PVE_ROLE_STORE"
|
||||
done
|
||||
_grant / "$PVE_ROLE_BASE"
|
||||
log_success " scoped ACL applied (Guest@/pool/$PVE_POOL, Store@[${PVE_STORAGES[*]}], Base@/)"
|
||||
log_success " scoped ACL applied (Base@/, Guest@/pool/$PVE_POOL, Store@[${PVE_STORAGES[*]}])"
|
||||
}
|
||||
|
||||
# _acl_grant_present PATH TYPE UGID ROLE — true if that exact ACL grant exists.
|
||||
|
||||
Reference in New Issue
Block a user