What is agent identity?

Agent identity is a separate, named identity for each AI agent, with its own credentials, its own permissions and its own audit trail. A service account names a workload, so several agents can end up sharing one account. An agent identity also records which agent acted, the task it was running and the person it acted for.
Checked against the Kubernetes service account and RBAC documentation as fetched on 2026-11-04. The examples below have not been run on a cluster yet.
Start with the service account
Kubernetes gives workloads an identity through service accounts. The docs describe a service account as a non-human account that provides a distinct identity in a cluster. For an agent running in a pod, that is the obvious starting point. The pod names a service account, and the account carries the credentials.
A service account does not cover everything an agent needs. It identifies a workload, meaning the process holding the credentials. It does not say which agent inside that workload acted, what task it was doing, or which person asked for the action. Those three facts decide whether a later review can explain what happened, so they belong in the agent identity and should not be left for a reader to guess from a pod name.
What a service account covers, and what it misses
The table compares the Kubernetes object with what an agent identity should add. The first two columns describe the Kubernetes docs. The third column is our recommendation.
| Question | Kubernetes service account | What an agent identity should add (our recommendation) |
|---|---|---|
| Who is it? | A non-human identity, bound to one namespace | One named identity per agent, plus the person or system it acts for |
| How is the credential issued? | A short-lived token that rotates automatically since v1.22 | The same short lifetime, with one credential per agent |
| What can it do? | Permissions from RoleBindings (one namespace) or ClusterRoleBindings (cluster-wide), purely additive | Grants scoped to the task, reviewed on a schedule |
| What is recorded? | The account, its namespace and its token | The agent, its task, the delegating person and each tool call |
Three reasons one service account is not enough
Shared accounts pool their permissions
RBAC permissions are purely additive. The RBAC docs say there are no “deny” rules. That means every binding that grants a permission to a service account applies to every pod running under that account. Two agents that share one account share every grant, and you cannot carve out an exception for one of them. If the release agent needs to write to a namespace, the triage agent running under the same account can write there too.
The practical fix is one service account per agent, so each binding changes the reach of exactly one agent.
Grants follow the account, not the task
A RoleBinding grants permissions within a specific namespace. A ClusterRoleBinding grants them cluster-wide. Both attach to a subject, not to the work the subject is doing. An agent that reads tickets on Monday and deploys on Tuesday holds the same grants on both days, unless someone edits the bindings.
The RBAC docs describe no expiry on a binding and no field for a task. If you want task-scoped access, you have to build that lifecycle in your own systems and then make sure the bindings reflect it.
Short-lived tokens do not record who asked
Since v1.22, a service account token is short-lived and rotates automatically. That removes the long-lived static token that earlier versions gave a pod as a Secret, and it shrinks the window for a stolen token. It does not tell you who used the token for what. The authentication docs say Kubernetes has no objects that represent normal user accounts, and service account credentials let in-cluster processes talk to the API. The person who asked an agent to act does not appear in that token, so the delegation has to be recorded somewhere else.
What an agent identity needs
- Create a named service account for each agent. Set it on the pod with
spec.serviceAccountName. Each namespace gets adefaultaccount that receives no permissions beyond API discovery, so do not run agents under it. - Bind it with a RoleBinding in one namespace. Use a ClusterRoleBinding only when the agent really needs cluster-wide reach, because it covers every namespace.
- Use the rotating token. Do not mount a static token Secret into agent pods. Kubernetes before v1.22 issued that kind of token.
- Record the delegation outside Kubernetes. Log the agent name, the person who started the task and each tool call in the audit system you already run. Kubernetes does not write this for you.
- Review bindings on a schedule. Additive grants accumulate, and nothing expires on its own.
A RoleBinding for a release agent, assuming a Role named pod-reader already exists in the agents namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: release-agent-read-pods
namespace: agents
subjects:
- kind: ServiceAccount
name: release-agent
namespace: agents
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
The pod that runs the agent names the account it uses:
apiVersion: v1
kind: Pod
metadata:
name: release-agent
namespace: agents
spec:
serviceAccountName: release-agent
containers:
- name: agent
image: registry.example.com/release-agent:1.0
Test both on a cluster before you rely on them. The manifests above are a starting point, not a tested configuration.
Where a policy engine fits
Kyverno describes itself as a cloud native policy engine. Its docs say it can validate, mutate, generate or clean up any Kubernetes resource. A rule could require that agent pods name a dedicated service account, which checks that each agent was configured with its own identity.
That is a configuration check. It shows how an agent was set up, and it does not show what the agent did while it ran. Treat it as one part of the identity model next to the audit trail, not as a replacement for either.
What to do next
Start with one agent. Give it its own service account, one RoleBinding and an audit record that names the person who asked for the work. The next time that agent takes on a new kind of task, check whether its account still needs the same grants.
Two related posts cover the rest of the picture. How to audit MCP tool calls covers the tool-call side, and Governing AI agents from code to runtime covers the wider picture. For the wider governance context, see the governing AI agents hub and the AIControls platform page.
Frequently asked questions
Is a Kubernetes service account the same as agent identity?
No. A service account is the Kubernetes identity for a workload. Agent identity is a wider requirement: the agent, the task it was running and the person it acted for should all be on record. The Kubernetes docs describe the account, its namespace and its token. They do not describe a field for the task or the delegating user, so you add those in your own systems.
Why not give every agent the namespace default service account?
The namespace's default service account has no permissions beyond API discovery, so an agent on it cannot do its work. The fix people reach for is granting that account a role, and that makes the grant apply to every pod on it. Create a named account per agent instead, so a grant reaches only the agent it was made for.
Do short-lived tokens solve agent identity?
They solve part of it. Since Kubernetes v1.22, service account tokens are short-lived and rotate automatically, which shrinks the window for a stolen token. They do not record who asked an agent to act or why. Token lifetime and an audit trail answer different questions, so an agent deployment needs both.
Does a policy engine such as Kyverno give agents an identity?
No. Kyverno is a policy engine that can validate, mutate, generate or clean up Kubernetes resources. It can check that an agent pod is configured with its own service account, which is useful. It does not issue identities, and it does not record what an agent does once it is running.