Skip to content

Add refresh button to docker.yml so trivy scan failures are recoverable without pinning#104

Draft
ashiramin wants to merge 1 commit into
mainfrom
aa/fix-vulns-20260518-221951
Draft

Add refresh button to docker.yml so trivy scan failures are recoverable without pinning#104
ashiramin wants to merge 1 commit into
mainfrom
aa/fix-vulns-20260518-221951

Conversation

@ashiramin
Copy link
Copy Markdown
Contributor

Why

Today's Trivy scan on `:main` failed with 11 distinct Debian packages flagged (27 SARIF findings) — libcap2, libsystemd0, libudev1, openssh-client, jq/libjq1, python3.13-*, libpython3.13-*. The Dockerfile already runs apt-get update && apt-get upgrade -y; the patched versions exist in Debian's archive. They aren't getting picked up because buildx caches the entire apt RUN layer indefinitely — same Dockerfile text → same layer hash → cached layer reused → archive never re-fetched.

This is the same root cause that #99 (libngtcp2) and #102 (libnghttp2) papered over with explicit version pins. PR #99's body called it out:

Out-of-scope alternatives we can revisit if this pattern recurs:

  • Removing the persistent buildx cache (matches sibling convention: brain-backend and brain-app don't cache buildx layers).
  • A weekly APT_CACHE_BUST build-arg that forces the apt layer to rebuild on a schedule while preserving other cache benefits.

Pattern has recurred (3 PRs in 4 weeks, ~11 packages flagged today). Time to fix the cache mechanism instead.

What

Adds a refresh boolean input to docker.yml's workflow_dispatch trigger. When dispatched with refresh=true:

  1. cache-from is skipped → fresh build, fresh apt-get update && upgrade → patched packages pulled from archive
  2. cache-to still writes → subsequent builds (including tags cut afterwards) read the now-fresh cache
  3. On success and on refs/heads/main only, the job pushes an empty commit chore: refresh apt cache for trivy scan as an audit marker

Default behavior unchanged. Push to main, PRs, and tag builds keep using the cache exactly as before. The scan-failure signal is preserved — silence means everything's actually fresh.

How to use

When the scheduled Trivy scan fails:

  1. Actions → Build and Publish Docker ImageRun workflow
  2. Check refreshRun workflow
  3. Wait for it to finish. New :main image is fresh; an empty commit lands on main.
  4. Cut release tag vX.Y.Z from that empty commit — tag build uses the now-fresh cache, customer image is patched.

The empty commit re-triggers docker.yml on push to main, which is harmless: the cache it inherits is fresh.

What stays

Existing hard pins (libngtcp2-*, libnghttp2-14) remain as deterministic floors. Adding more pins becomes a last resort instead of a routine.

Test plan

  • PR's docker.yml build succeeds with default cache behavior
  • PR's trivy-pr scan still passes (no behavioral change on PR builds)
  • After merge, dispatch with refresh=true on main; confirm:
    • Build runs without cache hit on the apt layer
    • Empty commit lands on main
    • Next scheduled Trivy scan on :main passes
    • Tag cut from the empty commit produces a patched image

Notes / caveats

  • The empty-commit push needs contents: write on the build job (added).
  • If main has branch protection requiring PR review, the bot push could be blocked. If so, we may need a PAT or app token. Will verify on first manual dispatch.
  • Doesn't change today's failing scan on :main. To clear it: merge this, then run the dispatch flow once.

🤖 Generated with Claude Code

The :main Trivy scan keeps failing because buildx caches the apt-update layer
indefinitely, so `apt-get upgrade -y` doesn't actually re-fetch Debian's
archive. Recent CVE fix PRs (#99, #102) treated this as the symptom rather
than the cause; PR #99's body explicitly flagged the cache mechanism as
deferred work.

Adds a `refresh` boolean input to docker.yml's workflow_dispatch. When set,
cache-from is skipped (fresh build, fresh apt), and on success the job pushes
an empty commit to main as an audit marker — tag a release from that commit
to ship the patched image to customers.

Existing libngtcp2 / libnghttp2 hard pins stay as deterministic floors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant