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.
47 lines
1.6 KiB
Bash
Executable File
47 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bats
|
|
# Seam: the Seerr quadlet on dankclaw. Pins boot persistence, self-healing,
|
|
# the pinned image tag, the guard chain's port posture (loopback-only
|
|
# publish — the guard chain is the only user path), the Containers data
|
|
# root, and zero env-carried secret material in the tracked unit.
|
|
|
|
load helpers
|
|
|
|
SEERR_UNIT="$REPO_ROOT/dankclaw/seerr/quadlet/seerr.container"
|
|
|
|
@test "seerr quadlet exists under dankclaw/seerr/quadlet/" {
|
|
[ -f "$SEERR_UNIT" ]
|
|
}
|
|
|
|
@test "seerr unit is boot-persistent (WantedBy=default.target)" {
|
|
grep -q '^WantedBy=default.target$' "$SEERR_UNIT"
|
|
}
|
|
|
|
@test "seerr unit is self-healing (Restart=always)" {
|
|
grep -q '^Restart=always$' "$SEERR_UNIT"
|
|
}
|
|
|
|
@test "seerr image is pinned to an exact version tag and digest" {
|
|
# 2026-10-21 fleet law: tag AND digest (tests/quadlet_image_pins.bats)
|
|
grep -Eq '^Image=ghcr\.io/seerr-team/seerr:v[0-9]+\.[0-9]+\.[0-9]+@sha256:[0-9a-f]{64}$' "$SEERR_UNIT"
|
|
}
|
|
|
|
@test "seerr publishes 5055 on loopback only (guard chain is the user path)" {
|
|
grep -q '^PublishPort=127.0.0.1:5055:5055$' "$SEERR_UNIT"
|
|
if grep -Eq '^PublishPort=' "$SEERR_UNIT"; then
|
|
grep -Eq '^PublishPort=127\.0\.0\.1:5055:5055$' "$SEERR_UNIT"
|
|
[ "$(grep -c '^PublishPort=' "$SEERR_UNIT")" -eq 1 ]
|
|
fi
|
|
}
|
|
|
|
@test "seerr data lives under the Containers data root" {
|
|
grep -q '^Volume=/home/dank/Containers/seerr/data:/app/config$' "$SEERR_UNIT"
|
|
}
|
|
|
|
@test "seerr joins the app network for the post-auth route" {
|
|
grep -q '^Network=dankclaw_default$' "$SEERR_UNIT"
|
|
}
|
|
|
|
@test "seerr unit carries no env or env-file secret material" {
|
|
! grep -Eq '^(Environment|EnvironmentFile)=' "$SEERR_UNIT"
|
|
}
|