
Kubernetes v1.37 introduces bind mount options and emptyDir permission modes, letting teams enforce noexec, nosuid, nodev, and sticky‑bit settings directly in pod specs. This outline covers the Linux basics, motivation, activation steps, example manifests, and verification techniques.
Linux Foundations: Bind Mount Flags and Sticky Bit
When managing Linux filesystems, Virtual File System (VFS) bind mount flags and directory permission modes serve as foundational controls for securing shared resources. These mechanisms allow administrators to override default behaviors at the kernel level, effectively mitigating risks associated with untrusted binary execution and unauthorized file manipulation within shared storage.
VFS Bind Mount Flags
Bind mount flags restrict operations on a specific filesystem mount point, regardless of the underlying object's permissions. These flags are critical for hardening workloads by enforcing security policies at the boundary of a container or process namespace:
- noexec: Disallows the direct execution of binaries. Even if a file is marked executable (e.g., via
chmod +x), the kernel will deny execution, preventing the runtime of arbitrary malicious payloads. - nosuid: Prevents the set-user-identifier (set-uid) and set-group-identifier (set-gid) bits from being honored. This effectively mitigates privilege escalation vectors that rely on executing binaries with elevated permissions.
- nodev: Prevents the interpretation of character or block special device files. This ensures that a compromised process cannot interact with raw hardware devices via the mounted filesystem.
The Unix Sticky Bit (01777)
While standard permissions (Read, Write, Execute) manage access scope, the sticky bit (mode 01777) provides granular control over file deletion in shared directories. When applied to a directory, the kernel restricts file removal and renaming: only the file owner, the directory owner, or the root user may delete or move a file. This is the standard security configuration for shared scratch spaces like /tmp, as it prevents non-privileged processes from deleting files they do not own, even if the directory itself is globally writable.
By implementing these flags and modes—such as configuring an emptyDir volume with noexec or the 01777 mode—engineers can enforce the principle of least privilege, ensuring that multi-tenant or multi-container pods cannot interfere with one another's data or execute unauthorized binaries within shared writable volumes.
Why Bind Mount Options and emptyDir Modes Matter in Kubernetes
Kubernetes pods have always relied on the container runtime to bind‑mount volumes into the container’s filesystem namespace. Prior to the introduction of the VolumeBindMountOptions and EmptyDirVolumeMode feature gates, those bind mounts were created without the noexec, nosuid, or nodev flags. At the same time, the emptyDir volume type always instantiated its directory with a hard‑coded mode of 0777. Both defaults break the principle of least privilege and conflict with security baselines such as NIST SP 800‑53, ISO 27001 A.12.1, and SOC 2 CC6.1, which require that writable storage be protected against execution of untrusted code and unauthorized file removal.
Audit findings illustrate the practical impact:
- Issue #48912 documented the “inability to set mount options on
emptyDir” as a high‑severity gap. - Issue #119627 (Kubernetes 1.24 Security Audit, Finding NCC‑E003660‑7HM) called the missing
noexecflag on writable volumes a “security failure”. - These reports noted that a compromised container could download a binary to any writable volume,
chmod +xit, and execute it even whenreadOnlyRootFilesystem: truewas enforced.
Without the sticky bit (mode 01777) on emptyDir, any process that can discover the shared directory can delete or rename files owned by another container. This enables cross‑container data‑wiping attacks in multi‑container pods such as CI/CD runners or sidecar‑based loggers.
Practical illustration – attempting to run a script on a volume mounted without noexec:
# kubectl exec -it pod -- sh
cd /tmp
echo '#!/bin/sh' > test.sh
chmod +x test.sh
./test.sh # → sh: ./test.sh: Permission denied (when noexec is set)
And a sticky‑bit enforcement example:
# kubectl exec -it pod -- sh
ls -ld /tmp # drwxrwxrwt …
su -s /bin/sh -c "touch /tmp/guest_file" guest
su -s /bin/sh -c "rm /tmp/guest_file" nobody # → Operation not permitted
By applying bindMountOptions: [noexec, nosuid, nodev] and configuring emptyDir: { mode: 01777 }, engineers can align pod storage with established hardening guidelines, prevent arbitrary binary execution, and protect shared scratch space from accidental or malicious deletion—all without resorting to init‑container work‑arounds.
Enabling the Alpha Features in v1.37
Kubernetes v1.37 introduces two Alpha feature gates—VolumeBindMountOptions and EmptyDirVolumeMode—that allow bind‑mount flags (e.g., noexec, nosuid, nodev) and explicit permission bits (including the sticky bit) on emptyDir volumes. Because they are Alpha, the gates must be enabled on both the API server and the kubelet before any pod can reference the new fields.
- API server: start the server with
--feature-gates=VolumeBindMountOptions=true,EmptyDirVolumeMode=true. The flag is evaluated at admission time, so the API server will reject manifests that containbindMountOptionsormodewhen the gates are off. - Kubelet: use the same
--feature-gatesflag on each node. The kubelet validates the pod spec after it is scheduled and will refuse to start a pod that requests the Alpha fields on a node where the gates are disabled.
Enabling the gates alone is insufficient; the underlying container runtime must also support the CRI mount_options field. Runtimes advertise this capability via the runtimeFeatures API. If the runtime does not list MountOptions, the kubelet will reject the pod with a clear error, and the scheduler will avoid placing the pod on such nodes because the node’s feature set is reported in the NodeStatus object.
Practical steps for a cluster administrator:
- Verify runtime support:
and consult the runtime’s documentation for CRIkubectl get node -o jsonpath='{.status.nodeInfo.runtimeVersion}'mount_optionssupport. - Update the API server manifest (or static pod) to include the feature‑gate flag.
- Restart the API server, then update each kubelet configuration with the same flag and restart the kubelet.
- Confirm the node reports the feature:
kubectl get node <node-name> -o yaml | grep -i mount_options
Example pod manifest using both features:
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
When the cluster meets the gate and runtime requirements, the kubelet enforces noexec/nosuid at the bind‑mount level and applies the sticky‑bit mode to the emptyDir, providing native compliance with hardening benchmarks such as CIS Kubernetes and NIST SP 800‑190.
Practical Manifest Examples: Noexec/Nosuid and Sticky Bit
Kubernetes v1.37 introduces bindMountOptions and an emptyDir.mode field that let platform engineers enforce Linux‑level hardening directly in a pod manifest. The options map to VFS mount flags (noexec, nosuid, nodev) while the mode value follows standard Unix permission notation, where 01777 adds the sticky bit (t) to a writable directory. Both features are gated behind VolumeBindMountOptions and EmptyDirVolumeMode and require the container runtime to expose the CRI mount_options capability.
Example 1 – Bind mount options on an emptyDir
apiVersion: v1
kind: Pod
metadata:
name: hardened-bindmount-pod
namespace: default
spec:
os:
name: linux
containers:
- name: hardened-app
image: alpine:latest
command: ["sleep","3600"]
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: temp-storage
mountPath: /tmp
bindMountOptions:
- noexec
- nosuid
volumes:
- name: temp-storage
emptyDir: {}
- readOnlyRootFilesystem: keeps the container image immutable; the writable
/tmpis the only mutable location. - bindMountOptions: applies the
MS_NOEXECandMS_NOSUIDflags to the bind mount, preventing execution of binaries and ignoring set‑uid/set‑gid bits. - emptyDir: {}: creates a node‑local directory with the default
0777permissions; the mount flags provide the security hardening.
Example 2 – Sticky‑bit emptyDir mode
apiVersion: v1
kind: Pod
metadata:
name: hardened-emptydir-pod
namespace: default
spec:
os:
name: linux
containers:
- name: app-container
image: alpine:latest
command: ["sleep","3600"]
volumeMounts:
- name: shared-tmp
mountPath: /tmp
volumes:
- name: shared-tmp
emptyDir:
mode: 01777
- mode: 01777: sets the directory permissions to
rwxrwxrwt, enabling the sticky bit so only a file’s owner (or root) may delete or rename it. - volumeMounts.mountPath: exposes the hardened directory at
/tmpfor all containers in the pod. - emptyDir: works with any medium (disk, memory, HugePages) and now respects the explicit mode without requiring an init container.
After deployment, kubectl exec into each pod to verify the enforcement: attempts to run a script in the first pod are blocked with “Permission denied”, and ls -ld /tmp in the second pod shows the trailing t indicating the sticky bit is active.
Verification and Real‑World Use Cases
Before testing enforcement, understand the underlying Linux mechanisms. A bind mount can be created with the noexec flag, which sets the MS_NOEXEC attribute on the mount point, preventing the kernel from executing any file located on that filesystem. The sticky bit (mode 01777) on a directory restricts deletion or renaming of files to the file’s owner or to root, a behavior commonly relied upon for shared /tmp spaces.
To verify that a pod respects noexec, use kubectl exec to create an executable script on a volume that was declared with bindMountOptions: [noexec, nosuid]. The expected outcome is a “Permission denied” error from the shell, confirming that the kernel rejected execution at the mount level.
# Exec into the pod
kubectl exec -it hardened-bindmount-pod -- sh
# Create a script on /tmp
cd /tmp
printf '#!/bin/sh\n echo "Running untrusted code"\n' > test.sh
chmod +x test.sh
# Attempt execution
./test.sh
# → sh: ./test.sh: Permission denied
To confirm sticky‑bit enforcement, inspect the directory mode and attempt cross‑user deletion. The directory should display the trailing t (e.g., drwxrwxrwt), and a user other than the file’s owner must receive an “Operation not permitted” error when trying to remove the file.
# Exec into the pod
kubectl exec -it hardened-emptydir-pod -- sh
# Verify mode
ls -ld /tmp
# → drwxrwxrwt 2 root root ...
# Create a file as user "guest"
su -s /bin/sh -c "touch /tmp/guest_file" guest
# Attempt removal as user "nobody"
su -s /bin/sh -c "rm /tmp/guest_file" nobody
# → rm: can't remove '/tmp/guest_file': Operation not permitted
Common enterprise scenarios that benefit from these controls include:
- Securing temporary workspaces: Mount
emptyDirwithnoexecandnosuidto prevent a compromised process from executing payloads downloaded to a writable directory. - Multi‑container CI/CD pods: Apply
mode: 01777to anemptyDirshared between a builder and a logger. Each container can write its artifacts, but the sticky bit stops one container from deleting another’s files, preserving build integrity. - Database temporary storage: Use
mode: 0750on anemptyDirthat holds a database’s temp files. Only the database user and its group can read/write, enforcing the principle of least privilege for side‑car containers such as monitoring agents.
When deploying these features, remember they are gated behind the VolumeBindMountOptions and EmptyDirVolumeMode alpha flags. Enable the flags on the API server and kubelet, verify runtime support for the CRI mount_options field, and test with kubectl exec as shown to ensure compliance with standards such as SOC 2, ISO 27001, or NIST 800‑53, which require demonstrable control over executable media and file‑system permissions.
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.
