Set readOnlyRootFilesystem to true on each container and mount small writable volumes, such as emptyDir, for the paths the application must write. An attacker who gets code execution then cannot easily modify binaries or drop tools into the image filesystem. It does not stop everything, so use it with the other hardening settings.
What the setting does
The Kubernetes security context docs describe readOnlyRootFilesystem as mounting the container's root filesystem as read-only, with any writable paths provided by volumes. It is a container level field.
containers:
- name: app
image: registry.example.com/app:1.4.2
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/app
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
The emptyDir volume is one of the volume types the Restricted standard allows.
Steps to roll it out
- Turn it on in a test environment.
- Run the app and its tests. Read the logs for errors such as read-only file system.
- Note each path that fails. Typical ones are tmp, a cache folder, a PID file location and a framework working directory.
- Add an emptyDir mount for each path.
- Repeat until clean, then ship.
Many images write to a handful of places, so the list is usually short. Where configuration files must be generated at start, generate them in a writable mount or at image build time.
Common failures
Application cannot start because it writes a lock or PID file: mount a writable directory there and, if the app allows, configure its path.
Package manager or updater runs at start: this is an image smell. Bake dependencies into the image at build time.
Language runtimes writing compiled caches: point the cache directory to an emptyDir through an environment variable, if the runtime supports it.
Writable data that must survive restarts: use a PersistentVolumeClaim, not the container filesystem.
What it does and does not do
It makes tampering with the image filesystem harder, and it makes unexpected writes visible as failures. It does not block writes to the mounted volumes, memory only attacks, or network activity. An attacker can still run code that is already in the image or loaded in memory, and can write to emptyDir paths.
That is why it belongs next to non-root users, dropped capabilities and a seccomp profile. The whole set is in the securityContext checklist.
A smaller image with fewer tools in it also helps, since there is less to run once an attacker is inside.
Order of rollout
Start with stateless web services, which usually need only tmp. Move to workers and batch jobs next. Leave databases and legacy applications for last, since they write in many places. For each service, record the writable paths you added so the next engineer knows why they exist.
Quick check
Does read-only root block writes to mounted volumes?
No. Only the container's own root filesystem is read-only. Volumes keep their own mode.
Is this required by Pod Security Standards?
The fetched pages do not list it among the Restricted requirements, so treat it as extra hardening.
Sources
- Configure a Security Context for a Pod or Container, Kubernetes documentation
- Pod Security Standards
Last reviewed: 19 October 2026.