Skip to content

Commit 603fbf6

Browse files
committed
feat: refine Dockerfile for improved Trivy integration and artifact handling
1 parent 23a93a4 commit 603fbf6

File tree

1 file changed

+31
-38
lines changed

1 file changed

+31
-38
lines changed

python-versions/Dockerfile

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@ ARG PYTHON_VERSION
1616
ARG ACTIONS_PYTHON_VERSIONS
1717
ARG TRIVY_VERSION
1818

19-
# Many base images (including our `powershell` image) switch to a non-root
20-
# runtime user for security. The builder stage must perform system package
21-
# installs and compile steps which require root. Explicitly switch back to
22-
# `root` here so all following RUN steps have the privileges they need.
19+
# Switch to root for installation privileges
2320
USER root
2421

25-
# Use bash with pipefail so any command in a pipeline failing will cause the
26-
# whole RUN step to fail (safer for build-time checks and early failure).
22+
# Use bash with pipefail for safety
2723
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
2824

2925
# Build environment and compiler hardening flags
@@ -44,7 +40,7 @@ ENV pythonLocation=${PYTHON_INSTALL_DIR} \
4440
RUNNER_TEMP=/tmp \
4541
RUNNER_TOOL_CACHE=/opt
4642

47-
# Combined Install Step (Essential + Core + Optional) to reduce layers.
43+
# Combined Install Step (Essential + Core + Optional)
4844
RUN apt-get -qq update -y && \
4945
apt-get -qq -y install --no-install-recommends \
5046
tzdata curl wget gcc g++ make git ca-certificates \
@@ -57,18 +53,18 @@ RUN apt-get -qq update -y && \
5753
python3 pkg-config sudo libmpdec-dev libbluetooth-dev libz-dev || true) && \
5854
apt-get clean && rm -rf /var/lib/apt/lists/*
5955

60-
# Install Trivy (used for local security gates)
56+
# Install Trivy
6157
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${TRIVY_VERSION}
6258

63-
# Clone Python
59+
# Clone Python Build Scripts
6460
RUN if [ ! -d /python-versions ]; then git clone https://github.com/actions/python-versions.git /python-versions; fi
6561
WORKDIR /python-versions
6662
RUN git checkout "${ACTIONS_PYTHON_VERSIONS}" && git submodule init && git submodule update
6763

68-
# [CEVS STEP 1] Scan Source Code BEFORE Build
64+
# [CEVS STEP 1] Scan Source Code
6965
RUN trivy fs --scanners secret,misconfig --exit-code 1 ./
7066

71-
# Build Python & Restore Artifact (FIXED LOGIC)
67+
# Build Python & Restore Artifact
7268
# The `build-python.ps1` script creates a compiled tarball in `/tmp/artifact` and
7369
# cleans up the `/opt` directory to save space. We immediately extract that
7470
# artifact back into place so `python-tests.ps1` can find the binaries.
@@ -97,31 +93,27 @@ RUN export MAKEFLAGS="-j $(nproc)" && \
9793
${PYTHON_INSTALL_DIR}/bin/python3 -c "import ssl; print('Python installed and SSL verified')"
9894

9995
# [CEVS STEP 2] Scan the Compiled Artifact (The Gatekeeper)
100-
# Generate SBOM (Only happens if CEVS passed) and place it in /tmp/artifact
96+
# Generate SBOM & Reports
10197
RUN mkdir -p /tmp/artifact && \
10298
trivy fs --format cyclonedx --output /tmp/artifact/python-${PYTHON_VERSION}-${TARGETARCH}.sbom.json ${PYTHON_INSTALL_DIR} || true
10399

104-
# Also write Trivy JSON reports (vuln and secret/misconfig) into /tmp/artifact
100+
# Write Trivy JSON reports
105101
RUN trivy --download-db-only || true; \
106102
trivy fs --format json --output /tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-vuln.json --scanners vuln ${PYTHON_INSTALL_DIR} || true && \
107103
trivy fs --format json --output /tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-secret.json --scanners secret,misconfig ${PYTHON_INSTALL_DIR} || true
108104

109-
# Create a small gate script to parse Trivy JSON and decide whether to fail
110-
# the build. This provides a single place to tune thresholds or ignore rules.
105+
# Create the Gate Script
111106
COPY <<EOF /usr/local/bin/trivy-gate.sh
112107
#!/bin/sh
113108
set -e
114-
# Inputs: vuln-json, secret-json
115109
VULN_JSON=\${1:-/tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-vuln.json}
116110
SECRET_JSON=\${2:-/tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-secret.json}
117-
# Controls: Set these env vars to tune build gating behavior
118111
FAIL_ON_CRITICAL=\${FAIL_ON_CRITICAL:-1}
119112
FAIL_ON_HIGH=\${FAIL_ON_HIGH:-0}
120113
FAIL_ON_MEDIUM=\${FAIL_ON_MEDIUM:-0}
121114
FAIL_ON_SECRET=\${FAIL_ON_SECRET:-1}
122-
echo "Trivy Gate: checking \$VULN_JSON and \$SECRET_JSON"
123115

124-
# Initialize counters
116+
echo "Trivy Gate: checking \$VULN_JSON and \$SECRET_JSON"
125117
critical=0; high=0; medium=0; secrets=0
126118

127119
if [ -f "\$VULN_JSON" ]; then
@@ -135,31 +127,29 @@ fi
135127

136128
echo "Counts => CRITICAL=\$critical HIGH=\$high MEDIUM=\$medium SECRETS=\$secrets"
137129

138-
if [ "\$FAIL_ON_CRITICAL" -eq 1 -a "\$critical" -gt 0 ]; then
139-
echo "ERROR: Trivy found CRITICAL vulnerabilities: \$critical"
140-
exit 1
141-
fi
142-
if [ "\$FAIL_ON_HIGH" -eq 1 -a "\$high" -gt 0 ]; then
143-
echo "ERROR: Trivy found HIGH vulnerabilities: \$high"
144-
exit 1
145-
fi
146-
if [ "\$FAIL_ON_SECRET" -eq 1 -a "\$secrets" -gt 0 ]; then
147-
echo "ERROR: Trivy found secrets/misconfigs: \$secrets"
130+
BLOCK=false
131+
if [ "\$FAIL_ON_CRITICAL" -eq 1 ] && [ "\$critical" -gt 0 ]; then BLOCK=true; fi
132+
if [ "\$FAIL_ON_HIGH" -eq 1 ] && [ "\$high" -gt 0 ]; then BLOCK=true; fi
133+
if [ "\$FAIL_ON_SECRET" -eq 1 ] && [ "\$secrets" -gt 0 ]; then BLOCK=true; fi
134+
135+
# Write result for Makefile extraction
136+
printf '{"critical":%d,"high":%d,"medium":%d,"secrets":%d,"block":%s}\n' "\$critical" "\$high" "\$medium" "\$secrets" "\$BLOCK" > /tmp/artifact/trivy-gate-result.json
137+
138+
if [ "\$BLOCK" = "true" ]; then
139+
echo "GATE FAILED."
148140
exit 1
141+
else
142+
echo "GATE PASSED."
143+
exit 0
149144
fi
150-
151-
echo "Trivy gate passed; no blocker findings."
152-
exit 0
153145
EOF
154146
RUN chmod +x /usr/local/bin/trivy-gate.sh
155147

156-
# Run the gate. Note: FAIL_ON_CRITICAL is set to 0 here to allow build to pass
157-
# during development/debugging, but the reports are generated above.
158-
RUN FAIL_ON_CRITICAL=0 FAIL_ON_HIGH=0 FAIL_ON_MEDIUM=0 FAIL_ON_SECRET=0 /usr/local/bin/trivy-gate.sh /tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-vuln.json /tmp/artifact/trivy-${PYTHON_VERSION}-${TARGETARCH}-secret.json || true
148+
# Run the gate (non-blocking for now so artifacts are exported)
149+
RUN FAIL_ON_CRITICAL=0 FAIL_ON_HIGH=0 FAIL_ON_MEDIUM=0 FAIL_ON_SECRET=0 /usr/local/bin/trivy-gate.sh || true
159150

160151
# Run Tests
161152
WORKDIR /python-versions/tests
162-
# Ensure the build output log exists (created during pwsh build) for tests to analyze
163153
RUN cp $RUNNER_TEMP/work/build_output.txt $RUNNER_TEMP/ || touch $RUNNER_TEMP/build_output.txt
164154
RUN pwsh -Command "Install-Module -Name Pester -Force -Scope CurrentUser -SkipPublisherCheck" && \
165155
AGENT_TOOLSDIRECTORY=/opt RUNNER_TOOL_CACHE=/opt pwsh python-tests.ps1 ${PYTHON_VERSION} linux ${TARGETARCH}
@@ -175,7 +165,7 @@ FROM ubuntu:${UBUNTU_VERSION} AS final
175165
ARG PYTHON_VERSION
176166
ARG TARGETARCH
177167

178-
# Set up a non-root user (Security Best Practice)
168+
# Set up a non-root user
179169
RUN groupadd -g 10001 python_group && \
180170
useradd -u 10001 -g python_group -s /bin/bash -m python_user
181171

@@ -185,8 +175,11 @@ RUN apt-get update && \
185175
ca-certificates openssl libssl3 libffi8 libsqlite3-0 liblzma5 libbz2-1.0 zlib1g && \
186176
rm -rf /var/lib/apt/lists/*
187177

188-
# Copy Artifacts
178+
# Copy Installed Python
189179
COPY --from=builder /opt/Python/${PYTHON_VERSION}/${TARGETARCH} /opt/Python/${PYTHON_VERSION}/${TARGETARCH}
180+
181+
# [IMPORTANT] Copy Build Artifacts & Reports so Makefile can extract them
182+
COPY --from=builder /tmp/artifact /tmp/artifact
190183
COPY --from=builder /tmp/artifact/python-${PYTHON_VERSION}-${TARGETARCH}.sbom.json /opt/python-sbom.json
191184

192185
# Clean Source

0 commit comments

Comments
 (0)