Supply chain: digest-pin the base, keep apt unpinned, scan for CVEs (#395) - #446
Supply chain: digest-pin the base, keep apt unpinned, scan for CVEs (#395)#446Ultimate-Storm wants to merge 1 commit into
Conversation
…395) main has had ZERO of its 87 apt packages pinned since 2026-07-03: PR #387 merged the cron's temporary "WIP: remove apt versions for rebuild" strip commit, while the PR carrying the correct re-add (#385) was closed. The Dockerfile comment has been claiming "version-pinned for security" ever since. It was not true. Rather than restore the pins, ratify the unpinned state -- because the pins were never doing what the comment claimed: - They gave no reproducibility. The base image was pinned by TAG, and a tag is mutable, so the multi-GB foundation could be re-pushed under us while we froze 87 leaf packages on top of it. - They gave no security; they blocked it. A pin freezes an OLD patch version. PR #435 demonstrated this against its own intent: restoring 9-day-old pins broke CI because five had vanished from the archive, and the fix was to bump them to exactly what unpinned apt already installs. All five were security updates. So: pin what is mutable but persistent (the base image, by digest -- the only pin here that makes a build reproducible), and let apt float to current patches. Sites never build, so build reproducibility was never the requirement; image-level reproducibility (a digest-addressed artifact + a retained SBOM) is, and the registry gives that for free. Security becomes a control that actually exists. There was no CVE scanner and no dependabot config anywhere in this repo, so the pins were the only claimed control and they pointed the wrong way. The daily cron is replaced by a job that BUILDS from current sources, proves it still trains, scans the built image (failing only on fixable HIGH/CRITICAL -- the actionable ones), and retains the SBOM we already generated and threw away. It fails loudly; its predecessor green-ticked for 11 days while silently skipping its own push and PR steps. The three load-bearing pip pins now say WHY (none of the 112 did): numpy 1.26.4 predates the NumPy 2.0 ABI break, and torchvision/torchaudio are the exact companions of the torch 2.2.2 that ships in the base image. Broader pip relaxation is deliberately deferred -- PyPI never deletes versions, so pip pins don't break builds, and the scanner should tell us which ones matter first. Verified the digest resolves and that a real docker build off this ARG/FROM succeeds. Dockerfile_STAMP is untouched to avoid conflicting with #421. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Can we shorten the list of apt packages to those we actually need (excluding their dependencies)? Currently, it's a mixed list of desired packages and (possibly outdated, possibly incomplete by now) dependencies the desired packages had at some point in the past. |
|
@oleschwen is right, and I'd go a step further — the list is worse than cosmetic once the pins are gone. Counting it: of the 87 names, about eight are actual intent — One subtlety before anyone just deletes them. The list isn't only documentation — naming a transitive package explicitly makes apt upgrade it to the newest available even when the installed version already satisfies dependencies. That was the CVE-remediation mechanism. Dropping the 79 without replacing it would quietly reduce patch coverage, so the PR would be weaker than it looks. But the mechanism is wrong in a way that bites this PR specifically. I checked: 48 of the 87 carry a version in the name — Suggestion that satisfies Ole and strengthens the PR's own thesis: RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
apt-transport-https ca-certificates curl gnupg lsb-release openssl unzip zip \
&& rm -rf /var/lib/apt/lists/*
This is also more consistent with the PR's argument: it already decided the CVE scan + SBOM is the control and apt should float. An 79-name pseudo-manifest is a leftover of the pinning philosophy this PR is retiring. Caveats, honestly:
Two notes on merging, since main moved under this PR:
|
|
Yes, that sounds good.
|
Closes #395. Supersedes #435 (which I'm closing).
The state of
mainis not what the Dockerfile says0 of 87 apt packages have been pinned since 2026-07-03. PR #387 merged the cron's temporary "WIP: remove apt versions for rebuild" strip commit; the PR carrying the correct re-add (#385) was closed.
Dockerfile_ODELIAhas been claiming "version-pinned for security" ever since.Why ratify that rather than restore the pins
3db2815) was to bump them to exactly what unpinnedaptalready installs. All five were security updates.What this does
@sha256:digest (the only pin here that makes a build reproducible)numpy==1.26.4predates the NumPy-2 ABI break;torchvision/torchaudioare the exact companions of the base image's torch 2.2.2Answers @oleschwen's "isn't digest-pinning the base while unpinning apt inconsistent?" — no, that's the crux: pin what is mutable but persistent (the base), float what is immutable but garbage-collected (apt). Sites never build, so build reproducibility was never the requirement; image-level reproducibility (digest + SBOM) is, and the registry gives it free.
CVE scan fails only on fixable HIGH/CRITICAL — unfixed CVEs in the CUDA base are reported, not blocking, so the gate stays actionable.
Verification: confirmed the digest resolves and that a real
docker buildoff this exactARG/FROMsucceeds. Unit suite: 232 passed.Dockerfile_STAMPuntouched to avoid conflicting with #421 (follow-up).