Skip to content

chore(ci): add Grype ignore rules for unreachable base-image findings#539

Merged
rdimitrov merged 1 commit intomainfrom
chore/grype-base-image-ignores
Apr 21, 2026
Merged

chore(ci): add Grype ignore rules for unreachable base-image findings#539
rdimitrov merged 1 commit intomainfrom
chore/grype-base-image-ignores

Conversation

@rdimitrov
Copy link
Copy Markdown
Member

Summary

Adds a .grype.yaml at repo root that suppresses Grype findings the PR author has no lever to fix: base-image OS packages, the bundled npm CLI (build-time only), and the base-image Python/Node runtimes. Runtime deps of specific MCP servers (/app/node_modules/… and /opt/uv-tools/…) are intentionally left visible.

Every currently open PR is failing build-containers / Run Grype vulnerability scanner because Grype's DB updated 2026-04-21 with new high/critical fixes for packages that ship inside our base images. The scanner is configured with severity-cutoff: high, only-fixed: true, fail-build: true, so any newly-fixed high/critical in the base image turns every PR red. This change unblocks PRs whose only failure is in the base image, while keeping real server-dep issues blocking as before.

What each rule covers and why

Rule Rationale
package.type: deb Debian OS packages in the base image (python:3.x). Dockyard Dockerfiles never apt-get install anything of their own. Fix path: base-image rebuild tracked by upstream Debian.
package.type: apk Alpine OS packages in the base image (node:22-alpine / node:24-alpine). Dockyard Dockerfiles never apk add. Fix path: base-image rebuild tracked by upstream Alpine.
package.location: /usr/local/lib/node_modules/npm/** The system-bundled npm CLI runs only at image build time (to npm install the MCP server). It is not invoked by the running server, so CVEs in its internal deps — picomatch via tinyglobby, minimatch, glob, tar, cacache, node-gyp — are not reachable from the server's runtime attack surface.
package.location: /usr/local/bin/python* CVEs in the CPython binary from the base image. Fixed by a base-image rebuild.
package.location: /usr/local/bin/node CVEs in the Node.js runtime binary from the base image. Fixed by a base-image rebuild.

Full per-rule comments live inline in the file.

What this PR does NOT ignore

These stay blocking and need the upstream MCP server package (or the upstream Go module) to bump vulnerable deps:

  • /app/node_modules/… findings: next, protobufjs, axios, lodash, basic-ftp, undici, path-to-regexp, @modelcontextprotocol/sdk, fast-xml-parser, oauth2-server, convict, application-level picomatch, ...
  • /opt/uv-tools/<server>/… findings: fastmcp, mcp (Python SDK), aiohttp, pyjwt, pillow, lupa, langchain-core, ...
  • /app/mcp-server Go stdlib CVEs (the netbird MCP binary) — these reroll when toolhive bumps the Go toolchain.

Expected impact on open PRs

Should unblock:

Will still fail until upstream fixes:

  • all npx PRs whose server has vulnerable deps under /app/node_modules/…
  • all uvx PRs whose server has vulnerable deps under /opt/uv-tools/…

Validation

Built three images locally with dockhand, scanned with anchore/grype and the new -c .grype.yaml:

  • local-scan:octocode-test — 3 findings before (picomatch GHSA-c2c7-rcm5-vvqj high + 2 mediums), 0 after.
  • local-scan:aws-doc-test — python stdlib + debian libs before, 0 after.
  • local-scan:chroma-test — still fails on 3 high mcp 1.6.0 GHSAs in /opt/uv-tools/chroma-mcp/, as intended (real runtime-dep risk, not a base-image one).

Test plan

  • Build MCP Server Containers CI on this PR passes (no spec changes, so only a lint-level validation that the config doesn't break the workflow).
  • After merge, rebase one each of: (a) renovate/octocode-mcp-14.x — expected to go green; (b) renovate/mcp-clickhouse-0.x — expected to still fail on fastmcp, confirming scope is narrow.

🤖 Generated with Claude Code

Grype currently blocks every PR on high/critical CVEs in base-image
layers that PR authors cannot fix (OS packages, the bundled `npm` CLI
used only at build time, the base-image Python/Node runtimes). This
adds a `.grype.yaml` that narrowly suppresses those findings while
leaving real runtime-dependency issues in `/app/node_modules` and
`/opt/uv-tools` visible.

Philosophy and per-rule rationale are inline in the file. Most entries
are expected to roll off as upstream Node, Python, Debian and Alpine
images pick up fixes via future toolhive bumps.

Validated locally by building and scanning octocode-mcp (picomatch
base-image finding → clean), aws-documentation (python stdlib +
debian libs → clean), and chroma-mcp (unrelated `mcp` package GHSAs
still flagged, as intended).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdimitrov rdimitrov merged commit 897a3e3 into main Apr 21, 2026
2 checks passed
@rdimitrov rdimitrov deleted the chore/grype-base-image-ignores branch April 21, 2026 15:25
@rdimitrov rdimitrov mentioned this pull request Apr 21, 2026
5 tasks
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.

2 participants