feat(security): digest-pin every registry image on all three hosts (fleet law)
Closing the command-center security queue #70/#71/#72/#73/#74: rolling tags let a rebuild move under a running service with nobody approving it, and make a CVE audit ungradeable. 36 quadlet units across dankclaw, dankserver and frankbook-pro now carry tag@sha256; localhost/* builds stay exempt (their build is the pin). The pihole and copyparty pins pull the fixed builds; valkey 9.1.2 (already running) and redis 7.4.11 are pinned in place, vendor fixes TBD. New gate tests/quadlet_image_pins.bats: no unpinned registry image, no generator-rejected key anywhere. Three seams that pinned the old exact-tag law (frankbook readarr, open_webui, seerr) now require tag AND digest - strictly stronger. Quadlet Lifecycle docs: batch-abort law, entrypoint flags-only law, pin law.
This commit is contained in:
1 parent
7a8cc83385
commit
d2810ab610
41 files changed
+120
-45
No files matched your search
@@ -130,10 +130,19 @@ Quickest unblock: `podman compose up -d --force-recreate <svc>`. Durable fix
|
||||
|
||||
## 4. Podman 5.x quadlet v1 generator quirks (verified live 2026-08-28)
|
||||
|
||||
- **Hard-fail keys** — the whole unit silently fails to generate
|
||||
(`systemctl --user cat <unit>` shows "could not be found"): any
|
||||
dash-prefixed `[Container]` option (`--shm-size=…` → `unsupported key …
|
||||
in group 'Container'`); `Command=` is unsupported, use `Exec=`.
|
||||
- **Hard-fail keys abort the WHOLE BATCH, not one unit** (podman 5.7.0,
|
||||
live 2026-10-21): one unsupported key — e.g. `HostAddr=` — makes the
|
||||
generator log `unsupported key … in group 'Container'` plus
|
||||
`processing encountered some errors` and generate NOTHING for that
|
||||
manager. The running containers keep going as orphans, so the failure
|
||||
first appears on the next deploy as `Unit <x>.service not found` for a
|
||||
service that is visibly up. Other offenders: any dash-prefixed
|
||||
`[Container]` option (`--shm-size=…`), `Command=` (use `Exec=`).
|
||||
The seam `tests/quadlet_image_pins.bats` fails the build on any
|
||||
generator-rejected key in any host's units.
|
||||
Also: an image whose ENTRYPOINT is the binary takes FLAGS ONLY in
|
||||
`Exec=` — repeating the binary makes it a positional arg
|
||||
(`unexpected /bin/blackbox_exporter`, live 2026-10-21).
|
||||
- **HealthCmd space-splitting:** the v1 generator splits `HealthCmd` on
|
||||
spaces into the healthcheck argv; a quoted probe
|
||||
`/bin/sh -c "pg_isready …"` lands as argv token `"pg_isready` →
|
||||
@@ -148,6 +157,16 @@ Quickest unblock: `podman compose up -d --force-recreate <svc>`. Durable fix
|
||||
"unsupported key"`, `systemctl --user cat probe.service` (shows the
|
||||
generated ExecStart verbatim), then remove + reload.
|
||||
|
||||
## 4a. Image pins (fleet law, 2026-10-21)
|
||||
|
||||
Every registry image in a quadlet is digest-pinned (`tag@sha256:…`);
|
||||
locally built images (`localhost/*`, `franksdank/*`) are exempt — their
|
||||
build is the pin. A rolling tag lets a rebuild move under a running
|
||||
service with nobody approving it, and it makes a CVE audit ungradeable.
|
||||
Gate: `tests/quadlet_image_pins.bats`. Where upstream publishes no version
|
||||
tags (copyparty-ac stops at 1.19.15), pin `:latest@sha256:` and name the
|
||||
version the config label carries in the comment beside it.
|
||||
|
||||
## 5. Rootless Quadlet log retrieval
|
||||
|
||||
Step 0 — establish ownership: `systemctl --user status <name>.service`
|
||||
|
||||
Reference in new issue
Block a user