Security Contexts

[!IMPORTANT] A SecurityContext defines privilege and access control settings for a Pod or Container. It is the primary way to harden your workloads against container breakouts.

The Problem: The “Root” of All Evil

Imagine running a banking web application. You’ve isolated it in a Docker container, assuming the perimeter is secure. However, an attacker exploits a remote code execution vulnerability in your app. Once inside, they discover they are running as root (UID 0) within the container—which is Docker’s default behavior.

Because the container fundamentally shares the underlying host’s kernel, the attacker can leverage a kernel exploit or a misconfigured capability to break out of the container boundary, effectively taking over the entire Kubernetes node.

Security Contexts are the mechanism to lock this down. By applying the Principle of Least Privilege at the Pod and Container levels, you can prevent lateral movement and container breakouts.


1. User and Group IDs (UID/GID)

Don’t run as root (UID 0). Pick an arbitrary ID.

securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  runAsNonRoot: true # Fails to start if image defaults to root

[!TIP] If you set runAsNonRoot: true, Kubernetes will check the image metadata. If the image is built to run as root (default), the Pod will crash with CreateContainerConfigError.

2. Read-Only Root Filesystem

Prevent attackers from installing tools (apt-get install nmap) or modifying configuration files.

securityContext:
  readOnlyRootFilesystem: true

Note: If your app needs to write temp files, mount an emptyDir volume to /tmp.


3. Linux Capabilities (The “Power Buttons”)

Root isn’t just one permission; it’s a collection of Capabilities (e.g., CAP_CHOWN, CAP_NET_ADMIN). Docker drops most by default, but you should drop ALL and only add back what is strictly needed.

Interactive: Capability Dropper

What power does your container have?

Current State

Select capabilities to see what they allow.

Risk Level: MEDIUM

4. Pod vs. Container Context

You can set security contexts at two levels:

  1. Pod Level: Applies to all containers. (e.g., runAsUser, fsGroup)
  2. Container Level: Overrides Pod settings. (e.g., capabilities, readOnlyRootFilesystem)
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsUser: 1000 # Pod-wide default
    fsGroup: 2000   # For volume permissions
  containers:
  - name: app
    image: my-app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"] # Best Practice!

[!WARNING] Privileged Mode (privileged: true) gives the container nearly all the same access as processes running on the host. It effectively disables all security mechanisms. Never use this in production unless absolutely necessary (e.g., CNI plugins).