v0.19.0 — the backup-freshness fence
New — the backup-freshness fence
pve_backup_freshness (+1 tool → 365): a read-only check that walks the ACTUAL backup
archives per guest (every job-referenced storage, every node) and compares their age against
what the enabled backup jobs promise. A job or task reporting OK is never treated as evidence
a backup exists — only an archive on storage counts. Verdicts per guest:
fresh | stale | never | uncovered | unknown, with PVE's own not-backed-up read as a
cross-check on the coverage parse and every disagreement flagged. It never fails toward
"fresh": an unreadable storage yields unknown + complete: false, not a clean bill.
Born from the field: a real nightly job reported OK for a month while producing nothing —
this check would have caught it on day two.
- Token-sight guard, live-found on day one: PVE hides backup volumes from the content
listing per-volume (200 + empty, no error) unless the token holdsDatastore.AllocateSpace
on the storage ANDVM.Backupon the guest (orDatastore.Allocateon the storage) —
verified againstpve-storage'scheck_volume_access. A read-only PVEAuditor token walked
a healthy PBS storage and read every guest as "never backed up". The fence now proves the
token could have SEEN an archive before trusting its absence: blind absence verdicts degrade
tounknownwith a flag naming the exact grants to fix it. - Population honesty, live-found the same day: the guest list itself is permission-
filtered — PVE silently omits guests the token cannotVM.Audit, and a deeper-path ACL
grant REPLACES inherited privileges (a scoped/vmsgrant shrank a real fleet's visible
population from 25 to 6 with no error). The report now carriesguests_visibleand the
note tells operators to compare it against the fleet size they expect.
Full detail: CHANGELOG.md.
See SECURITY.md for what
each control honestly holds.