Skip to content

Switch base image to distroless python3-debian13 to eliminate CVE surface#2

Merged
RoiGlinik merged 1 commit into
masterfrom
fix/distroless-base-image
Jun 4, 2026
Merged

Switch base image to distroless python3-debian13 to eliminate CVE surface#2
RoiGlinik merged 1 commit into
masterfrom
fix/distroless-base-image

Conversation

@RoiGlinik
Copy link
Copy Markdown
Contributor

@RoiGlinik RoiGlinik commented Jun 3, 2026

Summary

  • Replaces python:3.12-slim runtime base with gcr.io/distroless/python3-debian13 to eliminate the openssl + glibc CVE surface flagged by image scanners (DSA-6113-1: 11 openssl CVEs including a CVSS 8.1 stack buffer overflow in CMS AuthEnvelopedData parsing; pending glibc 2.41-12+deb13u2 fixes).
  • Builder stage bumped to python:3.13-slim to match the distroless Python 3.13 runtime; pydantic bumped to >=2.11.7 for Python 3.13 wheel availability.
  • Adds config/test-definitions.yaml as a runnable example RBAC config and a .gitignore covering *.env so local credential files don't get committed.

Why distroless

  • No shell, no apt, no openssl userland binary, no package manager → far smaller scanner-tracked package set.
  • Daily-rebuilt by Google with current Debian trixie security patches, so glibc/libssl fixes flow in automatically.
  • Pushed/compressed image is ~52 MB (uncompressed local: 263 MB; the previous image was a similar size — the bulk is the venv: zstandard 22 MB, cryptography 15 MB, pygments/pyiceberg 13 MB transitive from supabase).

Notable behavior changes

  • CMD is now ["-u", "/app/builder/main.py"] — the distroless ENTRYPOINT is python3, so this composes to python3 -u /app/builder/main.py.
  • PYTHONPATH=/app:/venv/lib/python3.13/site-packages because the runtime image has no pip and no venv/bin/python activator pointing at a valid interpreter.
  • No kubectl exec ... sh into the running pod — distroless has no shell. Use gcr.io/distroless/python3-debian13:debug as a temporary swap when debugging, or use ephemeral debug containers.

Test plan

End-to-end smoke test executed against https://test.remediate.dev/db:

docker build -t rbac-builder:distroless-test builder/
docker run --rm \
  --env-file config/test.env \
  -v $(pwd)/config/test-definitions.yaml:/config/definitions.yaml:ro \
  rbac-builder:distroless-test

Output:

2026-06-03 08:55:45.847 INFO     logger initialized using INFO log level
2026-06-03 08:55:45.847 INFO     Running rbac builder...
2026-06-03 08:55:45.957 INFO     Supabase dal login
2026-06-03 08:55:49.786 INFO     Done building rbac definitions
2026-06-03 08:55:50.055 INFO     Exiting
exit: 0
  • Image builds cleanly on python:3.13-slim builder stage
  • All deps (pydantic, supabase, httpx[http2], regex, PyYAML) import on Python 3.13 in the distroless runtime
  • logging.basicConfig() output is captured by container stdio (Kubernetes-compatible)
  • Outbound HTTPS to Supabase works (libssl shared lib still present in distroless; only the openssl CLI binary is removed)
  • Supabase auth via STORE_USER/STORE_PASSWORD succeeds
  • Real CRUD against PermissionScopes + PermissionGroups succeeds (delete-then-upsert flow)
  • Process exits 0
  • Pydantic config validators still fire correctly (caught a deliberately-bad scope/group type mapping in the first test run)
  • Verify in the test.remediate.dev DB that scopes/groups for account 6c2cbf41-c7b5-48ab-9777-76d320b985d4 match config/test-definitions.yaml
  • Run build_on_apple_m1.sh to confirm multi-arch (linux/arm64,linux/amd64) build still succeeds

Notes for reviewers

  • Python 3.12 → 3.13 is the cost of using Google's distroless (their tags are pinned to Debian release defaults; debian12 = 3.11, debian13 = 3.13, no 3.12 variant). All current deps support 3.13.
  • Consider pinning the distroless image by digest (gcr.io/distroless/python3-debian13@sha256:...) before merge for reproducibility — left on the floating tag for now to keep absorbing security rebuilds.

🤖 Generated with Claude Code

…face

Replaces the python:3.12-slim runtime base with gcr.io/distroless/python3-debian13.
The previous base shipped openssl/glibc userland binaries flagged by DSA-6113-1
(11 CVEs incl. CVSS 8.1 stack buffer overflow in CMS AuthEnvelopedData parsing)
and glibc 2.41-12 fixes pending in 2.41-12+deb13u2. Distroless ships only the
shared libs Python needs, no shell, no package manager.

Builder stage bumped to python:3.13-slim to match the runtime Python; pydantic
bumped to >=2.11.7 for Python 3.13 wheel availability. Final image's CMD relies
on the distroless ENTRYPOINT being python3.

Adds config/test-definitions.yaml as a runnable example and .gitignore covering
*.env for local credential files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@RoiGlinik RoiGlinik merged commit d1b2979 into master Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants