
Kubernetes v1.37 introduces granular control over volume security through bind mount flags and configurable EmptyDir permissions. This guide explores how to leverage these features to prevent privilege escalation and enforce strict access controls within your containerized workloads.
The Security Gap: Why Writable Volumes Need Hardening
Historically, Kubernetes mounted every writable volume (emptyDir, PersistentVolume, ConfigMap, etc.) with the default Linux permissions 0777 and without any bind‑mount flags. The container runtime performed a simple bind‑mount, so the VFS flags noexec, nosuid and nodev were absent. This default created two concrete attack surfaces:
- Any process that could write to the volume could also set the executable bit and run the binary, even when the pod’s root filesystem was declared read‑only (
readOnlyRootFilesystem: true). - Shared writable directories lacked the sticky bit (mode 01777). Consequently, a container could delete or rename files owned by another container, violating the principle of least privilege in multi‑container pods.
Because emptyDir volumes are the most common temporary storage, the gap was repeatedly highlighted in security audits (e.g., NCC‑E003660‑7HM). The default 0777 mode meant that “any process that discovers the mount can read, write, and delete anything,” and there was no native way to enforce noexec or the sticky bit without an init container that manually runs chmod.
With Kubernetes v1.37 the VolumeBindMountOptions and EmptyDirVolumeMode feature gates expose the missing controls. The following manifest demonstrates a hardened emptyDir that blocks execution and enforces the sticky bit:
apiVersion: v1
kind: Pod
metadata:
name: hardened-pod
spec:
containers:
- name: app
image: alpine:latest
command: ["sleep","3600"]
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: work
mountPath: /tmp
bindMountOptions: [noexec, nosuid]
volumes:
- name: work
emptyDir:
mode: 01777
Running kubectl exec -it hardened-pod -- sh and attempting to execute a script placed in /tmp yields “Permission denied” because the kernel enforces MS_NOEXEC on the bind mount. Likewise, a second user cannot delete a file owned by another user, as the directory listing shows drwxrwxrwt (the trailing t indicates the sticky bit).
These mechanisms close the historic gap: they prevent arbitrary code execution from writable volumes and ensure that shared scratch space respects ownership boundaries without resorting to complex init‑container workarounds.
Core Concepts: Linux VFS Flags and Directory Permissions
When the Linux kernel mounts a directory, the Virtual File System (VFS) layer attaches a set of mount flags that constrain how processes can interact with the underlying filesystem. The three most relevant flags for container hardening are noexec, nosuid, and nodev:
noexec– the kernel sets the MS_NOEXEC flag on the mount; any attempt to execute a binary directly from that filesystem results inPermission denied, even if the file’s executable bit is set.nosuid– the MS_NOSUID flag disables the effect of set‑user‑ID and set‑group‑ID bits, preventing privilege escalation through binaries that would otherwise run with elevated UID/GID.nodev– the MS_NODEV flag tells the VFS not to interpret character or block device nodes, eliminating the risk of a container creating or accessing raw devices via the mount.
These flags are applied at mount time, not at the file‑system level, so they affect bind‑mounted volumes inside containers without altering the underlying storage driver.
Directory permissions follow the traditional Unix model (owner, group, others) expressed as octal modes such as 0755 or 0777. The sticky bit, represented by the high‑order octal 1 (e.g., 01777), adds a special “t” flag to directories. When set, a file inside the directory can be removed or renamed only by its owner, the directory’s owner, or root. This behavior is essential for shared writable directories like /tmp, where multiple users must coexist without being able to delete each other’s files.
In Kubernetes v1.37 the VolumeBindMountOptions and EmptyDirVolumeMode feature gates expose these VFS mechanisms directly to pod specifications. Example bind‑mount options:
volumeMounts:
- name: temp-storage
mountPath: /tmp
bindMountOptions:
- noexec
- nosuid
Example emptyDir with the sticky bit:
volumes:
- name: shared-tmp
emptyDir:
mode: 01777
Trade‑offs to consider:
- Enabling
noexecblocks legitimate use cases such as in‑container build tools that need to compile and run binaries on a writable volume. nosuidmay interfere with applications that rely on set‑uid helpers for internal privilege separation.- Setting the sticky bit (
01777) does not prevent a privileged container (UID 0) from deleting files; it only protects against non‑root users.
Understanding these low‑level flags allows engineers to align container storage with hardening benchmarks, reducing the attack surface while preserving required functionality.
Implementation Guide: Enforcing Bind Mount Options
In Kubernetes v1.37, the introduction of bindMountOptions and granular emptyDir permissions provides a native mechanism to enforce Linux VFS-level security flags directly within Pod specifications. These features mitigate common privilege escalation vectors where attackers leverage writable volumes to store and execute unauthorized binaries.
By default, volumes are mounted without restrictive flags, allowing processes to bypass readOnlyRootFilesystem configurations. The bindMountOptions field allows operators to explicitly apply kernel-level restrictions to these mounts.
Applying Bind Mount Options
The bindMountOptions field accepts standard mount flags such as noexec (disallows binary execution) and nosuid (ignores set-user-identifier bits). This ensures that even if a payload is written to a volume, the Linux kernel will deny execution at the syscall layer.
apiVersion: v1
kind: Pod
metadata:
name: hardened-bindmount-pod
spec:
containers:
- name: app
image: alpine
volumeMounts:
- name: scratch-space
mountPath: /tmp
bindMountOptions:
- noexec
- nosuid
volumes:
- name: scratch-space
emptyDir: {}
Enforcing Directory Permissions
Previously, emptyDir volumes defaulted to 0777 permissions, creating significant multi-tenancy risks within pods. The mode field now supports POSIX permission sets, including the sticky bit (01777), which prevents unauthorized users from deleting files they do not own—essential for shared /tmp directories.
- Security hardening: Setting
mode: 0750restricts access strictly to the owner and group, following the principle of least privilege. - Shared workspace integrity: Applying
mode: 01777ensures that while multiple sidecars can write to a shared volume, file ownership is respected for deletion operations.
Operational Considerations:
- Feature Gates: Both
VolumeBindMountOptionsandEmptyDirVolumeModeare Alpha features in v1.37 and require enablement on the API server and kubelet. - Runtime Dependencies:
bindMountOptionsrequires the underlying container runtime to support the CRImount_optionsfield. - Validation: If a node lacks the capability to satisfy the requested mount options, the kubelet will reject the Pod, preventing silent security degradation.
Securing Shared Workspaces with EmptyDir Permissions
In Kubernetes v1.37 the emptyDir volume type gains two orthogonal controls that let platform engineers enforce least‑privilege storage semantics inside multi‑container pods: the mode field, which sets POSIX permissions (including the sticky bit), and bindMountOptions, which applies VFS flags such as noexec, nosuid and nodev to the bind‑mount that presents the volume to each container.
When a pod omits these fields the kubelet creates the backing directory with mode 0777 and mounts it without any restrictive flags. This default permits any container that can reach the mount point to read, write, delete, or execute files arbitrarily—a common source of privilege‑escalation findings (e.g., NCC‑E003660‑7HM). By explicitly configuring the fields, the same volume can be hardened to match the principle of least privilege.
- Sticky‑bit mode (01777) – Guarantees that a file can be removed only by its owner or root, mirroring the behaviour of
/tmp. This is essential when several containers share a scratch space (builder, logger, sidecar) and must not be able to delete each other’s artifacts. - Restrictive bind‑mount flags –
noexecblocks execution of binaries on the mount,nosuiddisables set‑uid/set‑gid bits, andnodevprevents creation of device nodes. Together they stop a compromised process from turning a writable volume into an execution sandbox.
Example manifest that combines both mechanisms:
apiVersion: v1
kind: Pod
metadata:
name: hardened-workspace
spec:
os:
name: linux
containers:
- name: builder
image: alpine:latest
command: ["sleep","3600"]
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: shared-tmp
mountPath: /tmp
bindMountOptions:
- noexec
- nosuid
volumes:
- name: shared-tmp
emptyDir:
medium: "" # disk‑backed
mode: 01777 # sticky bit + rwx for owner/group/others
Verification steps (run with kubectl exec) demonstrate the enforcement:
- Attempting
./test.shon thenoexecmount yields “Permission denied”. - Listing
/tmpshowsdrwxrwxrwt, confirming the sticky bit. - Deleting a file owned by another user fails with “Operation not permitted”.
Key trade‑offs:
- Enabling these flags requires the
VolumeBindMountOptionsandEmptyDirVolumeModealpha feature gates on the API server and kubelet. - All container runtimes must advertise support for the CRI
mount_optionsfield; otherwise the pod is rejected at scheduling time. - Setting a restrictive
modedoes not affect the underlying storage medium (disk, tmpfs, HugePages) – the same semantics apply across allemptyDirtypes.
By combining mode: 01777 (or tighter values such as 0750) with bindMountOptions, engineers can construct shared workspaces that are both functionally convenient and compliant with hardened security baselines.
Validation and Runtime Requirements
To implement hardened storage in Kubernetes v1.37, you must ensure the cluster control plane and node runtimes support the requisite Alpha feature gates: VolumeBindMountOptions and EmptyDirVolumeMode. Verification of these configurations is conducted at the Linux kernel layer, specifically by auditing the Virtual File System (VFS) mounts and inode permissions within the container runtime environment.
The verification process utilizes kubectl exec to validate security posture against the kernel's enforcement of bind mount flags and directory permission bits:
noexecenforcement: WhenbindMountOptionsincludesnoexec, the kernel prevents the execution of binaries directly from the mount point. Even withchmod +xapplied, attempting to execute a script via./test.shwill trigger aPermission deniederror.- Sticky bit (
01777) validation: Verification requires switching users within the container. By creating a file as one user and attempting to unlink it as another, you can confirm that the VFS honors the sticky bit; the kernel will returnOperation not permittedif the deletion attempt violates owner-based constraints.
Runtime and Architectural Requirements:
Successful deployment of these features depends on tight integration between the Kubelet and the underlying container runtime interface (CRI). For bindMountOptions, the following architectural dependencies apply:
- CRI Compatibility: The container runtime must explicitly support the
mount_optionsfield within the CRI and broadcast this capability viaruntimeFeatures. - Node Scheduling: The scheduler performs capacity and capability checking. If a Pod requests
bindMountOptionson a node where the runtime does not expose the necessary features, the Kubelet will reject the Pod admission request rather than failing silently. - Volume Scope: These options apply to the bind mount generated for the container. Unlike CSI-level
mountOptions, which act at the storage driver layer during block device attachment, these flags govern the VFS view inside the container mount namespace.
Conversely, EmptyDirVolumeMode is managed directly by the Kubelet during volume provisioning. As this operates on the directory creation logic before the volume is mounted, it does not require specialized runtime support or feature negotiation at the CRI level.
Production Considerations and Feature Gates
In Kubernetes v1.37, the introduction of VolumeBindMountOptions and EmptyDirVolumeMode addresses long-standing security gaps regarding container storage hardening. These features allow operators to enforce Linux-level restrictions—specifically noexec, nosuid, and nodev—on volume mounts, as well as define POSIX permission modes (including the sticky bit) for emptyDir volumes. Both features are currently in Alpha status, meaning they are disabled by default and require explicit configuration at the cluster level.
To leverage these capabilities, you must enable the corresponding feature gates on both the API server and the Kubelet. The configuration requires the following flags:
--feature-gates=VolumeBindMountOptions=true,EmptyDirVolumeMode=true
From an architectural perspective, VolumeBindMountOptions shifts security enforcement from post-deployment container configuration (such as using init containers to perform chmod) to the native container runtime layer. By utilizing the bindMountOptions field in a Pod manifest, you instruct the Kubelet to apply specific Virtual File System (VFS) flags during the mount process. Because these are applied as bind mount flags, they effectively restrict the scope of action for any process, even if the container executes with elevated privileges or has a writable root filesystem.
Consider the following manifest implementation for enforcing execution restrictions:
spec:
containers:
- name: hardened-app
volumeMounts:
- name: temp-storage
mountPath: /tmp
bindMountOptions:
- noexec
- nosuid
volumes:
- name: temp-storage
emptyDir: {}
Critical trade-offs and operational requirements include:
- Runtime Requirements: The container runtime must support the Container Runtime Interface (CRI)
mount_optionsfield. If a node does not advertise these runtime capabilities, the Kubelet will reject the Pod during the admission phase, preventing silent misconfiguration. - Backward Compatibility: If these fields are omitted, the system reverts to legacy default behaviors, such as
0777permissions foremptyDir. - Scope: While
bindMountOptionsapplies to most volume types—including CSI volumes, Secrets, and ConfigMaps—it remains unsupported for image volumes.
Platform engineers should prioritize these gates in sandboxed environments to validate compatibility with existing CSI drivers and runtime environments before broader cluster-wide adoption.
Looking for Custom Software or AI Solutions?
Appworks Technologies designs, builds, and scales production enterprise platforms, microservices, and AI agent workflows tailored to your business goals.
Editorial Policy & Research Methodology
Our findings are based on rigorous internal research, verified industry benchmarks, and direct technical implementation experience from our enterprise client projects. All statistics and technical claims are reviewed by senior engineers before publication to ensure accuracy, transparency, and helpfulness for our readers.
