Skip to content

All posts

KubernetesAI

AI agent threat model for Kubernetes

Ritesh Patel

Kubernetes: AI agent threat model for Kubernetes

An AI agent threat model for Kubernetes lists what a running agent pod can reach: its token, the Secrets in its namespace, its pod settings and its network destinations. For each path it names the control that stops it. Start with an inventory of agent pods, since every other step tests against it.

What the model has to cover

An agent is a workload that holds credentials and chooses, at runtime, which tools to call. The threat model therefore starts at the pod rather than the model. For each agent, three questions matter: what its identity can do in the API, what the pod can read from its node and namespace, and where its traffic can go.

A compromised agent, or one that follows instructions in content it retrieved, gets the same three things. The model should describe those capabilities, not guess at attacker intent. Use one agent, one namespace and one service account as the unit of analysis, because that is the scope Kubernetes controls are written against.

Five attack surfaces to model

The pod spec

Pod-level settings decide what the container can do to the node. The Pod Security Standards Baseline level forbids hostPath volumes, sharing the host PID, IPC or network namespaces, and privileged containers. Pod Security admission applies those levels through namespace labels in three modes: enforce rejects violating pods, audit adds an annotation to the audit event, and warn shows a warning to the user.

A namespace with no Pod Security label gets the cluster-wide defaults from the admission configuration. In the stock configuration those defaults are privileged, which accepts a privileged agent pod with a host mount, but a cluster can set stricter defaults and exempt namespaces, users or runtime classes. The threat model should record which namespace each agent runs in and the effective level and exemptions that apply to it.

The service account token

By default, the ServiceAccount admission controller adds a projected volume that holds a token for API access. It does not do so when automountServiceAccountToken resolves to false. A value set on the pod takes precedence over the value on its service account, so a pod that sets true still gets the token even when its service account sets false. The token comes from the TokenRequest API, is bound to the pod and has the kube-apiserver as its audience. The kubelet requests it with a one-hour lifetime by default, but the --service-account-extend-token-expiration flag, which defaults to true, extends admission-injected tokens to up to one year. Check the exp and iat claims of the issued token for its real lifetime. The kubelet refreshes the token before it expires.

The lifespan limits how long a copied token works, which for an admission-injected token can be a year. It does not limit what the token can do, which is set entirely by the RBAC bindings on the account. An agent that never calls the API should not have a token at all.

Secrets in the namespace

The Secrets documentation says a container reaches any Secret other than the default service account’s only after you map it, through an environment variable or a volume. That default-account sentence is out of date for the API credential: on v1.22 and later the default credential is a short-lived projected token, not a Secret, according to the service accounts page. The Secrets page also says anyone authorized to create a pod in a namespace can use that access to read any Secret in the namespace. Direct API access is a second path. Anyone with get, list or watch on Secrets can read them without creating a pod.

For agents this is the most common path to trouble. Giving an agent identity pod-creation rights, even for a debugging job, is a route to every Secret the namespace holds. The same page says that when a Secret is mounted as a volume, Kubernetes updates the files after the Secret changes, using an eventually consistent approach. It does not say the same for environment variables, so test rotation before you rely on it.

Network destinations

The agent reaches tool servers, model endpoints and internal services over the network. The pod spec does not decide those destinations. Your network controls do, and they sit outside the agent’s own manifest.

List every destination the agent needs. Anything else the agent can reach is a finding, whatever the agent’s configuration says it should use. Test the reachable set from inside the pod; do not rely on the endpoints you configured.

Content the agent reads

Instructions can arrive inside data the agent retrieves: a ticket, a web page, a log line or a tool response. No Kubernetes admission or RBAC rule sees that path. The threat model should record which inputs each agent reads and which of its tools those inputs can influence. The defence for this surface is in the agent’s design and in keeping its identity small, which is why the other four surfaces carry the weight.

Map each path to a control

The table below pairs each surface with what an attacker gets and the Kubernetes control that limits it. Use it as a worksheet: add one row per agent and mark any surface with no control as a gap.

Surface What a compromised agent gets Control Where it applies
Pod spec Host filesystem, host PID, IPC or network namespaces, privileged container Pod Security admission at the Baseline level Admission
Service account token API calls as the agent’s service account automountServiceAccountToken: false, narrow RBAC Role Pod creation, request time
Namespace Secrets Any Secret in the namespace No pod-create rights for agent identities; one namespace per agent RBAC
Network destinations Reach to services the agent was never meant to call Network controls on egress Runtime
Content the agent reads Instructions that change what the agent does Agent design; least-privilege identity Agent

Build the model in six steps

  1. List every agent pod, its namespace, its service account and its image. Write one row per agent.
  2. For each pod, record the Secrets mounted or referenced, whether the token is mounted, and the RBAC bindings on its service account.
  3. Label each agent namespace with Pod Security in warn and audit mode at the Baseline level. Leave enforce off for now.
  4. Read the warnings and audit events from a full run cycle of the agent. Pod Security is applied when pods are created, and warn and audit labels do not re-check a pod that is already running, so an empty log is not a pass. Re-create each running pod, or run kubectl label --dry-run=server --overwrite ns agents pod-security.kubernetes.io/enforce=baseline to see how existing pods would fare. Fix each pod that violates the level, then switch enforce on.
  5. Set automountServiceAccountToken: false on every agent that does not call the Kubernetes API. Keep the token for agents that do, and bind them to the narrowest Role that works.
  6. Remove pod-creation rights from agent identities. Record the maximum effect each agent could complete with the identity and destinations it holds.

Config for steps 3 and 5

The first block sets Baseline enforcement in warn and audit mode on an agent namespace. The label names come from the Pod Security admission page. The optional version labels are left out here.

apiVersion: v1
kind: Namespace
metadata:
  name: agents
  labels:
    pod-security.kubernetes.io/warn: baseline
    pod-security.kubernetes.io/audit: baseline

The second block shows an agent pod that does not need the API. The ServiceAccount admission controller skips the token volume when the pod’s automountServiceAccountToken is false, or when the pod leaves it unset and its service account sets false. The block creates the ServiceAccount first, because the admission controller rejects a Pod whose ServiceAccount does not exist.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: report-agent
  namespace: agents
---
apiVersion: v1
kind: Pod
metadata:
  name: report-agent
  namespace: agents
spec:
  serviceAccountName: report-agent
  automountServiceAccountToken: false
  containers:
    - name: agent
      image: registry.example.com/report-agent:1.0

Before you use either block, run it on the cluster version you operate.

Questions to answer before you sign off

  • Can each agent name its namespace, service account and every Secret it can read?
  • Does any agent identity have pod-creation rights?
  • Is the token mounted on any agent that never calls the API?
  • Which network destinations can the agent reach from inside its pod, and which of them did you intend?
  • Which inputs does each agent read, and which tools can those inputs influence?
  • What is the most consequential action each agent can complete without a second decision?

Where to go next

The model above covers the Kubernetes side. The longer threat model, with attack paths and control coverage across the build, deploy, request and execution points, is on the Governing AI agents in Kubernetes page. For the identity and sandbox parts of this model, read RBAC for AI agents in Kubernetes and How to sandbox AI agents on Kubernetes. The admission side is covered in Kyverno policies for AI agents, and the broader category is on the AI agent governance page.

Frequently asked questions

What is the first step in an AI agent threat model for Kubernetes?

Inventory the agent pods and their service accounts, then record which Secrets, tokens and network destinations each one can reach. Write the list per agent, not per cluster, so every row names one identity. Without that list the rest of the model has nothing to test against.

Should an AI agent pod mount its service account token?

Only if it calls the Kubernetes API. The ServiceAccount admission controller adds a token volume unless automountServiceAccountToken resolves to false. A value set on the pod takes precedence over the value on its service account, so a pod that sets true still gets a token even when its service account sets false. Set it to false on the pod for agents that never call the API. For agents that do, check the exp and iat claims of the issued token, since admission-injected tokens can stay valid for up to one year by default, and bind them to a narrow Role.

Can permission to create pods expose Secrets to an agent?

Yes. The Kubernetes Secrets documentation says anyone authorized to create a pod in a namespace can use that access to read any Secret in that namespace. Keep agent identities away from pod creation, and run each agent in a namespace that holds only the Secrets it needs.

Does Pod Security admission stop a privileged agent pod?

It does when the namespace enforces the Baseline level, which disallows privileged containers, hostPath volumes and host namespaces. In enforce mode the API server rejects the pod. Audit and warn modes only record or warn, so the pod is still created until you switch the namespace to enforce.

Ritesh Patel, Founder & VP Product, Nirmata

Ritesh Patel is a founder of Nirmata and leads its products. He writes about governing AI coding agents, MCP security and Kubernetes policy as code.

LinkedIn

Govern AI agents with AIControlsControl what AI agents do, and prove it.
ShareXLinkedIn

Stay up-to-date with the latest in AI, governance, and infrastructure

Subscribe to our free monthly newsletter to get industry news, DevOps tips, and articles right to your inbox on Kyverno, containerization, Kubernetes deployment & management and more.