How to Harden a Kubernetes Pod With a securityContext
A container securityContext is the first line of pod hardening in Kubernetes: drop every Linux capability, forbid privilege escalation, force a non-root user, and make the filesystem read-only. Four fields, applied once, that shrink the blast radius of a compromise.
Why containers are insecure by default
Without a securityContext, a Kubernetes container runs as root (UID 0), has
a writable root filesystem, can acquire new privileges via setuid binaries, and
holds the full set of Linux capabilities (including NET_ADMIN, SYS_ADMIN,
and others that can break out of weak sandboxes). If the application process is
exploited, the attacker starts with maximum access inside the container.
The four fields that matter
Add a securityContext to the container spec in your Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
spec:
containers:
- name: worker
image: busybox:1.36
command: ["sleep", "86400"]
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
Apply it and confirm the rollout:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/worker
What each field does
runAsNonRoot: true- Kubernetes rejects the pod at admission if the container image's default user is root. Pair it withrunAsUser: 1000(a non-zero UID) to set the user explicitly.allowPrivilegeEscalation: false- Blocks theno_new_privskernel flag from being cleared, so setuid/setgid binaries inside the container cannot grant the process more privileges than it started with.readOnlyRootFilesystem: true- Mounts the container's root filesystem read-only. An attacker who achieves code execution cannot write tools, backdoors, or modified binaries. If the app needs writable scratch space, mount anemptyDirvolume at the specific path.capabilities.drop: ["ALL"]- Strips every Linux capability that containers receive by default (CHOWN,NET_BIND_SERVICE,SETUID, etc.). Add back only what the app genuinely needs withcapabilities.add.
Verify the hardening
# confirm the container is running as a non-root user
kubectl exec deployment/worker -- id
# uid=1000 gid=0
# confirm the filesystem is read-only
kubectl exec deployment/worker -- touch /test 2>&1
# touch: /test: Read-only file system
Pod Security Standards
These four fields together satisfy the restricted level of Kubernetes
Pod Security Standards
- the strictest built-in policy. Security audits and compliance tools (kube-bench,
Trivy, Checkov) all flag containers missing these settings as high-severity findings.
Setting them is the highest-signal, lowest-effort hardening step on any production workload.
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Writing a container securityContext with non-root user, readOnlyRootFilesystem, and capabilities.drop: [ALL]
- Applying and rolling out a hardened Deployment with kubectl
- Verifying hardening with kubectl exec (id, filesystem write test)
FAQ
What does securityContext do in Kubernetes?
A securityContext configures Linux security settings on a pod or container - things like which user the process runs as, whether it can gain new privileges, whether the filesystem is writable, and which Linux capabilities it holds. It is the primary mechanism for hardening a container at the Kubernetes level.
How do I run a Kubernetes container as non-root?
Set runAsNonRoot: true and runAsUser: <non-zero UID> in the container's securityContext. Kubernetes will reject the pod at admission if the image's default user is root and runAsNonRoot is true, so pair both fields together.
What is allowPrivilegeEscalation in Kubernetes?
It controls whether a process inside the container can gain more privileges than its parent - for example via a setuid binary. Setting allowPrivilegeEscalation: false sets the no_new_privs kernel flag, preventing any privilege increase regardless of file permissions.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →