Shared Surface · RBAC
RBAC
RBAC is the mechanism the whole multi-tenant story leans on — and complexities in how it operates can lead to security weaknesses.
Tenant authorization is an important concept for Kubernetes multi-tenant security, especially in cases where tenants have direct access to the Kubernetes API (e.g. Namespace As A Service).
Whilst clusters can have multiple authorization mechanisms in place, RBAC is a constant in almost every cluster.
There are some places where the architecture of RBAC makes this complex and allows for possible tenant privilege escalation.
Privilege escalation
There are quite a lot of rights that can be provided to individual users or groups that allow for escalation of privileges. Without additional controls, letting a tenant create a pod on a shared node can lead to trivial privilege escalation, as one example. The project maintains a list of known privilege escalations, but it’s worth noting that this only focuses on the core of Kubernetes and doesn’t account for any external software installed in the cluster.
Some of the less obvious ones are:
escalateandbind. These verbs bypass the check that normally stops you granting permissions you don’t already have. I’ve written about both of these before, in Escalating Away and Getting Into A Bind.impersonate, which does pretty much what you’d expect.nodes/proxy, which gives access to the Kubelet API via the API server, skipping admission control and audit logging along the way.GETonpods/exec. You’d thinkGETwould be read-only, but since Kubernetes 1.31 switchedkubectl execover to websockets, it’s enough to run commands in pods (more detail here).- Creating and approving CSRs, which lets you mint a client certificate for pretty much any identity in the cluster.
- Write access to
controllerrevisions(along withstatefulsets). Before the fix for CVE-2026-2270 this was effectively the ability to create pods in any namespace (more on the operators page).
The general advice is to avoid wildcards wherever possible. We are all made of stars, your RBAC shouldn’t be :)
Are namespaces namespaced?
One place where this problem is shown quite clearly is the namespace object itself, which Iain Smart covered in some detail in his Breaking Boundaries post for AmberWolf.
Namespaces are a cluster-scoped resource, but they’re also treated as being namespaced to themselves. So a tenant admin who has been given wildcard permissions in their namespace (for example via a RoleBinding to the cluster-admin ClusterRole, which is not that unusual a setup) can edit their own namespace object. The minimum needed is get and patch on namespaces.
At one level this sounds quite obvious, a namespace admin can administer their own namespace, but it opens up some interesting risks because quite a few Kubernetes security controls make their decisions based on namespace labels.
- Pod Security Admission decides how restricted workloads in a namespace are based on the
pod-security.kubernetes.io/enforcelabel. A tenant who can edit that label can just change it fromrestrictedtoprivileged, create a privileged pod and escalate to the node. - Network policies often allow traffic from a namespace based on a custom label (e.g. something like
function: ingress-controlfor the ingress controller’s namespace). A tenant can add the same label to their own namespace and get past the policy.
For the network policy case, the fix is to select namespaces using the automatic kubernetes.io/metadata.name label instead of a custom one. That label is always set to the namespace’s name, and on Kubernetes 1.21+ it can’t be spoofed, as the API server resets it on every write and fills it in on every read (it’s not even stored in etcd). Unfortunately that doesn’t help with the Pod Security Admission label, so the real answer there is not giving tenants the ability to edit their namespace objects in the first place.
As Iain puts it in his post, “most of Kubernetes is a bunch of for loops in a trenchcoat”, and quite a lot of those loops will happily act on whatever a tenant puts in their namespace.