Skip to content

Install-time supply-chain hardening: hash-pinned installs + trivy unfixed-CVE policy review #391

Description

@cmeans-claude-dev

Summary

PR #390 correctly scopes pip-audit to runtime-effective deps (no more whole-venv scanning, no CVE-level allowlists). But scoping only addresses the runtime scanner's surface — it does not close the install-time supply-chain gap. Filing this so the work doesn't fall off the radar.

Context

pip 26.0.1 shipped with CVE-2026-3219 / GHSA-58qw-9mgm-455v on 2026-04-24 — pip treats concatenated tar/ZIP archives as ZIP regardless of filename. Exploit path: attacker supplies a hybrid archive (e.g., via a compromised PyPI mirror or a compromised publisher account) and a vulnerable pip on the install host picks the ZIP interpretation, installing different files than the tar manifest advertised.

The mcp-awareness server never invokes pip at runtime, so the runtime scanner (pip-audit) correctly does not gate on this CVE. The risk is purely install-time — it lives in every environment where an operator types pip install mcp-awareness-server or where a Docker image layer runs pip install during build.

Gaps to close

  1. Hash-pinned installs not offered — the project's pip install invocations (Docker image, install-demo.sh, docs) do not use --require-hashes with a lockfile. A hash-pinned install closes the "PyPI served me a different wheel than the advertised one" window by failing the install if the hash does not match the pinned value. Highest-leverage mitigation for the whole class of install-time supply-chain attacks, including CVE-2026-3219 and any future similar pip/setuptools issues.

  2. No signed-release / PyPI attestation verification — we do not sign our releases or verify signatures on deps we install. PEP 740 attestations are available; worth evaluating before the beta managed-service launch.

  3. Trivy's --ignore-unfixed silently passes unfixed CVEs in the Docker imagedocker-smoke.yml's trivy invocation ignores any CVE without an upstream fix. That is pragmatic (cannot fix what upstream has not fixed) but means the image ships with whatever pip/setuptools CVEs have not been patched yet, and the backlog is invisible. Should this instead log unfixed CVEs as a visible CI warning (not a failure) so we know the exposure window rather than silently masking it? Separate decision.

  4. Dependabot is the only thing tracking bootstrap-tool fixes — when pip 26.0.2 (or whatever version fixes CVE-2026-3219) ships, Dependabot will open a PR and we will merge it. That is correct for a known CVE with an upstream fix. No current gap, but documented here so the reviewer can confirm the chain works end-to-end.

Proposed scope (for triage, not this issue)

  • Phase 1 (lightweight): Audit trivy's --ignore-unfixed policy; decide between (a) fail CI, (b) warn-only non-gating, (c) document the current posture as an accepted trade-off. Size: 1-2 hours.
  • Phase 2 (medium): Generate a hash-pinned lockfile (e.g., via pip-compile --generate-hashes from pip-tools or uv's native lockfile), convert Dockerfile + install-demo.sh + docs to pip install --require-hashes. Size: 1-2 days including the docs sweep.
  • Phase 3 (larger): Sign releases + document operator-side verification steps. Size: 2-3 days, coordinates with beta-readiness.

Related

Filed to prevent this work being lost after #390 merges. Shares concerns with the broader beta launch-readiness trust posture.

Acceptance criteria (phase 1)

  • Decision recorded (in CHANGELOG or a design doc) on trivy --ignore-unfixed policy.
  • If phase 2/3 work is deferred, the deferral is explicit (pointer to a follow-up issue) rather than silent.

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