fix(release): strip pip and ensurepip from the bundled python toolchain - #371
Merged
Conversation
The release tarballs bundle the rules_python hermetic toolchain for the parser, which ships pip 24.3.1 and an ensurepip-embedded copy of the same pip. Neither is used at runtime — the parser only imports its own code, antlr4, and protobuf — but the stale pip is the ONLY CVE-scanner finding the tarball itself owns (CVE-2025-8869 et al., 4 Medium / 1 Low; everything else scanners report against fizzbee images comes from OS base layers). Strip pip, pip-*.dist-info, ensurepip, and bin/{pip,pip3*} from the packaged parser tree. Patterns are deliberately exact: the pip-INSTALLED dependency repos (++pip+pypi_312_antlr4_python3_runtime) merely contain "pip" in their names and must survive; bin/pip3* (rather than hardcoded pip3.12) keeps the strip working across future python minor bumps. The packaging invariants are now enforced by the script itself (fail the release rather than publish a violating tarball): 1. Negative: nothing the strip targets may remain — reuses the exact deletion predicates (a broad "*pip*" search would false-positive on the stdlib's pipes.py and the ++pip+pypi_* repo names). 2. Positive: the parser's runtime dependencies are still present, checked by importable package directory (*/antlr4, */google/protobuf) rather than bazel repo names, so the check survives repo renames and rules_python upgrades. This check already caught one wrong assumption during development: protobuf ships via the bazel protobuf+ module, not a pip site-packages. 3. End-to-end: the staged release runs a smoke spec (Counter.fizz) before archiving — native platform only, since cross-compiled artifacts cannot execute on the build host (linux_x86 on release CI; the linux tarballs additionally get exercised on both architectures by the docker publish workflow downstream). The PASSED grep is the real assertion — the binary exits 0 even when the model checker reports FAILED. Verified natively on macos_arm by replicating the modified per-platform block verbatim: strip + both invariants + smoke all pass; the smoke spec completes with PASSED through the staged fizz wrapper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jp-fizzbee
force-pushed
the
user/jp/fix-release-strip-pip
branch
from
August 24, 2026 17:57
664173f to
11ee281
Compare
jp-fizzbee
pushed a commit
that referenced
this pull request
Aug 24, 2026
Replaces the abandoned single-stage image (the full bazel/Ubuntu/JDK build environment with the source tree copied in — gigabytes of unpatched CVE surface, reported by users wanting to run fizzbee in CI). The image now installs the SAME artifact that brew/tarball users run: a fetch stage downloads the platform's official release tarball (FIZZBEE_VERSION build arg), extracts it, and sanity-checks the executables; the runtime stage is python:3.12-slim + that artifact. No bazel, no source build, no repackaging — one packaging pipeline, many distribution formats. The fetch stage runs on the build platform and the runtime stage has no RUN steps, so multi-arch builds need no QEMU. python:slim (not debian:slim) because the fizz wrapper needs bash and mbt-scaffold launches mbt_gen.zip with the system python; the parser uses the tarball's bundled hermetic interpreter. Workflow triggers: - release published (not tag push — the Release workflow is still uploading assets at tag time; `published` fires after assets exist) - monthly cron: re-downloads the latest release onto a freshly pulled base image so OS-layer CVE patches reach `latest` without a release - manual dispatch with optional version input Pre-push smoke tests on both architectures (amd64: Counter + two-phase-commit + mbt-scaffold; arm64: Counter under QEMU; the PASSED grep is the real assertion — the binary exits 0 even on FAILED), then a post-push manifest check for both platforms. Verified locally (arm64) against the real v0.5.3 release: image builds, two-phase-commit passes with baseline-identical output (331/281), mbt-scaffold works, and the #371 pip strip is confirmed end-to-end (no pip/ensurepip anywhere in the image). 704MB — the tarball ships the hermetic python with cp -L-materialized duplicate interpreters; deduplicating those in build_release.sh would shrink both the tarballs and this image, as a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jp-fizzbee
pushed a commit
that referenced
this pull request
Aug 24, 2026
Replaces the abandoned single-stage image (the full bazel/Ubuntu/JDK build environment with the source tree copied in — gigabytes of unpatched CVE surface, reported by users wanting to run fizzbee in CI). The image now installs the SAME artifact that brew/tarball users run: a fetch stage downloads the platform's official release tarball (FIZZBEE_VERSION build arg), extracts it, and sanity-checks the executables; the runtime stage is python:3.12-slim + that artifact. No bazel, no source build, no repackaging — one packaging pipeline, many distribution formats. The fetch stage runs on the build platform and the runtime stage has no RUN steps, so multi-arch builds need no QEMU. python:slim (not debian:slim) because the fizz wrapper needs bash and mbt-scaffold launches mbt_gen.zip with the system python; the parser uses the tarball's bundled hermetic interpreter. Workflow triggers: - release published (not tag push — the Release workflow is still uploading assets at tag time; `published` fires after assets exist) - monthly cron: re-downloads the latest release onto a freshly pulled base image so OS-layer CVE patches reach `latest` without a release - manual dispatch with optional version input Pre-push smoke tests on both architectures (amd64: Counter + two-phase-commit + mbt-scaffold; arm64: Counter under QEMU; the PASSED grep is the real assertion — the binary exits 0 even on FAILED), then a post-push manifest check for both platforms. Verified locally (arm64) against the real v0.5.3 release: image builds, two-phase-commit passes with baseline-identical output (331/281), mbt-scaffold works, and the #371 pip strip is confirmed end-to-end (no pip/ensurepip anywhere in the image). 704MB — the tarball ships the hermetic python with cp -L-materialized duplicate interpreters; deduplicating those in build_release.sh would shrink both the tarballs and this image, as a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jp-fizzbee
pushed a commit
that referenced
this pull request
Aug 24, 2026
Replaces the abandoned single-stage image (the full bazel/Ubuntu/JDK build environment with the source tree copied in — gigabytes of unpatched CVE surface, reported by users wanting to run fizzbee in CI). The image now installs the SAME artifact that brew/tarball users run: a fetch stage downloads the platform's official release tarball (FIZZBEE_VERSION build arg), extracts it, and sanity-checks the executables; the runtime stage is python:3.12-slim + that artifact. No bazel, no source build, no repackaging — one packaging pipeline, many distribution formats. The fetch stage runs on the build platform and the runtime stage has no RUN steps, so multi-arch builds need no QEMU. python:slim (not debian:slim) because the fizz wrapper needs bash and mbt-scaffold launches mbt_gen.zip with the system python; the parser uses the tarball's bundled hermetic interpreter. Workflow triggers: - release published (not tag push — the Release workflow is still uploading assets at tag time; `published` fires after assets exist) - monthly cron: re-downloads the latest release onto a freshly pulled base image so OS-layer CVE patches reach `latest` without a release - manual dispatch with optional version input Pre-push smoke tests on both architectures (amd64: Counter + two-phase-commit + mbt-scaffold; arm64: Counter under QEMU; the PASSED grep is the real assertion — the binary exits 0 even on FAILED), then a post-push manifest check for both platforms. Verified locally (arm64) against the real v0.5.3 release: image builds, two-phase-commit passes with baseline-identical output (331/281), mbt-scaffold works, and the #371 pip strip is confirmed end-to-end (no pip/ensurepip anywhere in the image). 704MB — the tarball ships the hermetic python with cp -L-materialized duplicate interpreters; deduplicating those in build_release.sh would shrink both the tarballs and this image, as a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jp-fizzbee
added a commit
that referenced
this pull request
Aug 24, 2026
Replaces the abandoned single-stage image (the full bazel/Ubuntu/JDK build environment with the source tree copied in — gigabytes of unpatched CVE surface, reported by users wanting to run fizzbee in CI). The image now installs the SAME artifact that brew/tarball users run: a fetch stage downloads the platform's official release tarball (FIZZBEE_VERSION build arg), extracts it, and sanity-checks the executables; the runtime stage is python:3.12-slim + that artifact. No bazel, no source build, no repackaging — one packaging pipeline, many distribution formats. The fetch stage runs on the build platform and the runtime stage has no RUN steps, so multi-arch builds need no QEMU. python:slim (not debian:slim) because the fizz wrapper needs bash and mbt-scaffold launches mbt_gen.zip with the system python; the parser uses the tarball's bundled hermetic interpreter. Workflow triggers: - release published (not tag push — the Release workflow is still uploading assets at tag time; `published` fires after assets exist) - monthly cron: re-downloads the latest release onto a freshly pulled base image so OS-layer CVE patches reach `latest` without a release - manual dispatch with optional version input Pre-push smoke tests on both architectures (amd64: Counter + two-phase-commit + mbt-scaffold; arm64: Counter under QEMU; the PASSED grep is the real assertion — the binary exits 0 even on FAILED), then a post-push manifest check for both platforms. Verified locally (arm64) against the real v0.5.3 release: image builds, two-phase-commit passes with baseline-identical output (331/281), mbt-scaffold works, and the #371 pip strip is confirmed end-to-end (no pip/ensurepip anywhere in the image). 704MB — the tarball ships the hermetic python with cp -L-materialized duplicate interpreters; deduplicating those in build_release.sh would shrink both the tarballs and this image, as a follow-up. Co-authored-by: jayaprabhakar <jayaprabhakar@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Step 1 of the CVE-cleanup plan (independent of any Docker change).
The release tarballs bundle the rules_python hermetic toolchain for the parser, which ships pip 24.3.1 + an ensurepip-embedded copy. Neither is used at runtime, but the stale pip is the only CVE-scanner finding the tarball itself owns (CVE-2025-8869 et al., 4 Medium / 1 Low). Everything else scanners report against fizzbee images comes from OS base layers.
10 lines in
release/build_release.sh: strippip,pip-*.dist-info,ensurepip,bin/pip*from the packaged parser tree. Exact-name patterns so the pip-installed dependency repos (++pip+pypi_312_antlr4_python3_runtime, protobuf) are untouched.Verification
Replicated the packaging steps for linux_arm with the exact strip commands, ran the result in a container: two-phase-commit passes with baseline-identical output (331/281);
docker scoutno longer reports the bundled pip.Context
Full plan: (1) this PR → (2) go_sdk patch bump → (3) tag v0.5.3 with clean tarballs → (4) Docker image as thin wrapper installing the v0.5.3 release (rework of #370). rules_python upgrade explicitly deferred — not needed for any scanner-visible CVE, and 1.9.x is currently release-breaking for cross-compiled platforms.
🤖 Generated with Claude Code