Risk surface
What Is Multi-Tenancy?
"Multi-tenancy" covers a wide range of situations, and they don't all carry the same risk. Before talking about the dangers, it helps to be precise about what kind of tenancy we mean.
Why bother?
Before getting into the risks, it’s worth remembering why people want multi-tenant clusters in the first place, as the reasons are pretty compelling.
- Money. Every cluster comes with its own control plane, and running lots of clusters means paying for lots of control plane nodes. Separate clusters also lose the ability to pack workloads from different teams onto the same worker nodes, which is where a lot of the savings in Kubernetes come from.
- Simplicity. Lots of clusters means lots of upgrades, lots of monitoring and lots of admin work. One big cluster is (at least in theory) a lot easier to look after.
The problem is that Kubernetes was designed to run lots of workloads on shared infrastructure, not to keep tenants who don’t trust each other apart. There’s no concept of a “tenant” anywhere in the Kubernetes API, and no built-in way of saying a resource belongs exclusively to one.
What do I mean by multi-tenancy?
When talking about Kubernetes multi-tenancy from a security standpoint, there can be different ways of framing what’s being discussed. For example, the Kubernetes documentation has a page on Multi-Tenancy. For the purposes of this site (and the talk) I came up with a definition of what I mean by it, which focuses on the security side of things: multiple groups of users (tenants) sharing a cluster, with some varying level of trust between them.
Essentially there are two variables that we’re considering.
How much do we trust the tenants?
The first one is how much trust we place in the individual tenants.
-
Same team. Here multiple applications from a single team are run in a single Kubernetes cluster. As it’s the same team managing them, and the applications (hopefully) are developed and secured in the same way, we have quite a bit of trust between tenants. We still need controls to mitigate the risk of an external attacker compromising one of the applications and then trying to expand their access to other applications in the cluster, but we’re less concerned with malicious users trying to cross tenant boundaries, or one insecurely developed application leading to the compromise of other higher security applications.
-
Different team or environment. Here our tenants might have a different threat model or risk posture that means we have to place additional controls between them. This could be multiple teams at the same organisation who have different development practices and/or threat models, or it could be having development/test/production applications in the same cluster, where a development environment is likely to have less rigorous controls placed on it. Once we have more variability in threat models, additional controls are a good idea.
-
External customers as tenants. Here we have essentially untrusted parties as tenants, who we need to treat as possibly actively hostile. There may be some controls from contracts in place, but tenants should be considered possibly malicious from a security perspective.
How much can the tenants do?
The second axis is more specific to Kubernetes and focuses on how many rights each tenant has. This will inform the types of controls that are necessary and how easy it will be to isolate tenants.
-
Application access. Here tenants and users can only see deployed applications, they have no direct access to the cluster or nodes. There are still some risks to consider based on application breakout attacks leading to container access, but it’s another layer of security that would need to be compromised before they were able to influence the cluster or containers directly.
-
Container shell. Where tenants are given a shell in their application containers, generally for debugging/maintenance reasons. This opens up attacks that can be executed from a container (e.g. container breakouts) and network attacks on other tenants.
-
Specified container image. In a Containers As A Service type deployment, tenants can effectively specify what image they want to run. Generally this will give them access to whatever tools they like, and will also let them specify the software available to be used. It can also open up specific vectors where a malicious container image is used for breakouts. Lastly, depending on how they specify and deploy their images, this might open up risks of compromised container registries.
-
Custom manifests. Here the tenant can specify not only the container image to be used but other aspects of the deployment manifest. This opens up risks of a tenant giving their containers access to the underlying nodes, via things like
privileged: trueor mounting the whole node filesystem into the container with ahostPathvolume. -
Limited Kubernetes namespace access. In this setup tenants are provided with access to a namespace and direct Kubernetes API access to deploy and manage their workloads in that namespace. This configuration opens up Kubernetes RBAC risks as, if given the wrong permission, it might be possible for tenants to escalate their privileges to the cluster.
-
Namespace As A Service. In this configuration tenants are given effectively full control of their namespace. It’s not unusual to see this done with wildcard permissions, for example a RoleBinding to the
cluster-adminClusterRole scoped to the tenant’s namespace. Here there are additional concerns, like tenants editing their own namespace object to bypass security controls.
Multi-tenancy you might not have noticed
It’s worth noting that multi-tenancy isn’t always visible at the Kubernetes layer. A cluster with a single, trusted operator can still host multiple untrusted tenants inside a higher-level platform, for example an ML platform like Kubeflow, a CI/CD system, or any application that runs code or workflows supplied by its users.
In these cases the tenant boundary sits at the application layer, and tenant workloads might even share a single namespace. ERNW’s Breaking Multi-Tenancy in Kubernetes research (Black Hat USA 2026) has some good examples of this, and makes the point that because these platforms treat their users as untrusted, an isolation failure tends to be a lot more serious than in a cluster shared by a couple of internal teams.
Where does the boundary sit?
There are three broad ways of drawing the line between tenants, and each one trades isolation for cost.
| Model | What’s shared | Trade-off |
|---|---|---|
| Cluster per tenant | Nothing at the Kubernetes level | Strongest isolation, but you lose most of the cost and simplicity benefits |
| Namespace per tenant | API server, nodes, network, cluster-scoped resources | Cheapest and most common, but relies on getting RBAC, admission control and network policy right |
| Virtual clusters | Nodes and the underlying network | Each tenant gets their own API server (so their own CRDs and DNS), but container breakouts to shared nodes are still a concern |
The rest of the site mostly looks at the namespace-per-tenant model, as that’s where most of the shared surfaces come into play.