A comprehensive approach to securing containers from build to runtime.
*Datanest Digital — datanest.dev*
2. Vulnerability Scanning Pipeline
Every container image should follow three principles:
1. Minimal: Include only what the application needs to run. No shells, no package managers, no debugging tools in production images.
2. Immutable: Never patch running containers. Rebuild and redeploy.
3. Non-root: Never run as UID 0.
Multi-stage builds are the foundation of hardened images. Build tools, compilers, and development dependencies never reach the final image:
# Build stage — has gcc, make, pip, etc.
FROM python:3.12-slim AS builder
COPY requirements.txt .
RUN pip install --prefix=/install -r requirements.txt
# Production stage — only runtime dependencies
FROM python:3.12-slim
COPY --from=builder /install /usr/local
COPY --chown=10001:10001 src/ ./src/
USER 10001| Language | Recommended Base | Size | Notes |
|---|---|---|---|
| Python | python:X.Y-slim | ~150MB | Debian slim, includes glibc |
| Node.js | node:X-alpine | ~50MB | Musl libc, smallest option |
| Go | scratch or gcr.io/distroless/static | ~2-10MB | No OS at all |
| Java | eclipse-temurin:X-jre + debian:slim | ~100MB | JRE only, no JDK |
:latest)HEALTHCHECK instructionCOPY instead of ADDENV or ARG.dockerignore to exclude .git, node_modules, etc.No single scanner catches everything. Use at least two:
| Scanner | Strength | Weakness |
|---|---|---|
| Trivy | Fast, comprehensive, misconfigs | Fewer language-specific advisories |
| Grype | Strong language ecosystem coverage | No misconfig scanning |
| Hadolint | Dockerfile best practices | Only lints Dockerfiles |
Developer Workstation CI/CD Pipeline Registry
│ │ │
hadolint lint trivy image scan periodic rescan
(pre-commit) grype image scan (new CVE DB)
│ conftest policy │
│ │ │
└──── Push ──── Build ── Scan ── Push ── Monitor
1. CRITICAL: Block deployment. Fix immediately.
2. HIGH: Block deployment. Fix within 7 days.
3. MEDIUM: Allow deployment. Fix within 30 days.
4. LOW: Track in backlog.
Create a .trivyignore file for accepted risks:
# CVE-2024-12345: Not exploitable in our configuration
# Reviewed by: security-team, Date: 2026-01-15
CVE-2024-12345
Always document the justification and review date.
OPA policies enforce rules at build time using conftest:
# Test Dockerfiles against policies
conftest test Dockerfile -p policies/opa/
# Test Kubernetes manifests
conftest test deployment.yaml -p policies/opa/Key policies included:
Kyverno policies enforce rules at deploy time as a Kubernetes admission controller:
# Install Kyverno
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
# Apply policies
kubectl apply -f policies/kyverno/Key policies:
@sha256: references| Mode | Behavior | Use Case |
|---|---|---|
Enforce | Block non-compliant resources | Production |
Audit | Log violations but allow | Migration period |
Start in Audit mode, monitor violations, then switch to Enforce.
Seccomp restricts which syscalls a container can make. The included profile blocks:
ptrace — Prevents debugging/container escapemount/umount — Prevents filesystem manipulationunshare/setns — Prevents namespace escapekexec_load — Prevents kernel replacementinit_module — Prevents kernel module loadingApply in Kubernetes:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/seccomp-profile.jsonAppArmor provides mandatory access control. The included profile:
/tmp (common attack vector)# Load profile on each node
sudo apparmor_parser -r /etc/apparmor.d/container-restricted
# Apply to pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/myapp: localhost/container-restrictedEvery production pod should have:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]The included workflow (container-security.yml) implements:
1. Lint — Hadolint checks Dockerfile best practices
2. Build — Docker Buildx with layer caching and SBOM generation
3. Scan — Trivy + Grype vulnerability scanning with SARIF upload
4. Policy — conftest OPA policy validation
5. Gate — Security summary with pass/fail gate
# .pre-commit-config.yaml
repos:
- repo: https://github.com/hadolint/hadolint
rev: v2.12.0
hooks:
- id: hadolint-dockerNew CVEs are published daily. Rescan deployed images on a schedule:
on:
schedule:
- cron: '0 6 * * *' # Daily at 6 AM UTC| Security Control | CIS Docker 1.6 | CIS Kubernetes 1.8 | NIST 800-190 |
|---|---|---|---|
| Non-root user | 4.1 | 5.2.6 | CM-7 |
| Read-only rootfs | 5.12 | 5.2.4 | AC-6 |
| Resource limits | 5.10 | 5.2.7 | SC-6 |
| Image scanning | 4.4 | — | RA-5 |
| Seccomp profiles | 5.2 | 5.2.2 | SC-39 |
| No privileged | 5.4 | 5.2.1 | AC-6(1) |
| Image signing | 4.5 | — | SI-7 |
| Network policies | — | 5.3.2 | SC-7 |
1. Isolate: Apply a deny-all NetworkPolicy to the compromised pod
2. Capture: Export container filesystem for forensics
kubectl cp <pod>:/app ./forensics/app-snapshot
docker export <container> > forensics/container.tar3. Investigate: Check logs, network connections, process list
4. Remediate: Rebuild from clean base image, rotate secrets
5. Harden: Add policies to prevent recurrence
# Check running processes in container
kubectl exec <pod> -- ps aux
# Check network connections
kubectl exec <pod> -- netstat -tlnp
# Check for unexpected SUID binaries
kubectl exec <pod> -- find / -perm -4000 -type f 2>/dev/null
# Check container events
kubectl describe pod <pod> | grep -A 20 Events*Part of the Container Security Toolkit by Datanest Digital.*
*For support: hello@datanest.dev*
Harden, scan, and enforce security policies across your container infrastructure.
*Datanest Digital — datanest.dev*
Get the full Container Security Toolkit and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.