Appendix A-Container Hardening Reference¶
Cumulative hardening checklist. By week 24 the reader's container-baseline/ template should encode every section.
A.1 Image Hardening¶
- Use distroless or scratch base images.
- Pin base by digest, not tag.
- Multi-stage build; runtime image has no compiler, no shell (unless required).
- Run as non-root user (UID >0); set explicit
USER. - No secrets baked in the image; verify with
trivy image --scanners secret. - All packages installed have a justification.
- OCI annotations:
source,revision,created,licenses. - Reproducible: identical commit → identical digest.
- SBOM attached as attestation.
- Signed with cosign.
- CI gate: vulnerabilities triaged or VEX'd.
A.2 Runtime Hardening (per docker run / podman run / Kubernetes pod)¶
- - -read-only` rootfs.
-
tmpfsfor/tmp,/run. - - -cap-drop=ALL`, add only what's needed.
- - -security-opt=no-new-privileges`.
- Custom seccomp profile (not the default if you can do better).
- LSM profile (SELinux:
container_t; AppArmor:runtime/defaultor custom). - Resource limits: - -memory
, - -cpus, - -pids-limit`. - Network: don't use - -network=host`. Use bridges or CNI.
- No - -privileged
. No - -pid=host. No - -ipc=host`. - No mounted Docker socket from inside the container.
- Volume mounts: only what's needed; consider
:ro,:Z(SELinux relabel). - Run the container in a user namespace ( - -userns=auto` in podman; rootless by default).
A.3 Daemon / Host Hardening¶
- Rootless runtime (
podmanrootless mode). - If using a daemon:
dockerdorcontainerdrunning as a hardened systemd unit (applyLinux/05_security_and_hardening.mddirectives). - LSM enforcing on the host.
- Modern kernel (≥ 5.10 for full rootless features).
- OverlayFS instead of
vfs. - Disk quotas (
xfs_quota) or - -storage-opt overlay.size=` for runaway-image protection.
A.4 Sandbox Tier (when needed)¶
For untrusted code:
- gVisor (runsc): registered as a containerd runtime. Mark untrusted workloads with runtimeClassName: gvisor (Kubernetes) or - -runtime=runsc` (nerdctl).
- Kata Containers: per-container micro-VM. Higher overhead, stronger isolation.
- Firecracker: micro-VM as a runtime. Used by AWS Lambda.
Decision matrix: | Workload | Runtime | |---|---| | Trusted internal services | runc / crun | | Customer-supplied code | runsc (gVisor) | | Regulated / multi-tenant | Kata | | Serverless, very-short-lived | Firecracker / runsc |
A.5 Supply-Chain Hardening¶
- All images signed with cosign.
- All images have attached SBOMs.
- All images have SLSA L3 (or higher) provenance.
- Admission policy verifies signatures at pull time.
- Vulnerability scanning continuous; new criticals page on-call.
- VEX statements for non-exploitable findings.
- Registry retention: signed images retained, unsigned discarded.
A.6 The container-baseline/ Template¶
container-baseline/
Dockerfile.template # multi-stage, distroless final
build.sh # buildah-based reproducible build
cosign-policy.yaml # admission policy (signature + SLSA)
seccomp/
default.json # tighter than runtime/default
apparmor/ # per-service profiles
selinux/ # type-enforcement modules
ci/
build.yml # build + scan + sign + attest
promote.yml # verify + tag + push to prod registry
scripts/
audit-image.sh # trivy + grype + syft, formatted
RUNBOOK.md
THREAT_MODEL.md
Every image you ship after week 24 should be built using this template.