K8s Security Pro
#03 Pod Security free

Hardened Pod Security Context

A Deployment template with a fully hardened security context including non-root execution, read-only filesystem, dropped capabilities, and seccomp profiles.

CIS Benchmark
5.2.45.2.55.2.75.2.95.2.12
MITRE ATT&CK
T1059T1611

Overview

This template provides a production-ready Deployment with every recommended security context setting applied. It configures both pod-level and container-level security contexts to enforce non-root execution, read-only filesystems, dropped capabilities, and seccomp filtering.

Security threat addressed: Containers without hardened security contexts run with excessive permissions, allowing attackers to install tools, escalate privileges, and escape to the host node.

When to use: Use this as a starting template for every new application deployment. Adapt the resource limits and container image to your application requirements while preserving all security settings.

Threat Model

  • Tool installation prevention: Read-only root filesystem prevents attackers from downloading malware, crypto miners, or reconnaissance tools.
  • Capability restriction: Dropping all Linux capabilities removes an attacker’s ability to manipulate network settings, mount filesystems, or perform other privileged operations.
  • Privilege escalation blocking: allowPrivilegeEscalation: false prevents setuid binaries (like sudo) from granting root privileges.
  • Kernel attack surface reduction: RuntimeDefault seccomp profile blocks dangerous system calls that enable container escapes.

MITRE ATT&CK:

  • T1059 — Command and Scripting Interpreter: Writable filesystems allow attackers to download and execute scripts or tools.
  • T1611 — Escape to Host: Unrestricted capabilities and privilege escalation enable container-to-host escape.

Real-world scenario: An attacker exploits a remote code execution vulnerability in your application. With this hardened security context, they cannot write files, install tools, escalate to root, or escape the container.

YAML Source

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hardened-app
  namespace: default
  labels:
    app.kubernetes.io/name: k8s-security
    app.kubernetes.io/part-of: k8s-security-pro
    app.kubernetes.io/managed-by: k8s-security-pro
spec:
  selector:
    matchLabels:
      app: hardened-app
  template:
    metadata:
      labels:
        app: hardened-app
    spec:
      # POD-LEVEL SECURITY CONTEXT
      # Applies to all containers in the Pod.
      securityContext:
        runAsNonRoot: true        # Prevents the container from starting as root (UID 0).
        runAsUser: 10001          # Explicitly define a high UID (not 0).
        runAsGroup: 10001         # Explicitly define a GID.
        fsGroup: 10001            # Ensures mounted volumes are readable by this group.
        seccompProfile:
          type: RuntimeDefault    # System Call Filtering: Blocks dangerous kernel calls.

      containers:
      - name: my-app
        image: my-app:1.0.0
        # CONTAINER-LEVEL SECURITY CONTEXT
        securityContext:
          allowPrivilegeEscalation: false # Prevents tools like sudo/setuid from working.
          readOnlyRootFilesystem: true    # Makes the container filesystem immutable.
          capabilities:
            drop:
            - ALL                         # Drops all Linux capabilities.
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Installation

kubectl:

kubectl apply -f 03_hardened_pod_security_context.yaml

Helm:

helm install k8s-security ./charts/k8s-security -f values-prod.yaml

Kustomize:

kubectl apply -k kustomize/overlays/prod

Verification

# Verify the deployment is running
kubectl get deployment hardened-app -n <namespace>

# Check security context on running pods
kubectl get pods -l app=hardened-app -o jsonpath='{.items[*].spec.securityContext}'

# Verify read-only filesystem (writing should fail)
kubectl exec -n <namespace> <pod-name> -- touch /test-file 2>&1
# Expected: touch: /test-file: Read-only file system

# Verify non-root execution
kubectl exec -n <namespace> <pod-name> -- id
# Expected: uid=10001 gid=10001

# Verify capabilities are dropped
kubectl exec -n <namespace> <pod-name> -- cat /proc/1/status | grep Cap

CIS Benchmark References

  • 5.2.4 — Minimize the admission of containers with readOnlyRootFilesystem set to false.
  • 5.2.5 — Minimize the admission of containers with allowPrivilegeEscalation.
  • 5.2.7 — Minimize the admission of root containers.
  • 5.2.9 — Minimize the admission of containers with added capabilities.
  • 5.2.12 — Minimize the admission of containers without a configured seccomp profile.

MITRE ATT&CK References

  • T1059 — Command and Scripting Interpreter: Writable filesystems allow attackers to download and execute scripts or tools. Read-only root filesystem prevents this.
  • T1611 — Escape to Host: Linux capabilities like CAP_SYS_ADMIN enable container escape. Dropping all capabilities and blocking privilege escalation eliminates these vectors.

Further Reading