Adopt Alpine as the sanctioned base; release candidate scans clean
Operator adopted Alpine/musl as the base and trivy as the scanner. Containerfile.alpine is promoted to Containerfile and the Debian slim variant is retired rather than kept as an option -- it shipped three perl-base CRITICALs with no upstream fix, in a package this service never invokes. Promoting Alpine left 7 HIGH and 1 MEDIUM, all libuuid 2.42.1-r0 as shipped by the pinned Alpine 3.24.1, and all with fixes in 2.42.3. The runtime stage now requires libuuid>=2.42.3-r1. That is a version floor, not a floating upgrade: the base stays digest-pinned and reproducible, and a vulnerable libuuid fails the build instead of shipping. The candidate scans 0 CRITICAL / 0 HIGH / 0 MEDIUM / 0 LOW. Verified on that exact artifact: non-root uid 10001, pip absent, schema v3, tenant default tenant:platform, fresh-store migrate and verify clean, restart persistence via re-verify on the same volume, both production fail-closed refusals, 111 tests on musl, kubectl dry-run passing. The gate is now reproducible instead of a one-off. make image-scan fails on any CRITICAL or HIGH, and make image-release runs build then scan then push, so a failing scan blocks the push by construction rather than by whoever remembers to look. Not released. docker push was attempted and refused by this session's sandbox as an outward-facing publish, and was not worked around. No release digest exists, so the manifest deliberately keeps REPLACE_WITH_RELEASE_DIGEST -- it must be pinned to the registry manifest digest, never the tag and never the local image id. T03 stays wait on that push plus the still-unmaterialized KeyCape registrations and audit sender credential. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PM5HnEAhokxdfcPqBNpT7D Assistant: claude-code Assistant-Model: opus Assistant-Process: 715850@bnt-lap001 Assistant-Session: eb557e93-7cb1-45d0-9e57-7d15b3edc60e
This commit is contained in:
parent
f88a92fb37
commit
d7a9fe53db
5 changed files with 154 additions and 75 deletions
|
|
@ -1,5 +1,17 @@
|
|||
# Build stage: pip exists here and is never copied into the runtime image.
|
||||
FROM python:3.12-slim@sha256:78387bc3881b8273120a12ebe6c1ab22b018ccc2c9adf565ae1ac9b536e184ea AS build
|
||||
# Sanctioned base — musl/Alpine, adopted 2026-09-06.
|
||||
#
|
||||
# Alpine carries no perl, which is where the Debian slim variant's three
|
||||
# unfixable CRITICALs lived (CVE-2026-13221, CVE-2026-42496, CVE-2026-8376 in
|
||||
# perl-base, no upstream fix). Debian slim scanned 3 CRITICAL / 51 HIGH / 56
|
||||
# MEDIUM against this image's 0 / 7 / 1.
|
||||
#
|
||||
# pip is deliberately absent from the runtime stage: it is a build-time tool,
|
||||
# it held every Python-layer finding, and a running approval service has no
|
||||
# business installing packages. Do not add it back.
|
||||
#
|
||||
# Base is pinned by digest, never a tag. See docs/image-scan-2026-09-06.md.
|
||||
|
||||
FROM python:3.12-alpine@sha256:b64631e04e4920160c50fbe8d8df828f7f35f06f425cb44aa09bca53e708a35a AS build
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
|
|
@ -11,34 +23,32 @@ WORKDIR /app
|
|||
COPY pyproject.toml README.md ./
|
||||
COPY approval_engine ./approval_engine
|
||||
RUN pip install --no-cache-dir '.[serve]' \
|
||||
&& pip uninstall -y pip setuptools wheel 2>/dev/null || true \
|
||||
&& rm -rf /opt/venv/bin/pip /opt/venv/bin/pip3 /opt/venv/bin/pip3.12 \
|
||||
/opt/venv/lib/python3.12/site-packages/pip \
|
||||
/opt/venv/lib/python3.12/site-packages/pip-*.dist-info \
|
||||
/opt/venv/lib/python3.12/site-packages/setuptools \
|
||||
/opt/venv/lib/python3.12/site-packages/setuptools-*.dist-info \
|
||||
/opt/venv/lib/python3.12/site-packages/pkg_resources \
|
||||
/opt/venv/lib/python3.12/site-packages/wheel \
|
||||
/opt/venv/lib/python3.12/site-packages/wheel-*.dist-info
|
||||
/opt/venv/lib/python3.12/site-packages/pkg_resources
|
||||
|
||||
# Runtime stage.
|
||||
FROM python:3.12-slim@sha256:78387bc3881b8273120a12ebe6c1ab22b018ccc2c9adf565ae1ac9b536e184ea
|
||||
FROM python:3.12-alpine@sha256:b64631e04e4920160c50fbe8d8df828f7f35f06f425cb44aa09bca53e708a35a
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PATH=/opt/venv/bin:$PATH
|
||||
|
||||
RUN addgroup --system --gid 10001 approval \
|
||||
&& adduser --system --uid 10001 --ingroup approval --no-create-home approval \
|
||||
&& python -m pip uninstall -y pip setuptools wheel 2>/dev/null || true \
|
||||
# libuuid is patched explicitly rather than left to the base's pinned version:
|
||||
# the pinned Alpine 3.24.1 ships 2.42.1-r0, which carries every remaining HIGH
|
||||
# finding, all fixed in 2.42.3. The floor is a minimum version, not a floating
|
||||
# upgrade, so the build stays reproducible while refusing a vulnerable libuuid.
|
||||
RUN apk add --no-cache 'libuuid>=2.42.3-r1' \
|
||||
&& addgroup -S -g 10001 approval \
|
||||
&& adduser -S -u 10001 -G approval -H approval \
|
||||
&& rm -rf /usr/local/bin/pip /usr/local/bin/pip3 /usr/local/bin/pip3.12 \
|
||||
/usr/local/lib/python3.12/site-packages/pip \
|
||||
/usr/local/lib/python3.12/site-packages/pip-*.dist-info \
|
||||
/usr/local/lib/python3.12/site-packages/setuptools \
|
||||
/usr/local/lib/python3.12/site-packages/setuptools-*.dist-info \
|
||||
/usr/local/lib/python3.12/site-packages/pkg_resources \
|
||||
/usr/local/lib/python3.12/site-packages/wheel \
|
||||
/usr/local/lib/python3.12/site-packages/wheel-*.dist-info
|
||||
/usr/local/lib/python3.12/site-packages/pkg_resources
|
||||
|
||||
COPY --from=build /opt/venv /opt/venv
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue