What You'll Learn
Container security is built on a foundation of understanding isolation mechanisms, threat models, and hardening techniques. This learning path teaches you how containers actually isolate workloads from each other and from the host, what security threats exist in containerized environments, and how to build and deploy container architectures that are secure by design. By the end of this path, you will know how to build hardened container images from scratch, implement security controls from the CIS Docker Benchmark, enforce security policies in Kubernetes clusters, scan images for vulnerabilities, sign images to verify their authenticity, and manage the complete supply chain from code to running container.
This path spans 4-6 weeks and requires 20-30 hours of study and hands-on work. It is designed for learners at the beginner to intermediate level who have basic Linux knowledge and are already familiar with Docker or container basics.
graph TB Week1["Week 1<br/>Fundamentals<br/>Isolation<br/>Threats"] Week2["Week 2<br/>Image Security<br/>Hardening<br/>Scanning"] Week3["Week 3<br/>Kubernetes<br/>Deployment<br/>Policies"] Week4["Week 4<br/>Compliance<br/>Monitoring<br/>Incident Response"] Week1 --> Week2 Week2 --> Week3 Week3 --> Week4 Week4 --> Goal["Secure Container<br/>Deployment"] style Goal fill:#c8e6c9Learning Outcomes
After completing this learning path, you will be able to understand container architecture and the isolation mechanisms that make containerization secure. You will be able to identify common container security threats, including escape vectors and privilege escalation techniques. You will be able to implement security controls from the CIS Docker Benchmark in your own container deployments. You will know how to build hardened container images following security best practices. You will be able to deploy secure containers to Kubernetes with appropriate security contexts and policies. You will be able to scan container images for vulnerabilities using tools like Trivy and interpret the results. Finally, you will be able to enforce container security policies in Kubernetes clusters using admission controllers and policy engines like OPA/Gatekeeper or Kyverno.
Module 1: Container Fundamentals (Week 1)
Concepts
In the Container Basics unit, you will learn what a container actually is—an isolated process, not a virtual machine. You will understand the differences between containers and VMs and when each is appropriate. You will learn Docker architecture, including images (the blueprints), layers (the stackable components), containers (running instances), and the container runtime (the tool that creates containers). You will understand containerd and runc, the modern runtime stack that powers Docker and Kubernetes.
In the Container Isolation unit, you will learn about Linux namespaces: the process namespace that hides processes from other containers, the network namespace that gives each container its own virtual network interface, the filesystem namespace that gives each container its own view of the filesystem, and the IPC, PID, and user namespaces that provide additional isolation boundaries. You will learn about control groups (cgroups), which enforce resource limits preventing containers from consuming unlimited CPU, memory, or I/O. You will understand how containers achieve isolation through these kernel mechanisms and the limitations of this isolation—notably that all containers share the same kernel.
In the Container Images unit, you will learn how image layers work through a copy-on-write mechanism that allows efficient sharing of base image layers across multiple containers. You will learn about image registries and repositories where images are stored and distributed, image tagging and versioning schemes that allow multiple versions of an image, and image digests (SHA256 hashes) that provide content addressability so you can guarantee you are always deploying the exact same image.
Hands-On Labs
Lab 1.1: Explore Container Internals
# Run container with debug flagsdocker run -it --privileged ubuntu:22.04 bash # Inside container:# - Check namespaces: ls /proc/self/ns/# - Check cgroups: cat /proc/self/cgroup# - Verify isolation: hostname, ip addr# - Check filesystems: mount, df # From host (in another terminal):# - List running containers: docker ps# - Inspect container: docker inspect <container_id># - Check resource usage: docker statsLab 1.2: Build and Push Image
# Create Dockerfilecat > Dockerfile << 'EOF'FROM python:3.11-slimRUN pip install flaskCOPY app.py /app/app.pyENTRYPOINT ["python", "/app/app.py"]EOF # Build imagedocker build -t myapp:v1.0 . # Tag imagedocker tag myapp:v1.0 registry.example.com/myapp:v1.0 # Push to registrydocker push registry.example.com/myapp:v1.0 # Verify: Pull from another machinedocker pull registry.example.com/myapp:v1.0Module 2: Container Security Threats (Week 1)
Concepts
In the Container Escape unit, you will learn what container escape means—when an attacker breaks out of the container and gains access to the host or other containers. You will understand kernel vulnerabilities that enable escapes, how privileged operations create escape opportunities, resource exhaustion attacks that can trigger unexpected behavior, and mitigation strategies like keeping the kernel patched, using sandboxed runtimes like gVisor, and running unprivileged containers.
In the Image Security unit, you will learn how vulnerable base images can introduce known CVEs into all images built on top of them, making base image selection critical. You will understand how malicious dependencies—packages that contain intentional backdoors or unwanted code—can compromise your entire application. You will learn about supply chain attacks where an attacker compromises the build system or registry to inject malware. You will understand image tampering, where someone modifies an image after it is built, and image verification techniques using cryptographic signatures to ensure images have not been modified.
In the Runtime Threats unit, you will learn about privilege escalation vulnerabilities that allow containers to gain root access. You will understand resource exhaustion attacks where one container consumes all available resources, affecting other containers. You will learn about lateral movement, where an attacker compromises one container and then uses it as a foothold to attack other containers or the host. You will understand data exfiltration, where an attacker steals sensitive data from the container or host.
Hands-On Labs
Lab 2.1: Identify Vulnerable Image
# Scan image with Trivytrivy image ubuntu:22.04 # Output shows:# - OS package vulnerabilities# - Dependency vulnerabilities# - Severity levels # Compare with distrolesstrivy image gcr.io/distroless/base-debian12 # Observation: Distroless has fewer vulnerabilitiesLab 2.2: Trace Privilege Escalation
# ❌ Create vulnerable imagecat > Dockerfile.vulnerable << 'EOF'FROM ubuntu:22.04RUN apt-get update && apt-get install -y sudoRUN useradd -m appuserUSER appuserRUN echo "appuser ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoersEOF # Build and run vulnerable containerdocker build -f Dockerfile.vulnerable -t vulnerable:latest .docker run -it vulnerable:latest bash # Inside: Try privilege escalationsudo id # Should show uid=0 (root) - VULNERABLE! # ✅ Create hardened imagecat > Dockerfile.hardened << 'EOF'FROM ubuntu:22.04RUN useradd -m appuserUSER appuserEOF # Build and run hardened containerdocker build -f Dockerfile.hardened -t hardened:latest .docker run -it hardened:latest bash # Inside: Try privilege escalationsudo id # Error: sudo: command not found - SECURE!Module 3: Container Hardening (Week 2)
Concepts
In the Image Hardening unit, you will learn how to run containers as non-root users, eliminating an entire class of privilege escalation vulnerabilities. You will learn about distroless images that contain only your application and its direct dependencies, with no shell, package manager, or other tools. These images have a tiny attack surface because there is nothing to exploit. You will learn how to implement read-only filesystems, preventing attackers from persisting modifications. You will learn to use minimal base images with fewer packages, reducing the number of potential vulnerabilities. You will understand supply chain security principles, ensuring that every component in your image comes from a trusted source.
In the Runtime Hardening unit, you will learn about Kubernetes security contexts, which allow you to specify constraints like running as non-root, dropping capabilities, and preventing privilege escalation. You will learn about Linux capabilities, the fine-grained permissions that can be granted or dropped to limit what a container can do. You will understand SELinux and AppArmor, mandatory access control systems that enforce security policies at the kernel level. You will learn to set resource limits, preventing containers from consuming unlimited CPU and memory. You will understand network policies, which restrict communication between containers at the network level.
In the CIS Docker Benchmark unit, you will learn the structure of the benchmark and its security controls. You will understand the key controls that have the highest impact, such as running as non-root, dropping capabilities, and scanning images. You will learn how to automate benchmark compliance checking. You will understand how to verify that your deployments actually comply with the benchmark.
Hands-On Labs
Lab 3.1: Build Hardened Container
# Multi-stage hardened buildFROM ubuntu:22.04 AS builder RUN apt-get update && apt-get install -y python3 pipCOPY requirements.txt .RUN pip install -r requirements.txt # Runtime stage - minimalFROM gcr.io/distroless/base-debian12 # Create non-root userRUN useradd -m -u 1000 appuserUSER appuser COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/lib/python3.11/site-packagesCOPY app.py /app/app.py WORKDIR /appENTRYPOINT ["python3", "app.py"]Build and verify:
docker build -t myapp:hardened . # Verify userdocker run myapp:hardened id# uid=1000(appuser) gid=1000(appuser) groups=1000(appuser) # Verify filesystem (try to write to root)docker run myapp:hardened touch /test.txt# Error: Read-only file system - SECURE!Lab 3.2: Implement Security Context
# Pod with hardened security contextapiVersion: v1kind: Podmetadata: name: hardened-appspec: containers: - name: app image: myapp:hardened securityContext: runAsNonRoot: true runAsUser: 1000 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: limits: cpu: "500m" memory: "256Mi" volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {}Deploy and verify:
kubectl apply -f hardened-pod.yaml # Verify running as non-rootkubectl exec -it hardened-app -- id# uid=1000(appuser) gid=1000(appuser) # Verify capabilities droppedkubectl exec -it hardened-app -- chroot /# Error: Operation not permittedLab 3.3: Run CIS Benchmark Scanner
# Install and run CIS Benchmark scannerdocker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy config docker://myapp:hardened # Or run with oscaposcap container image scan \ --profile xccdf_org.ssgproject.content_profile_cis_docker \ myapp:hardened # Output shows which CIS controls pass/failModule 4: Vulnerability Scanning (Week 2-3)
Concepts
In the Vulnerability Databases unit, you will learn about the National Vulnerability Database (NVD), which is the authoritative source for CVE information. You will understand CVEs (Common Vulnerabilities and Exposures), the standard way to identify and track security vulnerabilities. You will learn CVSS scores, which provide a standardized numerical rating of vulnerability severity. You will learn how to use package vulnerability databases that track vulnerabilities in dependencies specific to your programming language.
In the Scanning Tools unit, you will learn Trivy, Grype, and Syft—three complementary open-source tools for vulnerability scanning. Trivy scans images comprehensively. Grype excels at dependency scanning. Syft generates software bills of materials. You will understand image layer scanning, which identifies vulnerabilities in the OS and base image. You will learn dependency scanning, which finds vulnerabilities in application dependencies. You will understand configuration scanning, which identifies misconfigurations.
In the SBOM and VEX unit, you will learn what a Software Bill of Materials (SBOM) is—a machine-readable inventory of every component in your image. You will understand VEX (Vulnerability Exploitability eXchange), a standard way to mark vulnerabilities as "not affected" or "affected but accepted" with cryptographic proof. You will learn how to contextualize vulnerability risk using VEX statements, transforming a list of all CVEs into a list of actually exploitable vulnerabilities. You will understand how VEX reduces alert fatigue from false positives.
Hands-On Labs
Lab 4.1: Vulnerability Scanning
# Scan image for vulnerabilitiestrivy image ubuntu:22.04 # Output includes:# - Vulnerability ID (CVE)# - Severity (CRITICAL, HIGH, etc.)# - Installed version vs fixed version# - CVSS score # Export SBOMtrivy image --format spdx-json ubuntu:22.04 > sbom.json # Scan with different severity thresholdtrivy image --severity HIGH,CRITICAL ubuntu:22.04 # Scan only OS packages (exclude dependencies)trivy image --scanners vuln ubuntu:22.04Lab 4.2: Generate SBOM
# Generate SBOM with Syftsyft ghcr.io/myorg/myapp:v1.0 -o spdx-json > sbom.spdx.json # View SBOMjq '.packages[] | {name, version}' sbom.spdx.json # Generate CycloneDX formatsyft ghcr.io/myorg/myapp:v1.0 -o cyclonedx-json > sbom.cyclonedx.json # Compare vulnerabilities in SBOMgrype sbom.spdx.jsonLab 4.3: Context with VEX
# Mark vulnerability as NOT_AFFECTED with VEXcat > vex-statement.json << 'EOF'{ "statements": [ { "vulnerability": { "name": "CVE-2024-1234" }, "products": [ { "identifiers": { "purl": "pkg:docker/myapp@sha256:abc123..." } } ], "status": "NOT_AFFECTED", "justification": "vulnerable_code_not_present" } ]}EOF # Attach VEX to imagecosign attest --attestation-type vuln \ --predicate vex-statement.json \ ghcr.io/myorg/myapp:v1.0 # Verify with CleanStart or similar tool# Alert count reduces based on VEX contextModule 5: Container Orchestration Security (Week 3-4)
Concepts
In the Kubernetes Security unit, you will learn about pod security policies (now replaced by Pod Security Standards in newer Kubernetes versions), which enforce security constraints on all pods in a cluster. You will learn network policies, which restrict traffic between pods at the network level. You will understand RBAC (Role-Based Access Control), which controls what users and service accounts can do in the cluster. You will learn about admission controllers, which intercept requests and can enforce policies or mutate objects before they are persisted.
In the Container Runtime Security unit, you will learn how to monitor container behavior at runtime to detect compromises. You will understand anomaly detection, which identifies unusual behavior that might indicate an attack. You will learn threat detection techniques that look for known attack patterns. You will understand how to analyze logs from containers and the runtime to investigate security incidents.
In the Policy Enforcement unit, you will learn OPA/Gatekeeper, a policy engine that can express complex security policies in code. You will understand policy-as-code, where security policies are expressed as executable code rather than documents. You will learn how to automate compliance checking. You will understand audit logging, which records every policy decision for compliance and incident investigation.
Hands-On Labs
Lab 5.1: Implement Network Policy
# Network policy: Restrict traffic to databaseapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: app-database-policyspec: podSelector: matchLabels: tier: app policyTypes: - Egress egress: - to: - podSelector: matchLabels: tier: database ports: - protocol: TCP port: 5432 - to: - namespaceSelector: {} ports: - protocol: UDP port: 53 # DNS onlyDeploy and test:
kubectl apply -f network-policy.yaml # Test connectivity# Before: kubectl exec app -- curl database-service# After: Connection times out (blocked by network policy) # Only allowed traffic should workkubectl exec app -- psql -h database-service # SuccessLab 5.2: OPA/Gatekeeper Policy
# Install Gatekeeperkubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yaml # Create constraint template for required labelscat > constraint-template.yaml << 'EOF'apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8srequiredlabelsspec: crd: spec: names: kind: K8sRequiredLabels targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequired deny[msg] { container := input.review.object.spec.containers[_] not input.review.object.metadata.labels["app"] msg := "Pod must have 'app' label" }EOF # Apply constraintkubectl apply -f constraint-template.yaml # Create constraint (enforce policy)cat > constraint.yaml << 'EOF'apiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sRequiredLabelsmetadata: name: require-labelsspec: match: kinds: - apiGroups: [""] kinds: ["Pod"]EOF kubectl apply -f constraint.yaml # Test: Pod without label is rejectedkubectl apply -f pod-without-label.yaml# Error: Pod must have 'app' label # Test: Pod with label is acceptedkubectl apply -f pod-with-label.yaml# SuccessLab 5.3: RBAC Configuration
# Create service account for appapiVersion: v1kind: ServiceAccountmetadata: name: myapp namespace: default ---# Create role with minimal permissionsapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: myapp-rolespec: rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list"] - apiGroups: [""] resources: ["secrets"] resourceNames: ["db-creds"] verbs: ["get"] ---# Bind role to service accountapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: myapp-rolebindingroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: myapp-rolesubjects:- kind: ServiceAccount name: myapp namespace: defaultDeploy and verify:
kubectl apply -f rbac.yaml # Pod uses service accountkubectl run myapp --image=myapp:latest --serviceaccount=myapp # Verify permissionskubectl exec -it myapp -- kubectl get secrets# Error: Unauthorized - service account lacks permissionsModule 6: Supply Chain Security (Week 4-5)
Concepts
In the Container Image Signing unit, you will learn how digital signatures prove that an image came from a trusted builder and has not been modified. You will learn Cosign and Sigstore, modern tools for signing and verifying container images. You will understand keyless signing with OIDC, which allows signing without managing private keys. You will learn how to verify signatures before deploying images.
In the Build Integrity unit, you will learn the SLSA framework (Supply Chain Levels for Software Artifacts), which defines levels of security assurance for how artifacts are produced. You will understand build provenance, the complete record of what went into an artifact and how it was built. You will learn about reproducible builds, where building the same source code produces the exact same artifact, allowing you to prove the binary is authentic. You will understand attestations, cryptographically signed metadata about the build.
In the Trust and Verification unit, you will learn how to verify image signatures before deploying, using policies to prevent unsigned images from running. You will learn policy enforcement mechanisms in Kubernetes. You will understand transparency logs like Rekor, which create immutable records of all signatures, allowing anyone to audit the signing history. You will understand end-to-end supply chain verification, ensuring every component from source code to running container is verified.
Hands-On Labs
Lab 6.1: Sign Container Image
# Install Cosigncurl -Lo /usr/local/bin/cosign https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64chmod +x /usr/local/bin/cosign # Sign image (keyless with Sigstore)cosign sign --yes ghcr.io/myorg/myapp:v1.0# Uses OIDC to get temporary certificate # Verify signaturecosign verify \ --certificate-identity-regexp="https://github.com/" \ --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ ghcr.io/myorg/myapp:v1.0 # Check transparency log (Rekor)rekor-cli search --image ghcr.io/myorg/myapp:v1.0Lab 6.2: Enforce Signature Policy
# Gatekeeper policy: Require signed imagesapiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sSignedImagemetadata: name: require-signed-imagesspec: match: kinds: - apiGroups: [""] kinds: ["Pod"] parameters: publicKeys: - name: github-actions key: | -----BEGIN PUBLIC KEY----- [Your public key] -----END PUBLIC KEY----- trustedIssuers: - "https://token.actions.githubusercontent.com"Deploy and test:
kubectl apply -f signature-policy.yaml # Unsigned image rejectedkubectl apply -f unsigned-pod.yaml# Error: Image not signed # Signed image acceptedkubectl apply -f signed-pod.yaml# SuccessModule 7: Capstone Project (Week 5-6)
Project: End-to-End Secure Container Deployment
Build a complete secure container pipeline through these steps: create a secure application (Python/Node.js app), write a hardened Dockerfile with distroless base, generate SBOM with Syft, scan for vulnerabilities with Trivy, create VEX statements for false positives, sign the image with Cosign/Sigstore, deploy to Kubernetes with security context, enforce policies with OPA/Gatekeeper, implement network policies to restrict traffic, and document the complete pipeline with automation.
Deliverables
- Dockerfile with security best practices
- SBOM in SPDX format
- VEX statement addressing key vulnerabilities
- Signed container image in registry
- Kubernetes manifests with security controls
- OPA policy enforcing standards
- Deployment documentation with verification steps
- Security audit report showing all controls met
Assessment
Knowledge Check
[ ] Explain container isolation mechanisms. [ ] Identify CIS Docker Benchmark requirements. [ ] Describe vulnerability scanning process. [ ] Understand supply chain attack vectors. [ ] Implement hardened Dockerfile. [ ] Deploy secured Pod with policies. [ ] Verify image signatures. [ ] Generate and interpret SBOM/VEX.
Practical Skills
[ ] Build hardened container images. [ ] Scan for vulnerabilities with Trivy/Grype. [ ] Generate SBOMs with Syft. [ ] Sign images with Cosign. [ ] Deploy to Kubernetes with security contexts. [ ] Create network policies. [ ] Implement OPA/Gatekeeper policies. [ ] Verify supply chain integrity.
Next Steps
After completing this learning path, you can proceed to the Hardening Supply Chain Path to learn build security and SLSA, the Kubernetes Security Path for deep dive into Kubernetes-specific security, the Federal Compliance Path focusing on FIPS and DISA STIG requirements, or the AI/ML Workload Security path for securing containers for machine learning.
Additional Resources
CIS Docker Benchmark. NIST 800-190. Kubernetes Security Best Practices. Sigstore Documentation. OPA/Gatekeeper Documentation.
