Hi Ryan,
Following from Security Scanners , I have completed an audit across base container images used within the podplane, netsy.dev and nstance.dev projects. Most of these were OK, typically using scratch, gcr.io/distroless/static:nonroot or appropriate images except for a few cases.
Case 1: traefik/bootstrap-tls
One of the podplane helm components bootstrap-tls afaik is used to generate self-signed kubernetes.io/tls secrets for ingress domain at install/upgrade time before cert-manager is ready to issue real ones.
The component is based on dynamic Go source code, managed by Helm and uses the docker.io/library/golang:alpine image. I was thinking this could be made into a gcr.io/distroless/static:nonroot by pre-compiling the code with rules and shipping as a static binary for an image. Currently it uses the go run command whenever there is a change to Helm chart values.
This reduces a few risks:
kubectl update/patchon the ConfigMap provides direct code injection in the pod- Full Go toolchain gives an attacker more than static binary or image would
- Fewer Build-time security gates don’t apply to runtime-compiled code
- Helm release behaviour can drift without a chart version bump
It’d be good to have your input here as there are a few ways to approach this. In my mind, this would be significant enough to refactor to avoid some large vulnerabilities within a strongly held permission workload, that is writing the ConfigMap for tls-certitificate management.
Case 2: platform-certs/secret-sync
Currently, this service serves a very simple purpose which is solely to keep a secrets-store.csi.k8s.io volume mount alive so kubelet keeps syncing secrets into it.
The image is currently docker.io/library/golang:alpine which is 356 MB and is only used to call /bin/sh -c "trap : TERM INT; sleep infinity & wait" which waits for the pod to be killed (somewhat expensively).
There is an image registry.k8s.io/pause:3.10 which does exactly what the intention of the command is, and doesn’t over-expose it’s surface relative to it’s purpose. It’s ideal in the way where it is provided without a shell and ~300KB in size.
Finally
Side note, for gcr.io/distroless/static:nonroot images it’s recommended to state static-debian12: or static-debian13: instead of the static:* explicitly as this can impact applications dependent on the current filesystem structure with future changes across major Debian versions. Not really an issue for now.
For reference: Please add note into README.md about status of "non-debian" versions · Issue #2052 · GoogleContainerTools/distroless · GitHub .
Additionally, I can provide details on my analysis if you like. The most highly permissioned image used was debian:13-slim on vmconfig/test-install which is appropriate. Happy to take on the fixes for these cases too.