Skip to content

Reference compose pins Postgres by digest but Traefik by a mutable tag — and that tag is 8 months stale with 57 fixable HIGH/CRITICAL #369

Closed

Description

@mforce

Deploy-side context: mforce/cluckwork-deploy#20. Found while pinning and scanning deployed infrastructure images, and the evidence points back here.

The inconsistency

deploy/docker-compose.yml pins Postgres by immutable digest:

image: postgres:18.4-trixie@sha256:3a82e1f56c8f0f5616a11103ac3d47e632c3938698946a7ad26da0df1334744a

but pins Traefik by a mutable tag on an old release branch:

image: traefik:v3.5

Nothing scans it either — ci.yml's Trivy step has image-ref: cluckwork-api:ci, so the image build job covers the application image only.

Why this is worth fixing rather than a nit

traefik:v3.5 currently resolves to v3.5.6, built 2025-11-07. Scanned with Trivy 0.72.0 on 2026-08-02 it has 57 fixable and 2 unfixed HIGH/CRITICAL findings, including a CRITICAL Go stdlib CVE (CVE-2025-68121), plus fixable OpenSSL, zlib and golang.org/x/net findings.

v3.7.10 (2026-07-31) scans 0 fixable, 0 unfixed.

The propagation matters more than the CVE count: the deploy repo took its production Traefik version from this file. A mutable tag on a stale release branch here became a digest pin in a production manifest there, carrying every one of those findings. That has been corrected deploy-side, but the source is here.

Ask

  1. Pin Traefik by digest, matching how Postgres is already pinned in this same file, with the human-readable version in a trailing comment.
  2. Upgrade v3.5 → v3.7.10 (or current). Note v3.7 changes default handling of encoded characters in request paths and warns about split-view risk with backends that are not fully RFC 3986 compliant — worth a look given the SPA fallback and /api/* routing. Deploy-side has this recorded as verify, not exercised against the app.
  3. Include Traefik in the Trivy scan. Today the scan covers only the application image.
  4. Consider a scheduled scan. ci.yml runs on push and pull_request with no schedule:. Build-triggered scanning answers "were these bytes clean when built"; it cannot answer "are these bytes still clean", because a new advisory arrives with no commit to fire on. That is precisely how the eight-month-stale pin went unnoticed — nothing about the image changed. codeql.yml and security-audit.yml already establish the scheduled-workflow pattern in this repo.

Not asking for

Any change to the deploy repo's manifest, or ownership of the deployed digest — mforce/cluckwork-deploy/deploy/compose.yml has to carry a concrete digest because it is the file that runs in production, and it already pins v3.7.10 with a daily scan. This issue is about the reference stack that developers run and that deploy-side reads for version guidance.

Happy to keep the deploy-side scan as the backstop either way; the two are not in conflict.

Activity

  1. mforce commented on Aug 2, 2026

    @mforce
    OwnerAuthor

    Scoped down and implemented as #383 — items 1 and 2 only.

    Done (#383)

    1. Pinned by digest. traefik:v3.7.10@sha256:9c3b91d5…, matching how db is already pinned in the same file.

    2. Bumped v3.5 → v3.7.10, and the behaviour question you flagged as verify is now exercised rather than assumed:

    • sanitizePath has defaulted to true since v3.3.6 — unchanged from v3.5.6.
    • The http.encodedCharacters.* knobs arrived in v3.6.7 and all default to true (permissive).

    So v3.7.10's default path handling is identical to v3.5.6's. The router rule here is Host(…) only — no path matching, no path-rewriting middleware — so nothing routes on the path and there is no traefik/app split view to open. The split-view warning in the docs applies only when those knobs are set to false in front of a backend that decodes encoded reserved characters. That caveat is recorded in the compose file for whoever adds path-based routing later.

    Your scan numbers reproduced exactly: traefik:v3.5 → 57 fixable HIGH/CRITICAL, traefik:v3.7.10 → 0.

    Not done, deliberately

    3. Include Traefik in the Trivy scan and 4. Scheduled scan are not implemented. A first attempt (#379) built both — a compose-image enumerator with a digest-pin gate, a per-PR matrix scan, and a daily audit of the pins plus the published application image — and it was closed as disproportionate to the fix.

    Being explicit about what that leaves open, because the reasoning in item 4 of this issue is sound and still stands:

    • A digest never drifts, but it also never heals. Nothing in this repo proposes a bump for it — Dependabot's docker ecosystem reads Dockerfiles, not compose files, so deploy/ has no coverage at all. That is the actual mechanism by which v3.5 went eight months stale, and it is unchanged.
    • Nothing scans it. ci.yml's Trivy step is still image-ref: cluckwork-api:ci.
    • So this pin will go stale again the same way — just visibly, since the compose file now says so and carries the two commands to re-check it by hand.

    The deploy-side daily scan you mentioned is therefore the only automated backstop for these images. Worth keeping.

    Noted while scanning, not actioned

    The Postgres pin has 15 fixable HIGH/CRITICAL — all Go stdlib CVEs in /usr/local/bin/gosu, the helper the image uses once at start to drop privileges. The pinned digest is already the newest published 18-trixie (2026-07-19), so there is nothing to bump to; upstream has not rebuilt gosu.

    Also: while writing the fix, the v3.7.10 tag itself was re-pushed (2026-08-02 05:10 UTC) and the same version string began resolving to different bytes. Both builds scan clean and #383 pins the later one — an unusually direct demonstration of the point in item 1.

    Closing this issue would leave 3 and 4 unaddressed. Happy to leave it open for those, or split them into a follow-up — your call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions