On this page
Kubernetes Pod Security: Why Your AI's Container Runs as Root
Generated manifests leave containers running as root with default capabilities and a writable filesystem. Pod security settings close that gap, starting with securityContext.
Quick answer
- Without a securityContext, a container runs as whatever user the image specifies — frequently root.
- Root inside a container with a writable filesystem and default capabilities is a short path to compromising the node.
- The high-value settings are runAsNonRoot, a numeric runAsUser, allowPrivilegeEscalation: false, dropped capabilities, and a read-only root filesystem.
- The image has to cooperate: it must define a non-root user and not depend on writing outside its data volume.
- Pod Security Standards let you enforce a baseline across a namespace instead of auditing manifests one by one.
What is pod security?
Pod security is the set of controls that limit what a container can do to the host it runs on. A container is an isolated process, not a virtual machine, so a process running as root inside it that escapes, or that holds dangerous Linux capabilities, is materially closer to root on the node. Kubernetes exposes these controls through securityContext fields on the pod and container, and through admission policies that require certain values.
What does a secure securityContext look like?
The settings below cover the common cases: run as a non-root user, forbid privilege escalation, drop Linux capabilities, and make the root filesystem read-only. A read-only root filesystem forces the application to write only to explicitly mounted volumes, which both hardens the container and tends to surface hidden dependencies on writable paths.
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
containers:
- name: app
image: ghcr.io/acme/app:1.0.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}Why do AI-generated containers run as root?
Because the shortest Dockerfile that builds does not create a user, and the shortest manifest does not set a securityContext. The container starts as root, the app works, and nothing in the deployment output looks wrong. This is a default, not a decision — and it is the most common reason a small container escape has a large blast radius. Fixing it usually takes three changes: a USER line in the image, a securityContext in the manifest, and a writable volume for the paths the app actually needs.
How do I enforce this across a namespace?
Pod Security Standards define three levels — privileged, baseline, and restricted — and you apply them to a namespace with a label. Baseline blocks the obviously dangerous options; restricted enforces non-root, dropped capabilities, and a hardened security context. Applying restricted to application namespaces turns the requirement from a review item into an admission check, so a future generated manifest that would run as root is rejected at apply time rather than discovered later.
Where this bites vibecoders
Running as root is the default that generated artifacts almost never override, because the app works this way and the change requires touching both the image and the manifest. The result is a fleet of containers where a single application vulnerability — a dependency with an RCE, a command injection in an upload handler — inherits root inside the container, default capabilities, and a writable filesystem. Hardening the security context does not fix the vulnerability, but it changes what exploiting it is worth.
Where AI coding assistants get this wrong
- Omitting securityContext entirely, leaving containers as the image’s default user.
- Building images without a USER directive, so the default is root.
- Setting readOnlyRootFilesystem without adding a writable volume for /tmp or cache paths.
- Granting capabilities the app does not need, or running as privileged ‘to make it work’.
- Assuming namespace isolation alone prevents a container from affecting the host.
Checklist
- Create a non-root user in every image and set USER.
- Set runAsNonRoot and a numeric runAsUser in the pod spec.
- Set allowPrivilegeEscalation: false and drop all capabilities.
- Use a read-only root filesystem and mount writable volumes explicitly.
- Never run privileged containers for application workloads.
- Enforce the restricted Pod Security Standard on application namespaces.
FAQ
What happens if a container runs as root?
The process has root privileges inside the container. Combined with default capabilities, a writable filesystem, and any kernel or runtime vulnerability, that makes escaping to the node far easier. It also means file ownership issues are masked, so an app may only work as root by accident.
Will readOnlyRootFilesystem break my app?
It can, if the app writes to its own directory, a cache path, or /tmp. The fix is to mount emptyDir volumes at those paths. The breakage is informative: it reveals writes you did not know about.
What are Pod Security Standards?
Three built-in policy levels — privileged, baseline, and restricted — that Kubernetes can enforce per namespace. Restricted requires non-root execution, dropped capabilities, and a hardened security context, which makes secure defaults the path of least resistance instead of an ongoing review task.
Related topics
- Kubernetes Security for AI Builders: Hardening the Cluster Your Assistant Configured
- The Kubernetes Security Checklist for AI-Built Clusters
- How to Write a Secure Dockerfile
- What Is Kubernetes RBAC (and What Did Your AI Grant Away)?
- Why Do My Containers Keep Getting Killed (OOMKilled)?
- Kubernetes for AI Builders: Run What Your Assistant Generates Without Wrecking Production