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,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