Repository navigation
Description
Summary
A Docker Scout scan of pybot:staging (built from PR #466, commit ee8800a) failed 3 of 7 policies. None of these come from PR #466, and none block it. Fix them in one follow-up PR, together with the general hardening items below.
docker scout quickview 633607774026.dkr.ecr.us-east-2.amazonaws.com/pybot:staging
! Image runs as the root user
! Copyleft licensed packages found 400 packages
✓ No fixable critical or high vulnerabilities 0C 0H 0M 0L
✓ No high-profile vulnerabilities
✓ No outdated base images
✓ No unapproved base images
! Required supply chain attestations missing 2 deviations
Policy findings
1. The image runs as root (fix)
docker/Dockerfile has no USER instruction, so python -m pybot runs as UID 0. The app listens on port 5000 and does not need root.
- In the
prodstage, create a system user with a fixed UID (for exampleuseradd --system --uid 10001 --no-create-home pybot) and addUSER pybotbeforeCMD. - Keep
/appowned by root and not writable by the app user (COPY --from=builderwithout--chown). Check that nothing writes to/appat runtime: logging config and__pycache__(the venv is compiled at build time with--compile). - Use a numeric
USER 10001:10001so platforms that checkrunAsNonRootcan verify it.
2. Build attestations are missing (fix)
build-push-action in the CI workflow sets provenance: false, and SBOM generation is not turned on. Scout reports that the image has no SLSA provenance and no SBOM attestation.
- Set
provenance: mode=maxandsbom: true. - Find out why
provenance: falsewas set first. It was often a workaround for ECS or ECR failing on the image index that attestations create. ECR supports OCI referrers and ECS handles image indexes now, but test a staging deploy before you merge.
3. Copyleft licensed packages (accept)
There are 400 packages, almost all from the Debian python:3.14.10-slim-trixie base image (GPL and LGPL system packages). This is expected for a Debian image, and pybot is not distributed as a binary. No action is needed unless we move to a distroless or Chainguard base (see below). Record the decision in the PR.
Known unfixed CVEs (track only)
Debian has not released fixes for these. A rebuild picks up patches when Debian publishes them (the Dockerfile already runs apt-get upgrade).
| Package | CVE | Severity |
|---|---|---|
| zlib 1.3.1-1+deb13u1 | CVE-2026-85091 | High |
| zlib 1.3.1-1+deb13u1 | CVE-2026-76844 | High |
| tar 1.35+dfsg-3.1 | CVE-2025-45582 | Medium |
General hardening (same PR)
- Pin the base image by digest:
FROM python:3.14.10-slim-trixie@sha256:.... Dependabot's docker ecosystem updates digests. - Remove
wgetfrom the runtime image. It is used only byHEALTHCHECK. Usepython -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health', timeout=4)"instead. Check whether the ECS task definition has its own health check that callswget. - Remove
tarand other unused tools from the runtime stage if possible, or evaluate a distroless or Chainguard Python base. That also removes most of the copyleft packages and base-image CVEs. - Signal handling: confirm that
python -m pybotas PID 1 shuts down cleanly onSIGTERMduring ECS deploys. If not, add--initor enableinitProcessEnabledin the task definition. - ECS task definition (infrastructure repo):
readonlyRootFilesystem: true(add a tmpfs mount if anything needs/tmp),user: "10001", andlinuxParameters.capabilities.drop: ["ALL"]. - Add a Scout gate to CI: run
docker/scout-actionwithcommand: cvesandonly-fixed: true, so that fixable critical and high CVEs fail the build.
Done when
docker scout quickviewshows the "root user" and "supply chain attestations" policies as met.- A staging deploy is healthy with the new image (the ECS health check passes and the bot answers Slack events).
- The copyleft decision is recorded in the PR.
Found during the review of #466.
🤖 Generated with Claude Code
Activity