ci(grype): install pinned grype by checksum, drop scan-action - #294
Closed
stephrobert wants to merge 1 commit into
Closed
ci(grype): install pinned grype by checksum, drop scan-action#294stephrobert wants to merge 1 commit into
stephrobert wants to merge 1 commit into
Conversation
anchore/scan-action, even pinned by commit SHA, fetches and executes `install.sh` from anchore/grype@main at runtime (see action.js: `https://raw.githubusercontent.com/anchore/grype/main/install.sh`). `main` is a moving ref, so the pinned SHA gives a false sense of immutability: the code actually executed in CI can change with no change to anything committed here. Replace the action with a direct install of the pinned grype release, verified against a SHA-256 committed to this repo — the only trust anchor, immutable unless this file changes. Then run grype directly with the same gate (--fail-on high --only-fixed). Verified locally: download + checksum + extract + flags all succeed against grype 0.114.0.
stephrobert
requested review from
Joseph94m,
Totara-thib,
coconux3 and
thomasboni
as code owners
July 3, 2026 15:35
thomasboni
reviewed
Jul 3, 2026
thomasboni
left a comment
Contributor
There was a problem hiding this comment.
Verified the PR independently: the sha256 matches my own download of the official release asset and the official checksums.txt, the CI run proves the chain works end-to-end, and the severity gate is an exact match for the old action's behavior. One small parity gap with the replaced action below.
| fail-build: true | ||
| severity-cutoff: high | ||
| only-fixed: true | ||
| run: grype "plumber:ci" --fail-on high --only-fixed |
Contributor
There was a problem hiding this comment.
The replaced anchore/scan-action set GRYPE_CHECK_FOR_APP_UPDATE: false; without it grype makes a phone-home update check on every scan. Restoring it keeps parity and drops an unneeded network call:
Suggested change
| run: grype "plumber:ci" --fail-on high --only-fixed | |
| env: | |
| GRYPE_CHECK_FOR_APP_UPDATE: "false" | |
| run: grype "plumber:ci" --fail-on high --only-fixed |
thomasboni
approved these changes
Jul 3, 2026
thomasboni
added a commit
that referenced
this pull request
Jul 3, 2026
anchore/scan-action, though pinned by SHA, downloads and executes install.sh from anchore/grype@main at every run, a moving ref the pin does not cover. Install the pinned grype release directly instead and verify it against a sha256 committed in the workflow, then scan with the same severity gate as before (fail on fixable high+). Also disable grype's phone-home update check, which the removed action used to turn off. Redoes #294 by @stephrobert with the review suggestion applied, since the original branch could not be updated. Co-authored-by: Stéphane ROBERT <robert.stephane.28@gmail.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Merged in #298 |
plumber-release-bot Bot
pushed a commit
that referenced
this pull request
Jul 6, 2026
## [0.3.87](v0.3.86...v0.3.87) (2026-07-06) ### 🐛 Bug Fixes * **collect:** contain local CI-config reads and skip symlinked Dockerfiles ([ef9c275](ef9c275)) * **gitlab:** harden local include resolution ([729e259](729e259)) ### ♻️ Refactoring * **render:** sanitize repo-derived text and bound resource use ([17ed05e](17ed05e)) * **score:** resolve the score endpoint from CLI/env only ([0a89351](0a89351)) ### 👷 CI/CD * **grype:** install pinned grype by checksum, drop scan-action ([a275cdf](a275cdf)), closes [#294](#294) * pin runtime tool installs to immutable versions ([a203b7f](a203b7f)) * **release:** pin v0.3.86 refs [skip ci] ([101cd21](101cd21)) * **release:** stop persisting credentials in the pin-refs checkout ([8f0f261](8f0f261)), closes [#293](#293) * **scorecard:** document the action's mutable-image gap ([61c8cdd](61c8cdd))
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
grypecontainer-scan job pinsanchore/scan-actionby commit SHA, whichlooks immutable. It is not. At runtime the action fetches and executes an
install script from a moving ref:
anchore/grype@maincan change with no change to anything committed here, so theSHA pin gives a false sense of immutability: the code actually executed in CI is
not pinned. This is the supply-chain gap that pin-by-SHA does not close when an
action pulls remote code.
Fix
Install the pinned grype release directly and verify it against a SHA-256 that
lives in this workflow — the only trust anchor, immutable unless this file
changes — then run grype with the same gate:
To bump grype, update both
GRYPE_VERSIONandGRYPE_SHA256together (the hashis published in the release's
checksums.txt).Verification
Locally, against grype 0.114.0: download +
sha256sum -c+ extract +grype version+--fail-on high --only-fixedall succeed. Same severity gate asbefore (fail on fixable high+).
Note
The general case — a pinned third-party action that fetches/executes mutable
remote code — is not something Plumber detects today (pin-by-SHA passes it).
That detection is worth a dedicated control and will be tracked separately.