Kubernetes User Namespaces and Pod Hardening: Containing Container Escapes in 2026
Most container escape write-ups end the same way: the attacker breaks out of a container, and because the container process was root, they are now root on the node. The uncomfortable part is that nothing about the escape itself had to be exotic. A runc file-descriptor leak, a symlink race in a volume mount, a kubelet path-handling bug: each turns “root in the container” into “root on the host” because UID 0 means the same thing on both sides of the boundary.
Kubernetes user namespaces change that equation. With hostUsers: false in the pod spec, root inside the container is mapped to an unprivileged, per-pod range of IDs on the host, and the capabilities the pod holds are valid only inside its own user namespace. The feature is documented as stable as of Kubernetes v1.36, so it is no longer an experiment you need a feature gate for.
This article explains the mechanism, the node prerequisites that trip people up, how it composes with seccomp, AppArmor, Pod Security Standards and sandboxed runtimes, and where it breaks.
What this covers: how UID and GID mapping works for pods, the verified runtime and kernel requirements, runnable manifests, a defense-in-depth stack, failure modes, and a rollout checklist.
Context and Background
A Linux container is not a lightweight virtual machine. It is a process started with a set of namespaces (PID, network, mount, IPC, UTS, and optionally user and cgroup) plus cgroup limits, a capability bounding set, a seccomp filter and a Linux Security Module (LSM) profile. The kernel is shared. Every isolation property therefore depends on the kernel and the runtime enforcing the rules correctly, and every escape is, at root, a bug in that enforcement or a misconfiguration that disables it.
For years the Kubernetes default was to run containers in the host’s user namespace. A process with UID 0 in the container was UID 0 on the node, constrained only by dropped capabilities, seccomp and LSM rules. That is why the community pushed “run as non-root” as the baseline advice: if the process is not root, a breakout buys much less. The problem is that a huge amount of software still expects to be root in its container (package managers, init scripts, legacy images), and runAsNonRoot breaks them.
User namespaces resolve that tension. The Kubernetes documentation puts it plainly: a process running as root in a container can run as a different, non-root user on the host, with full privileges for operations inside the user namespace but unprivileged for operations outside it. The upstream enhancement proposal (KEP-127) lists several vulnerabilities rated HIGH or CRITICAL that were not exploitable under this model, including CVE-2019-5736 (host runc binary overwritten from a container), CVE-2021-25741 (a pod reading arbitrary host files via a subpath race), CVE-2017-1002101 and CVE-2021-30465. I cite those as the KEP’s own assessment; the mitigation depends on the specific exploit path and is not a blanket guarantee.
If you are tracking the runtime side of this problem, our guide to container runtime security hardening across containerd 2.3, CRI-O and Podman 6 covers CVE response at the runtime layer. User namespaces are the Kubernetes-level control that sits above that layer and limits the blast radius when the runtime itself has a bug. The official reference is the Kubernetes user namespaces documentation.
There is also a broader reason this matters in 2026. Clusters now run multi-tenant CI jobs, build agents, and increasingly AI agent workloads that execute model-generated code. Those workloads are the most plausible source of an adversary who can run arbitrary code inside a pod, which is exactly the threat model container escape defenses exist for.
How Kubernetes User Namespaces Contain a Compromised Pod
Setting spec.hostUsers: false tells the kubelet and container runtime to create a new Linux user namespace for the pod and map its IDs onto a private range of host IDs. Inside the pod, UID 0 exists and is fully privileged over the pod’s own resources. On the host, that same process runs as a high, non-overlapping UID with no authority over host files, other pods, or kernel-global operations.

Figure 1: Container UID 0 to 65535 is mapped onto a unique unprivileged host range per pod, and capabilities are scoped to the pod’s own user namespace.
Figure 1 shows the mapping. The kubelet assigns each pod a distinct block of IDs, and by default each block is 65,536 IDs wide (a configurable size from v1.33, covered below). The pod sees 0 to 65535; the host sees something like 833617920 to 833683455. Two pods on the same node never share a block, so a process escaping pod A cannot even match the UID of pod B’s files.
The mapping mechanism in practice
The kernel exposes the mapping in /proc/<pid>/uid_map and gid_map. Each line has three fields: the first ID inside the namespace, the first ID outside, and the length. The Kubernetes task page shows output such as 0 833617920 65536 from inside a pod, and says the last number must be 65536 inside the container while the host-side value must be a bigger number.
You can verify isolation in two commands. Inside the pod, readlink /proc/self/ns/user returns a namespace inode like user:[4026531837] that differs from the value you get on the host. That inode comparison is the cheapest, most trustworthy check that the pod really got its own user namespace.
Capabilities become local
The part that changes the threat model most is capability scoping. The Kubernetes docs give two examples: CAP_SYS_MODULE has no effect for a pod in a user namespace, so it cannot load kernel modules, and CAP_SYS_ADMIN is limited to the pod’s user namespace and invalid outside it. The mechanism is described in man 7 user_namespaces: a capability held in a non-initial user namespace only applies to resources owned by that namespace.
That makes many historic escape primitives inert. Mounting arbitrary filesystems, writing to host cgroup release agents, accessing raw devices and manipulating host network interfaces typically need capabilities in the initial user namespace. Granting CAP_SYS_ADMIN to a user-namespaced pod is still unwise, but the failure it enables is a much smaller one.
Volumes and file ownership
Pods share data through volumes, and ID mapping would normally scramble file ownership. Kubernetes avoids that with idmapped mounts. The docs state that runAsUser, runAsGroup and fsGroup always refer to the user inside the container, and that inodes created or read in a pod’s volumes are the same as if the pod did not use user namespaces.
The practical benefit is reversibility. A pod can switch hostUsers on or off without changing file ownership on its volumes, and it can share a volume with a pod that has no user namespace by setting matching in-container users. That makes staged rollouts far safer than they would be if each toggle forced a recursive chown.
Why isolation between pods improves
Without user namespaces, two pods both running as UID 1000 share an identity on the host and can read each other’s world-readable-by-UID files if a mount or path bug exposes them. With the feature on, the kubelet guarantees that no two pods on a node use the same mapping. Files with UIDs outside a pod’s mapped range appear as the overflow ID (usually 65534, configured in /proc/sys/kernel/overflowuid), and the docs note you cannot modify those files even as that user.
This is why the feature is effective against the CVE-2021-25741 class. The Kubernetes node-setup documentation explicitly names it: avoiding overlap between pod and host IDs limits what a pod can do when a bug lets it reach host files, because the pod’s UID will not match the host file owner.
Node Prerequisites and a Working Rollout Walk-through
The pod-level switch is one line. The node-level requirements are where rollouts stall, so it is worth being exact about what the Kubernetes documentation requires.
Kernel, filesystem and runtime requirements
User namespaces for pods is Linux-only and depends on idmapped mounts. The filesystem backing /var/lib/kubelet/pods/ (or your custom pod directory) must support idmap mounts, and so must every filesystem used by the pod’s volumes. In practice the docs say you need at least Linux 6.3, because tmpfs gained idmap mount support in that release, and Kubernetes uses tmpfs for service account tokens and Secrets. Filesystems listed as supporting idmap mounts on 6.3 include btrfs, ext4, xfs, fat, tmpfs and overlayfs.
The runtime stack must cooperate too. The documented minimums are crun 1.9 or later (1.13 or later recommended) or runc 1.2 or later as the OCI runtime, and containerd 2.0 or later or CRI-O 1.25 or later as the CRI runtime. Support in cri-dockerd was still tracked as an open issue in the docs I read. A fleet on containerd 1.7 will simply not honour the field, so check runtime versions before you roll out policy that depends on it.

Figure 2: Every layer from kernel to kubelet must support user namespaces and idmapped mounts, otherwise pod creation fails or the field is ineffective.
Figure 2 lays out the chain. A weak link does not degrade gracefully into “no user namespace”; the more common outcome is a pod stuck in an error state with an event from the runtime, which is at least a loud failure. The documentation shows the typical symptom: a failure to set MOUNT_ATTR_IDMAP with an invalid argument error and the hint that the filesystem may not support idmap mounts on this kernel.
Choosing the host ID range
By default the kubelet assigns pods IDs above 0 to 65535, assuming the host’s own users sit inside that range. If you need a custom range, the node must have a user named kubelet, the getsubids binary (from shadow-utils) in the kubelet’s PATH, and subordinate ID entries for that user. The documented constraints are strict: the starting ID must be a multiple of 65536 and at least 65536, the count must be a multiple of 65536 and at least 65536 x maxPods, UID and GID ranges must match, ranges must not overlap other assignments, and the configuration must be a single line.
The docs give a concrete example for the default of 110 pods per node:
# /etc/subuid and /etc/subgid
kubelet:65536:7208960
The arithmetic is simply 110 x 65536 = 7,208,960. If you raise maxPods to 250 on large nodes, the count becomes 16,384,000, so remember to update the subordinate range at the same time. The docs also warn that changing this on a node running user-namespaced pods requires draining it first, and the kubelet will fail to start if it cannot honour the new configuration for existing pods.
Tuning the pod ID count
Since Kubernetes v1.33 the number of IDs per pod is configurable in KubeletConfiguration; before that it was hard-coded at 65536. The value must be a multiple of 65536 and applies only to containers created after the kubelet starts with it.
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
userNamespaces:
idsPerPod: 1048576
Most workloads never need more than 65,536 IDs. Raise it only for workloads that run nested user namespaces, such as rootless container builders inside a pod, and remember that a larger idsPerPod multiplies the subordinate range you must reserve: one million IDs per pod across 110 pods needs 115,343,360 subordinate IDs.
A minimal opt-in and a verification loop
The upstream example is deliberately small. Applying it and then comparing namespace inodes proves the feature is active on your node.
apiVersion: v1
kind: Pod
metadata:
name: userns
spec:
hostUsers: false
containers:
- name: shell
command: ["sleep", "infinity"]
image: debian
kubectl apply -f userns.yaml
kubectl exec -ti userns -- bash -c 'id; cat /proc/self/uid_map; readlink /proc/self/ns/user'
# on the node hosting the pod
ps -eo user:20,pid,comm | grep 'sleep infinity'
Inside the pod you should see uid=0(root), a map ending in 65536, and a user namespace inode. On the host, ps shows a large numeric user rather than root. If the host shows root, the pod is not in a user namespace.
Building the Full Hardening Stack Around User Namespaces
User namespaces limit what a compromised process can do after it reaches the host boundary. They do nothing to reduce the number of ways to reach it. The right posture is layered: reduce the attack surface first, constrain the process second, and make breakout harmless third.

Figure 3: Admission policy, syscall filtering, LSM profiles, user namespaces and an optional sandbox runtime each stop a different stage of a container escape.
Pod Security Standards and the user namespace relaxation
Pod Security Standards define three profiles (Privileged, Baseline, Restricted) enforced by the Pod Security admission controller. Restricted requires, among other things, that seccompProfile.type be explicitly RuntimeDefault or Localhost, and Baseline prohibits Unconfined.
Kubernetes relaxes some of the checks for pods that set hostUsers: false. For Baseline and Restricted, the fields runAsNonRoot and runAsUser (at pod, container, init container and ephemeral container level) are not checked, because root inside the pod is never a privileged host user. For Baseline, procMount validation is also relaxed, but under Restricted a pod must still use the default or empty ProcMount. This is the headline benefit: legacy images that need to start as root can now satisfy the Restricted profile.
Be careful about reading that as permission to be sloppy. Restricted still requires allowPrivilegeEscalation: false, dropping all capabilities and a safe volume list. Keep those.
seccomp RuntimeDefault
Seccomp filters the system calls a process can make. The RuntimeDefault profile is the container runtime’s built-in allowlist, which blocks a set of dangerous or rarely needed calls while keeping typical applications working. A kubelet can also default every pod to it: the seccompDefault kubelet setting is documented as stable since v1.27, which removes the footgun of an unset profile.
Seccomp and user namespaces are complementary rather than redundant. Many kernel exploits need to create nested namespaces or call rarely used system calls to reach a vulnerable code path. Container runtimes’ default profiles generally deny namespace-creating calls unless a privileged capability is present, but the exact allowlist differs by runtime and version, so read the profile your runtime ships rather than assuming. Restricting the syscall surface shrinks the kernel bug area an attacker can touch even before the user namespace boundary matters.
AppArmor through the securityContext field
AppArmor profiles were specified through annotations before Kubernetes v1.30; since then there is a first-class appArmorProfile field on both the pod and container securityContext. It accepts RuntimeDefault, Localhost (with a localhostProfile name) or Unconfined. AppArmor is a Linux Security Module available on Ubuntu and Debian derivatives; Red Hat family nodes use SELinux instead, so the equivalent control there is an seLinuxOptions configuration.
LSM profiles add path-based and capability mediation that is independent of UID mapping. If an exploit defeats seccomp, the LSM can still deny writes to sensitive paths under /proc and /sys.
A hardened pod manifest
The manifest below combines the controls. It would be admitted under a Restricted namespace label, runs the application as root inside a user namespace, and keeps every other restriction in place.
apiVersion: v1
kind: Pod
metadata:
name: hardened-app
labels:
app: hardened-app
spec:
hostUsers: false
automountServiceAccountToken: false
securityContext:
seccompProfile:
type: RuntimeDefault
appArmorProfile:
type: RuntimeDefault
containers:
- name: app
image: registry.example.com/team/app:1.4.2
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: "500m"
memory: "256Mi"
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Enforce the policy at the namespace level with labels so the manifest cannot drift:
kubectl label namespace payments \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
Sandboxed runtimes through RuntimeClass
For the most hostile workloads, such as untrusted tenant code or model-generated code, add a second isolation boundary with a sandboxed runtime. gVisor intercepts system calls in a user-space kernel, and Kata Containers runs each pod in a lightweight virtual machine. You select them through a RuntimeClass, whose handler field names a runtime configuration installed on the node.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
scheduling:
nodeSelector:
sandbox.example.com/runtime: gvisor
---
apiVersion: v1
kind: Pod
metadata:
name: untrusted-job
spec:
runtimeClassName: gvisor
containers:
- name: job
image: registry.example.com/ci/runner:2.1.0
The handler name runsc is gVisor’s runtime binary name, but the handler is whatever you configured in containerd or CRI-O, so verify it against your node configuration. Note that the Kubernetes docs describe user namespaces as applicable to runtimes that use Linux namespaces for isolation, and call out that Kata uses VMs instead. A VM-isolated pod gets its isolation from the hypervisor boundary, not from hostUsers, so do not assume the two stack on every runtime; test the combination you intend to run.
For the policy side of the same story in AI systems, see our notes on agentic AI security and prompt injection, where sandboxing generated code is the main blast-radius control.
Walking Through an Escape: What Each Layer Actually Stops
A layered model is only convincing if you trace an attack through it. Consider a generic scenario, illustrative rather than a specific incident. An attacker achieves code execution inside a web-facing pod through an application bug, then tries to reach the node.

Figure 4: A compromised process meets admission policy, seccomp, an LSM profile and the user namespace boundary in sequence, and each stage removes a class of escalation.
Stage one: getting out of the sandbox of the pod
The attacker first looks for a way to touch the host: a mounted container runtime socket, a writable hostPath, a privileged flag, or a shared host namespace. Pod Security admission at the Baseline level already rejects privileged containers, host namespaces and most hostPath volumes, so this stage fails on well-governed namespaces before the pod ever starts. This is why admission is first in Figure 4: it is the only control that works before runtime.
If admission is permissive, user namespaces still impose limits. A pod with hostUsers: false cannot set hostNetwork, hostPID or hostIPC, and cannot use raw block volumeDevices. The API server rejects the combination, so an operator cannot accidentally weaken the isolation by stacking those options.
Stage two: kernel attack surface
Next the attacker tries a kernel vulnerability, for example in a rarely used syscall or a filesystem driver. Seccomp RuntimeDefault blocks a share of that surface, and an AppArmor profile denies writes to sensitive procfs and sysfs paths. Neither is a complete answer because a kernel bug in an allowed call still works, which is why the final layers exist.
Suppose the attacker succeeds and obtains kernel-level code execution as the pod’s process. Under the old model, the process was UID 0 with whatever capabilities the container held. Under a user namespace, the process starts as an unprivileged UID in the initial namespace; a kernel exploit that escalates to full root is still possible but is a harder class of bug than a plain logic flaw in a runtime’s file handling.
Stage three: runtime and orchestrator bugs
The more common escape class is a flaw in runc, containerd or the kubelet that abuses file descriptors, symlinks or mounts. The KEP lists CVE-2019-5736 as completely mitigated by user namespaces, because the overwritten host runc binary is owned by a host user the container cannot map to. The reason is mechanical: the exploit needs write access to a file that the pod’s mapped UID does not own.
Compare that with a patch-only strategy. Patching closes one CVE after it is published, while user namespaces change the outcome of the next, unknown CVE of the same class. Treat them as complementary: patch quickly, and make patch latency less dangerous.
A worked sizing example
Suppose you run a 40-node cluster with a maxPods of 110 and the default 65,536 IDs per pod. Each node needs 7,208,960 subordinate IDs. Because the ranges are per node, there is no cluster-wide pool to exhaust; the cost is entirely local.
The 32-bit UID space holds about 4.29 billion IDs. A node using the example range consumes roughly 0.17% of it, so even a generous idsPerPod of 1,048,576 across 110 pods (about 115 million IDs, roughly 2.7%) fits comfortably. The constraint to watch is not exhaustion but alignment: ranges must be multiples of 65536 and must not collide with IDs assigned by an LDAP or SSSD directory on the node.
Trade-offs, Gotchas, and What Goes Wrong
User namespaces are a strong control with a short but sharp list of limits. Most production incidents come from the following.
Filesystem and volume support. NFS volumes cannot be mounted in a user-namespace pod because the Linux NFS client does not yet support idmap mounts, per the Kubernetes docs. The same constraint applies to any volume plugin whose filesystem lacks idmap support. Check CSI drivers and storage classes before you migrate stateful workloads, and keep NFS-backed pods without hostUsers: false or move them to a supported backend.
Kernel floor. The documented practical minimum is Linux 6.3. A mixed fleet with older nodes needs node labels, taints or affinity so that user-namespaced pods land only on capable nodes. Otherwise the scheduler will place a pod on a node that cannot honour it, and you get a failing pod rather than a silent downgrade.
Host access is disallowed by design. Pods needing hostNetwork, hostPID, hostIPC or raw block devices cannot use the feature. That excludes many node agents, CNI components, log collectors and monitoring DaemonSets. Leave them in a tightly controlled system namespace, and spend your hardening effort on tenant-facing workloads instead.
Capabilities are not neutralised inside the namespace. A pod granted CAP_NET_ADMIN or CAP_SYS_ADMIN has those powers over resources owned by its namespace. It can still attack the pod’s own network namespace or abuse a kernel bug reachable with those capabilities. Dropping all capabilities remains correct.
The overflow ID trap. Files with host owners outside the pod’s mapped range show as 65534 and cannot be modified. An application that bind-mounts a host directory expecting to write into it will fail with permission errors. Fix this by using volumes the pod owns, or by adjusting ownership through supported volume mechanisms like fsGroup.
Operational drift. Changing the kubelet subordinate range while user-namespaced pods run can stop the kubelet from starting. Drain nodes first, as the documentation instructs.
Not a substitute for patching or isolation. A kernel bug reachable from inside a user namespace still exists, and user namespaces expose some kernel code to unprivileged use that was previously root-only, which is why some distributions restrict unprivileged user namespace creation by default. A sandboxed runtime or a VM boundary is the right addition for genuinely untrusted code. Which exposure you accept depends on your threat model; I am not aware of a published benchmark comparing the escape rates of these designs, so choose by reasoning about attack surface, not by measured numbers.
Observability gaps. Security tools that key on UID 0 or on host-visible usernames will now see large numeric IDs. Update detection rules, audit parsing and file integrity monitors so they correlate processes to pods by cgroup or pod UID rather than by user name. Also record the readlink /proc/<pid>/ns/user check as an audit probe to catch pods that silently run without isolation.
Practical Recommendations
Start by classifying workloads, because the right control set depends on who authored the code. Internal, reviewed services get Restricted-level Pod Security plus user namespaces. Anything that executes third-party or generated code gets those plus a sandboxed RuntimeClass.
Roll out in stages. First label a canary node pool with a kernel at 6.3 or later and a runtime stack that meets the version floor, then taint it so only opted-in pods schedule there. Enable hostUsers: false on one low-risk namespace, watch for permission errors on volumes, and compare namespace inodes to prove isolation. Move on only when storage and observability issues are resolved.
For ownership, make hardening a property of the platform instead of each team’s manifest. Use a Pod Security admission label per namespace, and add a policy engine rule that requires hostUsers: false for tenant namespaces. The same discipline applies to what runs inside the pod: our piece on AI model supply chain security and provenance shows why verifying artifacts matters as much as constraining the process that loads them.
A short checklist:
- Confirm kernel 6.3 or later, runc 1.2 or later (or crun 1.9 or later), and containerd 2.0 or later (or CRI-O 1.25 or later) on target nodes.
- Verify every volume filesystem supports idmapped mounts; replace NFS-backed volumes for these pods.
- Size
/etc/subuidand/etc/subgidfor65536 x maxPodsif using a custom range. - Set
hostUsers: false,seccompProfile: RuntimeDefault,appArmorProfile: RuntimeDefault, drop all capabilities and disable privilege escalation. - Enforce the Restricted Pod Security profile per namespace with enforce, warn and audit labels.
- Add a sandboxed RuntimeClass for untrusted code, and test that the combination works on your runtime.
- Add a detection rule that alerts on pods whose
/proc/<pid>/ns/usermatches the host. - Patch runtimes and the kernel on a fixed cadence; treat user namespaces as damage limitation, not prevention.
Frequently Asked Questions
What is the difference between hostUsers false and runAsNonRoot?
runAsNonRoot forces the container process to use a non-zero UID, which breaks images that expect root. hostUsers: false lets the process run as root inside the container while the host sees an unprivileged mapped UID. The first removes a privilege; the second relocates it into a namespace. For pods that set hostUsers: false, Pod Security admission does not check runAsNonRoot or runAsUser, so legacy images can meet the Restricted profile.
Which Kubernetes version do I need for user namespaces?
The Kubernetes documentation marks the feature as first available in v1.28 and stable in v1.36, with the UserNamespacesSupport feature gate now locked on. The per-pod ID count setting arrived in v1.33. Version of Kubernetes alone is not enough, since nodes also need Linux 6.3 or later for idmapped mount support on tmpfs, plus a compatible OCI and CRI runtime.
Does hostUsers false stop every container escape?
No. It limits what an escaped process can do on the host, and the upstream KEP lists several high and critical CVEs that were not exploitable under it, such as CVE-2019-5736. A kernel vulnerability reachable from inside the namespace, or a misconfiguration like a mounted runtime socket, can still be dangerous. Combine it with seccomp, an LSM profile, admission policy and prompt patching.
Can I use user namespaces with hostNetwork or privileged pods?
No. Setting hostUsers: false disallows hostNetwork, hostPID and hostIPC, and containers cannot use volumeDevices raw block volumes. Node-level agents such as CNI plugins and log shippers typically need host access, so they keep running without user namespaces in a controlled system namespace. Harden tenant-facing workloads with the feature and treat privileged infrastructure pods as a separate, tightly restricted category.
How do I know a pod is really running in its own user namespace?
Run readlink /proc/self/ns/user inside the pod and compare the result with the same command on the host; the inodes must differ. Also read /proc/self/uid_map, where the last number must be 65536 by default, and confirm with ps on the node that the process runs as a large numeric UID rather than root. Automate this check as an audit probe.
Should I use gVisor or Kata instead of user namespaces?
They solve different problems and can be combined where the runtime supports it. User namespaces are cheap, work with the standard runtime and narrow host privileges. Sandboxed runtimes add a separate kernel or VM boundary at the cost of overhead and compatibility limits. Use user namespaces broadly, and add a sandbox for workloads that run code you do not control. Test the combination before relying on it.
Further Reading
- Container runtime security hardening with containerd 2.3, CRI-O and Podman 6: runtime-level CVE response that complements pod-level isolation.
- Agentic AI security and prompt injection in 2026: why sandboxing model-generated code is the main blast-radius control.
- AI model supply chain security and provenance: verifying what runs inside your hardened pods.
- Bitget breach and exchange security architecture: a case study in third-party zero-day exposure and blast-radius design.
- Kubernetes documentation: User Namespaces and Pod Security Standards.
- KEP-127: user namespaces support: the motivation section and CVE list.
By Riju — about
