Executive Summary
Kubernetes v1.37 shipped two alpha features that give you control over how writable volumes arrive inside a container. VolumeBindMountOptions applies the Linux bind mount flags noexec, nosuid and nodev to the mount the container runtime creates. EmptyDirVolumeMode sets the permission mode on an emptyDir volume, including the sticky bit.
The gap these close is old and specific. Volumes always reached the container executable, so a compromised process could use any writable mount to stage and run a binary, even with a read only root filesystem. emptyDir was the worst of it, creating directories at 0777 with no supported way to change that. External auditors called the missing noexec option a security failure in the Kubernetes 1.24 review. That finding now has a fix, on Linux, behind a feature gate.
Kubernetes has shipped the same hardening advice for years. Set a read only root filesystem, drop capabilities, run as non root. Most teams do all three. None of it stops a process from writing to a mounted volume and running what it wrote there.
v1.37 addresses that with two new fields. A volumeMounts entry now takes bindMountOptions, and an emptyDir volume now takes a mode. Both are alpha. Both are off by default.
A writable volume was never the boundary you thought it was
Volumes get bind mounted into containers by kubelet and the container runtime. Nothing applied noexec, nosuid or nodev to that mount unless you had a way to ask. For the bind mount the runtime creates inside the container, you did not.
The practical result is worth spelling out. A container that sets readOnlyRootFilesystem cannot write to its own filesystem. It can still write to /tmp, to an emptyDir, or to a PersistentVolume. From there a compromised process stages a payload and runs it. The root filesystem held. The workload was still owned.
The same problem shows up in multi container pods. Two containers share an emptyDir. Either one can delete the other’s files, because the directory is 0777 and nothing distinguishes the owner. Unix solved this in the 1980s with the sticky bit. Kubernetes had no way to set it.
emptyDir carried a hardcoded 0777 for a decade
emptyDir is the most common writable volume in Kubernetes. It is what you get when you mount scratch space, and what a lot of charts reach for by default. It also created every directory at mode 0777, hardcoded, with no field to change it.
Two upstream issues tracked the problem. One of them came out of the Kubernetes 1.24 security review, where external auditors stated plainly that mounting emptyDir without noexec is a security failure. The other flagged the missing mount options and sat open.
The v1.37 answer splits into two fields that do different jobs. emptyDir.mode sets the permission mode at creation. Set 01777 and the shared scratch space behaves like /tmp, where each container writes freely and none can delete another’s files. Set 0750 and only the owning user and group get in. bindMountOptions then handles the flags on the mount itself, and it works across emptyDir, PersistentVolumes, CSI volumes, projected volumes, ConfigMaps and Secrets.
The two are not interchangeable. A PersistentVolume already has a mountOptions field, but those flags go to the CSI driver at the storage layer. They do not become bind mount flags inside the container. The new field covers that layer.
Check your runtime before you turn the gates on
Both features are alpha in v1.37. You enable them with the VolumeBindMountOptions and EmptyDirVolumeMode feature gates on the API server and kubelet. KEP-5855 covers the bind mount work. KEP-5502 covers the emptyDir mode.
Three things to check first. The container runtime has to support the CRI mount_options field and advertise it through runtimeFeatures. The scheduler then uses node declared features to keep pods off nodes that cannot honor the request, and if a pod lands on one anyway, kubelet rejects it. No silent degradation, which is the right call and also means a bad rollout looks like a scheduling failure rather than a security warning.
Second, fsGroup wins. If your pod security context sets fsGroup, the group permissions it applies override the mode you set on emptyDir. Third, none of this applies to Windows nodes. noexec, nosuid and the Unix permission bits are Linux concepts, and the mode field is skipped entirely on Windows.
Neither field changes existing behavior. Leave them out and you get 0777 emptyDir and unflagged mounts exactly as before, which is the right default for a decade of running clusters. It also means the fix does nothing until you ask for it.
That last point is the one worth acting on. The audit finding sat open for years. Most clusters will keep running exactly as they do today until someone adds noexec and nosuid to the bindMountOptions on volumes that have no business executing anything. Almost none of them do. The CIS Kubernetes Benchmark has been asking for it the whole time.
Related reading. We looked at why Kubernetes isolation keeps breaking at the runtime layer, and at how the most used storage on Kubernetes is the one you get for free. For the observability half of the same problem, see what v1.37 changed in native histograms.
Get the next one before it is old news
Independent analysis of cloud-native infrastructure, Kubernetes and data centre economics. No vendor spin.

