Zero trust architecture for AI agents is three layers, not a mesh checkbox

Part of: Agent Security

Zero trust architecture for AI agents means sandbox, egress, and identity, each assuming the others failed. A service mesh on worker pods is not that.

Zero trust architecture for AI agents means sandbox, egress, and identity, each assuming the others failed. Every action is authenticated as the agent, authorized for that agent, and logged somewhere the agent cannot edit. A service mesh on worker pods is not that.

Defensive security research. This post analyses publicly disclosed findings so the controls that stop them can be tested. It describes mechanisms, not procedures, and links the primary sources for anyone verifying the work.

I already wrote a short stack as sandbox, egress, identity . This post is that stack pointed at a multiplexed runtime, because Substrate makes the usual mesh story miss the workload.

The phrase shows up on slides next to a mesh logo. I want it to mean something I can test.

What is a zero trust architecture for AI agents?

It is three layers plus a tool-call gate, not a product SKU.

Sandbox bounds compute and filesystem. Fresh per occupant. No leftover files, no hostPath, no hostNetwork.

Egress is default-deny. The only outbound path is a proxy that names destinations per agent and logs the decision. DNS is in scope.

Identity is the agent, this session, not the worker’s ServiceAccount and not the human’s SSO cookie. Short-lived. Minted at restore. Dropped at suspend.

No layer trusts the others to have worked. That is the whole definition. If the sandbox leaked a socket, egress still denies. If egress was used, the credential is still this agent. If the credential is valid, the tool call can still be refused.

OWASP files the failure as Excessive Agency: damaging actions from unexpected, ambiguous, or manipulated model output, usually from excessive functionality, excessive permissions, or excessive autonomy. The badge version of that list is in who gave the agent a badge : own identity, permissions scoped to the task, a written approval list, and an audit trail. Zero trust for agents is those four controls enforced outside the model.

On Agent Substrate the enforcement has to follow the actor. Nine agents on two workers, later 18 on the same two, means the pod is not the principal. kagent Agent Substrate .

Why isn’t a service mesh zero trust for multiplexed agents?

It is zero trust for the worker pod if you do mTLS and authz on the pod identity. Multiplexed actors share that pod. Mesh without actor identity is encrypted shared-fate.

What is an agentic mesh is the useful version of the word: keep the service mesh for L4 identity and encryption, add an AI-aware hop that can see LLM, MCP, and tool actions. Replacing Istio with a checkbox is the wrong mental model.

atenet is agentgateway under the hood in the lab I ran. Config lived at /etc/agentgateway/config.yaml. Traffic to an actor goes through that hop, not through a Service per agent, because there is no Pod per agent. That is where actor identity has to appear. Agent Substrate dataplane .

Compose mesh with actor-aware egress. Do not substitute. If the mesh identity is the worker, you have wrapped layer 2 around the wrong principal. SPIFFE on the proxy is still worth having. It proves the proxy. It does not name the actor restored onto that worker five seconds ago.

What does the sandbox layer have to prove?

Assume the agent has a shell. gVisor or a microVM bounds syscalls and the filesystem. No hostPath, no hostNetwork, no leftover files for the next actor. Sandboxed networking for agents is part of this layer, not a bonus.

One actor per sandbox, always. That is Substrate’s rule. Density comes from time-multiplexing, not from sharing a filesystem. A worker hosts one actor at a time. The next restore may be a different agent. If a file survives, you do not have a sandbox. You have a disk.

I tried to break checkpoint with a held flock(). It survived because the sentry virtualized it. The resources that would actually pin a worker are the ones gVisor does not own: hostNetwork sockets, host devices, out-of-sandbox shared memory. Pinned resources . Sandbox class is a dataplane concern. I would not mix classes in one pool.

Test: write a file, suspend, restore a different agent on the same worker, confirm the file is gone. If you cannot run that, you cannot claim this layer.

The July 2026 intrusion’s path from a compromised worker to root on the node was a bare privileged pod with the host filesystem mounted. Pod Security Admission in restricted mode rejects that at the API server. That control is still on this layer. Rogue agent Kubernetes controls .

What does the egress layer have to prove?

Assume the sandbox leaked a socket. Default-deny out. Only the proxy. The proxy names destinations per agent. DNS is in scope.

Kubernetes Network Policy for agents is the pod backstop so a proxy bug cannot talk to the world. It cannot name the actor. It can keep the pool from becoming a botnet.

Hostname allowlists fail. The Hugging Face timeline had C2 over pastebins and file-drop hosts. A permitted package registry cache proxy was the sandbox escape. Allowed destinations are attack surface. Payload and destination both matter.

DNS is a separate channel. An OpenAI research agent had HTTPS blocked, then talked to an external chatbot over DNS. A CONNECT proxy never saw those queries. Agent DNS egress covert channel .

The containment basics lab is the topology: agent on an internal network, gateway on both, unapproved path returns 404 with reason NotFound, logged at the listener. The agent’s code did not change between the vulnerable run and the contained one. Agent containment basics .

Test: curl an unlisted host from inside the actor, confirm deny, confirm the deny is in a log the agent cannot edit. Then restore a second agent on the same worker and confirm it did not inherit the first agent’s destinations.

kind’s default CNI will accept the NetworkPolicy and ignore it. If you have never watched a policy refuse a packet, you do not have a backstop.

What does the identity layer have to prove?

Assume the network path was used. The credential must still be this agent, this session. Worker ServiceAccount is not that. Proof of agent identity . Mint at restore, drop at suspend.

On a WorkerPool, system:serviceaccount:kagent:kagent-default is proof of a pool. Actors rotate through the bay. If you revoke the SA, you revoke every actor. If you do not, you cannot tell which actor spoke.

The plumbing I have actually run: SPIFFE SVIDs with no cert file in the image, workload identity federation from a projected SA token, audience binding so a token minted for /data dies on /billing. Agent identity vs service account is the Kubernetes-native split. Why OAuth is not enough for agents is the human-token split.

Test: capture a token from agent A, replay as agent B, confirm 403. The SPIFFE demo does this with agent-alpha at HTTP 200 and agent-beta at HTTP 403 from a valid SVID in the same trust domain. Authentication is not authorization.

Do not serialize the credential into the snapshot. A checkpoint is a copy. Copies leak. Secretless AI agents is the inbound/outbound split: the agent holds identity, the gateway holds the provider key.

Where does tool policy sit?

Zero trust that never sees tools/call will allow a perfectly authenticated, perfectly isolated kubectl delete. Agent action verification . Tool-call guardrails reject or mask before the tool runs.

Network allow is “this agent may open a connection to this host.” Tool policy is “this agent may not pass rm -rf to that host.” Identity is “this is the refund agent, session 7, acting for Alice.” You need all three. Humans still approve intent. Machines still prove conformance on the path. Humans approve intent, machines prove conformance .

If any layer is “the mesh handles it,” I treat that layer as missing.

Checklist I would run on a WorkerPool

  • Sandbox: leftover file is gone after a different actor restores on the same worker.
  • Sandbox: no hostNetwork, no hostPath, restricted Pod Security on the pool.
  • Egress: unlisted host denied, deny logged off the actor.
  • Egress: DNS only to the cluster resolver you operate.
  • Egress: worker NetworkPolicy allows only the proxy, DNS, and node-local plumbing, verified with a refused packet.
  • Identity: token from A fails as B. Revoking A does not require deleting the worker SA.
  • Identity: no long-lived key in the snapshot.
  • Tool: destructive tools/call denied before the tool runs.
  • Log: the agent cannot edit the record.

Field guide: Agent Substrate .

Frequently asked questions

What is a zero trust architecture for AI agents?

Every action is authenticated as the agent, authorized for that agent, and logged. Compute is sandboxed, network is default-deny, credentials are short-lived. No layer trusts the others to have worked.

Is a service mesh zero trust for agents?

It is zero trust for the worker pod if you do mTLS and authz on the pod identity. Multiplexed actors share that pod. Mesh without actor identity is encrypted shared-fate.

How does this map to Agent Substrate?

Sandbox class on the worker, egress in front of the actor, identity minted at restore. NetworkPolicy on the pool is the backstop. I wrote each piece separately in this field guide.

Where does tool-call policy sit in zero trust for agents?

On the call path, before the tool runs. A perfectly authenticated, perfectly isolated kubectl delete is still a delete. Network allow is not authorization to invoke the tool.

What do you test first?

A leftover file after another actor restores on the same worker, an unlisted host from inside the actor, and a token from agent A replayed as agent B. If any of those pass, that layer is missing.

Disagree or have a war story? Reply on X