Skip to main content
RunBook Academy

KubernetesLXIII · Linux Security Controls in KubernetesLinux security controls

Linux capabilities — the kernel privilege boundary

Advanced⏱ ~14 minkubectl

What you'll learn

  • Explain what Linux capabilities are and how the kernel splits root privileges
  • Set the right capabilities in a Pod's securityContext (`drop ALL`, add only what is needed)
  • Identify the dangerous capabilities (`SYS_ADMIN`, `SYS_PTRACE`, `NET_ADMIN`) and their impact
  • Recognise the production failure modes (privileged, broad capabilities, missing drop ALL)

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Linux capabilities are the kernel’s mechanism for splitting the monolithic root privilege into discrete units. A process can have CAP_NET_BIND_SERVICE without having CAP_SYS_ADMIN. A container that runs as root but drops CAP_SYS_ADMIN is much less dangerous than one that does not. This lesson covers the capabilities, the right Kubernetes pattern, and the failure modes.

The capability model

Historically, a Unix process was either root (UID 0) or non-root. Capabilities split root into discrete units:

  • CAP_NET_BIND_SERVICE — bind to privileged ports (<1024)
  • CAP_NET_ADMIN — network configuration
  • CAP_SYS_ADMIN — broad system administration (mount, swapon, setuid, etc.) — the “almost root” capability
  • CAP_SYS_PTRACE — trace other processes
  • CAP_DAC_OVERRIDE — bypass file permission checks
  • CAP_CHOWN — change file ownership
  • CAP_FOWNER — bypass owner checks on operations
  • CAP_KILL — send signals to processes owned by other users
  • … and ~40 more

A container with drop: ["ALL"] has none of these; a container with add: ["NET_BIND_SERVICE"] has only that capability.

Setting capabilities in a Pod

The Pod’s securityContext.capabilities field controls the capabilities:

apiVersion: v1
kind: Pod
metadata:
  name: api
spec:
  containers:
  - name: api
    image: myapp:v1.0
    securityContext:
      capabilities:
        drop: ["ALL"]
        add: ["NET_BIND_SERVICE"]  # only if the workload binds to <1024

The drop field removes capabilities; the add field adds them. The order matters: capabilities are evaluated as defaults → drop → add. The container’s final capability set is defaults - drop + add.

flowchart LR
    A[Default capabilities] --> B[drop ALL]
    B --> C[add only needed]
    C --> D[Final set]

The dangerous capabilities

Three capabilities are particularly dangerous:

CapabilityWhat it allows
CAP_SYS_ADMINMount filesystems, setuid, swap, almost everything — close to root
CAP_SYS_PTRACETrace other processes — debug, but also inject code
CAP_DAC_OVERRIDEBypass file permission checks — read any file

A container with CAP_SYS_ADMIN can mount the host filesystem, escape the runtime, and gain full control of the node. The PSS baseline profile forbids CAP_SYS_ADMIN; restricted forbids it via drop: ["ALL"].

PSS restricted and capabilities

The restricted profile requires:

securityContext:
  capabilities:
    drop: ["ALL"]

If a workload needs a specific capability:

securityContext:
  capabilities:
    drop: ["ALL"]
    add: ["NET_BIND_SERVICE"]  # the only one allowed by restricted

The only capability that restricted allows to be added is NET_BIND_SERVICE (for binding to a privileged port as non-root). Any other added capability is rejected.

A hardened container

A container that meets restricted:

apiVersion: v1
kind: Pod
metadata:
  name: api
  namespace: prod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: api
    image: myapp:v1.0
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
        add: ["NET_BIND_SERVICE"]  # only if binding to <1024
    volumeMounts:
    - name: tmp
      mountPath: /tmp
  volumes:
  - name: tmp
    emptyDir: {}

The container has no capabilities except NET_BIND_SERVICE. A container escape attempt would fail because the container cannot mount filesystems (no CAP_SYS_ADMIN), trace processes (no CAP_SYS_PTRACE), or bypass file checks (no CAP_DAC_OVERRIDE).

Common failure modes

  1. No drop: ["ALL"]. The container has all capabilities by default. A container escape gives the attacker full kernel access.
  2. add: ["SYS_ADMIN"]. The container can mount filesystems and perform almost-root operations. Almost certainly a misconfiguration.
  3. add: ["NET_ADMIN"]. The container can change the network configuration (iptables, interfaces). Required for some network tools but rarely for production workloads.
  4. Privileged container. securityContext.privileged: true grants all capabilities. Reserved for system workloads.

Production patterns

  1. drop: ["ALL"] on every container. The default for production.
  2. Add only what is needed. Typically just NET_BIND_SERVICE.
  3. Audit capabilities in CI/CD. kube-linter flags add: ["SYS_ADMIN"] and other dangerous capabilities.
  4. Document every add. A list of which workloads add which capabilities is reviewed quarterly.

Cross-course references

  • The Linux course covers the kernel capability model in detail.
  • The Observability course covers the audit log entries for capability-related events.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the right `securityContext.capabilities` configuration for a production container that does not need any capabilities?

  2. Q2. `CAP_SYS_ADMIN` is a low-risk capability that is often added to production containers for convenience.

  3. Q3. Your networking workload sets `securityContext.capabilities.add: ["NET_ADMIN"]` to modify iptables. The migration to `restricted` would forbid this. Walk the response.

    The workload is a CNI plugin that needs to modify iptables rules. `NET_ADMIN` is required for the operation. The migration to `restricted` would require removing the capability.

  4. Q4. Name the one capability that PSS `restricted` allows to be added, and explain why.

Passing score: 75%. Answers are checked in this browser.

Production discipline

Linux capabilities are the kernel’s mechanism for splitting root privileges. A defensible capabilities programme drops ALL by default and adds only what is needed. The PSS restricted profile requires drop: ["ALL"] and allows only NET_BIND_SERVICE to be added. A container with drop: ["ALL"] has no capabilities; a container escape attempt cannot mount filesystems, trace processes, or bypass file checks. The discipline is to default to drop ALL, document every add, and audit the capabilities quarterly. A cluster whose containers all have drop ALL has a kernel-level security programme that is auditable.