BlueBear Insights · Runtime Security · 9 min read

Multi-Tenant AI Agent Isolation on Kubernetes

BlueBear platform runtime story poster
A poster generated from the existing BlueBear platform story.

Disclosure: BlueBear sells a platform that runs governed agent workspaces, so we have a commercial interest. The Kubernetes decisions below are yours regardless of platform, and this article is about how to choose between them rather than what to buy.

The decision you make by not making it

If you run agents for more than one customer on infrastructure you operate, you have already chosen an isolation level. Most teams choose it by accepting a default: one cluster, a namespace per customer, no network policy. That is a reasonable starting point for stateless services and a weak one for agents, and the gap is worth understanding before someone asks you to describe it in a security review.

What a namespace actually separates

A namespace gives you a naming scope, a place to hang resource quotas, and a unit for access control. Those are real. What it does not give you is network separation -- by default a pod in one namespace can reach a pod in another -- and it does not give you kernel separation, because every pod on a node shares that node's kernel.

So a namespace answers who can administer this and how much can it consume. It does not answer can this workload reach that one, which for agents is the question that matters.

Network policy is the control that earns its keep

The single highest-value addition is a default-deny network policy per namespace, with explicit allowances for what each workload legitimately needs to reach.

It matters more for agents than for ordinary services because of what an agent is: a process holding credentials for customer systems, following a path chosen at runtime. If one is compromised or manipulated, the practical question is what it can reach. Without a network policy the answer is everything in the cluster, plus whatever egress allows. With one, the answer is a list you wrote down.

Egress deserves as much attention as ingress here, and usually gets less. An agent that can make outbound calls to anywhere is an exfiltration path that does not require reaching another pod at all.

Node pools, and the honest reason to use them

Dedicating node pools per tenant, or per sensitivity tier, buys two things. It removes the shared kernel between tenants, which matters if your risk assessment takes container escape seriously. And it removes noisy-neighbour effects, which for agent workloads are real: a run that fans out across a large input set can consume enough CPU to degrade everything on the node.

The cost is utilisation. Dedicated pools mean paying for headroom per tenant rather than pooling it, and the bill is proportional to how many tenants you carve out.

When a separate cluster is the right answer

A cluster per tenant is the strongest boundary available short of separate accounts, and it is frequently the wrong choice anyway. The reason is operational rather than technical: your ability to patch, upgrade and monitor clusters promptly is finite, and a fleet of small clusters degrades that. A boundary you maintain badly is weaker than a lesser boundary you maintain well.

Reserve it for cases where a contract or regulator requires it, or where a specific tenant's data genuinely cannot share a kernel. Otherwise namespace plus network policy plus node pools covers most of the distance at a fraction of the operational load.

Four checks

  • Can a pod in one tenant namespace open a connection to another? Test it rather than assume. If it succeeds you have naming separation, not isolation.
  • Where can an agent pod reach on egress? If the answer is the internet, that is your exfiltration path.
  • Do two tenants share a node? If yes, you have accepted shared-kernel risk. That may be fine, but it should be a decision.
  • How long does it take you to patch every cluster you run? If adding clusters would push that past your tolerance, more clusters is not more security.

What this costs

Network policy is the cheapest meaningful improvement available and is mostly a day of writing rules plus the discipline to keep them. Node pools cost utilisation, and the number is calculable in advance. Separate clusters cost operational attention, which is the resource most likely to already be fully committed.

Where the isolation usually leaks in practice

The boundary you chose is rarely the one that fails. Three leaks account for most real incidents, and none of them are namespace or network policy problems.

Shared secrets. Per-tenant namespaces with a single credential for the downstream ERP is not tenant isolation, it is tenant naming. Whatever the pod boundary says, one agent can reach every tenant's data through that credential. This is the most common gap, and it usually arrives during a migration when per-tenant credentials were "coming later".

Shared caches and queues. A Redis instance or job queue serving all tenants is a channel that crosses every boundary above it. Keys are usually prefixed by tenant, which is a convention rather than a control — a bug in key construction is a cross-tenant read, and it will not look like a security event in any log.

Shared model context. Specific to agents and easy to miss: if retrieved context, embeddings or a conversation store are pooled, one tenant's content can reach another's prompt without any pod ever talking to another pod. The infrastructure boundary is intact and the data crossed anyway.

The test that finds all three

Give one tenant's agent a deliberately distinctive string — a made-up customer name works — and then, from a second tenant's agent, ask for it. Do it against the cache, the queue, the retrieval store and the downstream credential in turn.

It takes an afternoon and it tests what actually matters: not whether the pods are separated, but whether the data is. A namespace diagram cannot answer that question and this can.

What to write down once you have chosen

Whichever level you land on, record two things: which boundary each tenant sits behind, and what specifically would have to fail for one tenant to reach another. That second sentence is the one that gets asked in a security review, and it is much easier to write while the decision is fresh than to reconstruct a year later from manifests.

It also makes the boundary reviewable. A statement like "tenants share a cluster and a kernel, are separated by namespace and default-deny network policy, and a container escape would cross that boundary" is something a reader can agree or disagree with. A diagram of namespaces is not.

Questions people actually search for

how do you isolate ai agent workloads for different customers on kubernetes

By choosing a boundary deliberately at four levels. A namespace separates names, quotas and access control but shares a kernel and, by default, the network. A network policy stops pods reaching each other, which is the control that matters most for agents. A dedicated node pool removes shared-kernel and noisy-neighbour concerns. A separate cluster is the strongest and the most expensive to operate. The common mistake is taking the namespace default and assuming it did more than it did.

is a kubernetes namespace enough to separate tenants

Not on its own. A namespace scopes names, resource quotas and RBAC, but pods in different namespaces can normally still reach each other over the network, and all of them share the node kernel. For agent workloads holding per-customer credentials, namespace plus a default-deny network policy is the realistic minimum, and even then a container escape crosses the boundary.

do ai agents need stronger isolation than normal services

Generally yes, for two reasons. They hold credentials for customer systems, so a compromise yields access rather than just data. And they execute paths chosen at runtime rather than a fixed code path, so the set of things a given pod might do is wider than for a conventional service. That combination argues for network policy as a baseline rather than an enhancement.

when should each customer get a separate kubernetes cluster

When a contract or regulation requires it, when a customer's data cannot share a kernel with another's under your own risk assessment, or when one tenant's load genuinely threatens the others and node pools have not solved it. Below that threshold, a separate cluster per customer usually buys less isolation than it costs in operational surface, because the number of clusters you can patch promptly is finite.

Primary sources