In March 2026, an Internet-Draft called draft-klrc-aiagent-auth-00 appeared on the IETF datatracker: a framework for authenticating and authorizing AI agents, written by four people from Defakto Security, AWS, Zscaler and Ping Identity. Its proposal was that an agent is a workload, so give it a workload’s identity. Name it with a SPIFFE ID. Authenticate it with credentials that expire quickly. Authorize it through OAuth 2.0. An individual submission carries no official standing at the IETF; it is a personal contribution to the process.
I built my agent’s identity by hand before that. This is a gap analysis between what I have and where the standards point, including the cost of adoption and what it would not solve.
What I run today
My agent runs on a per-agent service account with a scoped role, a name on every trace, and a tool registry updated by hand when its capabilities change. That is the whole of its identity: a string in a logging pipeline, not something it can prove.
The audit question I could not answer was whether the account’s permissions had crept since it was created, whether other workloads in the same namespace shared its scope, and whether the agent’s tool-calling had grown past what the original approval covered. Nobody checked.
That is not unusual. The CSA whitepaper on non-human identity governance cites Entro Security research putting 47% of non-human identities as unchanged for more than a year, and a 2025 WEF analysis putting 51% of organizations as having no clear ownership of AI identities. Both figures describe the same failure: identity that is assigned once and never revisited.
Hand-built identity is static in a dynamic environment. When the agent needed a resource outside its original scope, the only way to grant it was to widen the scope, so the permission label became a lower bound rather than a boundary.
A per-agent service account also bounds only what the agent may ask the Kubernetes API for. It does not bound what anything else in that namespace can reach. The Kubernetes RBAC guidance is explicit: creating workloads in a namespace implicitly grants access to the secrets, config maps and service account tokens in it. Per-agent identity inside a shared namespace is a naming improvement, not a containment one.
The two layers the standards distinguish
The draft, which I’ll call AIMS, draws a distinction worth keeping: workload identity versus delegated identity. They answer different questions.
Workload identity answers “who is this?” It binds an identifier to a key, cryptographically, so a process can prove it is the thing it claims to be. SPIFFE defines the naming (spiffe://<trust-domain>/<path>). SPIRE, its reference implementation, hands out short-lived credentials that rotate on their own after checking what the workload actually is: which container, on which node, from which signed image.
Delegated identity answers “on whose authority?” That’s an OAuth 2.0 access token carrying the agent’s identifier as client_id and the delegating user’s as sub. Scoped, time-limited, checked by the receiving service on every request.
AIMS stacks these without inventing anything. SPIFFE handles who. OAuth handles on whose behalf. WIMSE supplies mechanisms that tie that identity to an individual request rather than to a session. RFC 8693 contributes the act claim, which records who is acting for whom.
Clean composition. Incomplete.
The left column is buildable today with shipping software. The right column has no standard, and the AIMS draft says so explicitly for the first row.What each standard actually specifies
SPIFFE: the identity substrate
SPIFFE gives you one way to issue and check workload identities using cryptographic identifiers instead of shared passwords or whatever token someone pasted into an env var. Each agent gets an identity tied to things about its deployment that can be verified independently. It’s short-lived and renews itself, which is what kills the orphaned-credential problem: nothing outlives the workload that owned it.
If your team already runs infrastructure as code, agent identity fits into the same pipeline. Credentials get provisioned through code review, which is a convenient place to force someone to name an owner, an expiry, and a scope.
WIMSE: the authentication layer
WIMSE (Workload Identity in Multi-System Environments) is the set of mechanisms that tie a SPIFFE identity to an individual request rather than to a session. The architecture draft (draft-ietf-wimse-arch-07, March 2026) defines the Workload Identity Token and treats certificates as an equivalent alternative.
The mechanisms live in separate documents. The original service-to-service draft expired and got split four ways: draft-ietf-wimse-wpt for the Workload Proof Token, draft-ietf-wimse-http-signature for signed HTTP messages, draft-ietf-wimse-mutual-tls for mutual TLS, and draft-ietf-wimse-workload-creds for credential formats. A Workload Proof Token, per the current spec, is “a signed JWT that binds the workload’s authentication to a specific HTTP request, providing application-level proof of possession.”
That last phrase carries the weight. A bearer token works like cash: whoever holds it can spend it. Proof of possession means the caller has to demonstrate it holds the private key, so a stolen token is worth nothing on its own. And the proof covers one request, not a whole session.
The fragmentation matters too. Evaluating WIMSE today means evaluating four active drafts plus an architecture document, not a finished specification.
Signed HTTP messages are the option for cases where identity at the transport layer isn’t enough. The WIMSE profile requires signing the method, the target, a digest of the body, and the identity token itself, so authentication survives proxies and gateways in between.
OAuth 2.0: the delegation layer
AIMS uses OAuth 2.0 for delegation, and nothing here is new. When a user hands authority to an agent, that’s the Authorization Code Grant: the user logs in, approves what’s being asked for, and the agent gets a token reflecting that grant. When the agent acts purely on its own behalf, it’s the Client Credentials Grant.
Transaction tokens address a specific risk inside a call chain. Rather than forwarding the original access token from service to service, where any hop could reuse it for something else, the issuer mints a narrower token carrying the caller’s context and a unique transaction ID. Its authority is bound to that one transaction and nothing beyond it.
One OAuth failure mode deserves naming because it requires no compromise at all. In consent phishing, an attacker persuades a user to grant permissions to an application the attacker controls. From then on the associated service principal reads data under a legitimately issued grant. No password is stolen, no vulnerability is exploited, and the resulting access looks correct in every log. For agent platforms and third-party orchestration tools, the consent screen is the attack surface, and it is governed by whoever can talk a user into clicking it.
The act claim and delegation chains
RFC 8693’s act claim identifies the actor on behalf of the subject. This is the mechanism for delegation chains. Agent A acts on behalf of user B, and when A calls service C, the token carries both B’s identity (as sub) and A’s identity (as act).
One limitation matters more than the rest: everything before the current actor is a record, not a rule. If A delegates to B and B delegates to C, C can see A and B listed in the token and does not check either one. The identity is visible the whole way down. The authority behind it is verified only at the last hop.
What the clouds already ship
Everything above is a standards conversation, and it leaves out something awkward: the platforms I already run on ship most of the identity half today, and I am not using it.
The shape is the same on all three major clouds. External proof of identity, a trust relationship that validates it, a token exchange, a short-lived credential, and optionally an impersonation step. AWS does it through role trust policies and AssumeRoleWithWebIdentity, AssumeRoleWithSAML, IAM Roles Anywhere for X.509, or IoT Core for mutual TLS. Azure does it through workload identity federation, where an app registration or user-assigned managed identity trusts tokens from GitHub, Google or a Kubernetes cluster. Google does it through Workload Identity Federation into STS, then service account impersonation.
Google’s impersonation model is worth noting for a reason unrelated to credentials. Most audit logs record both the originating principal and the impersonated service account. That dual trail is what an agent acting on an operator’s behalf needs, and it is the act claim above, implemented years earlier and shipping now.
The identity half is a solved, shipping problem on all three. The authorization half is not.The Kubernetes version is concrete enough to copy. With AKS Workload ID the cluster acts as an OIDC issuer, the pod gets a projected service account token, and Entra validates it against the cluster’s signing keys before exchanging it. The pod must carry the label azure.workload.identity/use: "true" before any of it is injected, which makes the behaviour fail-close.
The permission ceiling
The mechanism the standards conversation leaves out is the ceiling, and it is the one I should have built first.
On AWS the evaluation stacks. An identity-based policy grants the role its normal scope. A session policy narrows one run. A permission boundary caps what any identity-based policy can ever grant that role. A service control policy caps what any principal in the account or organizational unit can do, regardless of what the local role says. Google’s organization policies do something similar in a narrower way, including blocking service account key creation and upload outright. Azure combines RBAC scope with policy applied at the blueprint level so new agent instances inherit it.
Four caps on the same blast radius. The agent's role policy is only the third of them.A ceiling is deterministic and sits outside the agent runtime, outside the orchestration code and outside the model. It is set at grant time rather than request time, so it holds even when the agent’s tool graph changes underneath it. It never needs to understand the agent’s mission. It only needs to be lower than the mission.
The trap: attributes only help if they are trustworthy
AWS session tags let a role assumption carry runtime attributes such as tenant, environment or owning team, which policies reference through condition keys. For a fleet of agents that scales far better than per-agent policy sprawl.
There is a trap. AssumeRoleWithWebIdentity does not accept arbitrary tags the way AssumeRole does, so attributes have to arrive as claims inside the incoming token. The usual workaround is role chaining: assume one role through OIDC, then a second with explicit session tags. That reintroduces the whole problem if the second hop lets the caller assert its own values.
This is the confused deputy in IAM form. A tenant identifier supplied by the caller and trusted by the receiver is the same bug whether the caller is a language model or a CI job. An attribute model that is expressive but attacker-controlled is not a control.
The gap analysis
What adopting SPIFFE/SPIRE would fix
- Credential rotation. Short-lived credentials mean nothing survives the workload that owned it.
- Cryptographic binding. Static API keys go away. What replaces them can only be used by something holding the matching private key.
- Issuance tied to what’s running. The right workload gets the right identity, based on properties anyone can verify.
- Traceability. Every action ties back to a verifiable statement about what was running when it took it.
What adopting SPIFFE/SPIRE would NOT fix
What the agent may do. SPIFFE proves who the agent is. It has no opinion on what the agent is allowed to do. Authentication solved, authorization untouched.
The confused deputy problem. Workload identity does nothing about it, across all four vectors from the second piece in this series: caller-supplied resource identifiers, scope, tenancy, and delegation across boundaries you don’t own. Present valid credentials to a service that trusts them, let the model fill in the parameters, and the service still has no way to tell a legitimate parameter from a planted one.
The gap between the mission and the permissions. AIMS says outright that translating an agent’s mission, written in plain English, into authorization requirements is out of scope. An agent can hold a valid SPIFFE ID, a valid OAuth token and correct tool permissions while acting well outside its mandate, because instructions in its mission widened what it effectively does.
Prompt injection through the data it reads. The CSA whitepaper describes the vector directly: plant adversarial instructions in a source the agent reads, and it misuses credentials it legitimately holds. Perfect workload identity changes nothing here.
The academic perspective
Otsuka et al. (arXiv 2604.23280, “AI Identity: Standards, Gaps, and Research Directions for AI Agents,” submitted April 25 2026) identify five critical gaps that no current technology or regulatory instrument resolves:
- Semantic intent verification. The agent’s declared purpose does not match its observed behavior
- Recursive delegation accountability. When agent A delegates to B delegates to C, who is responsible when C acts maliciously?
- Agent identity integrity. The agent’s own identity can be spoofed or hijacked
- Governance opacity and enforcement. The gap between policy and practice
- Operational sustainability. The cost of maintaining identity governance at scale
The paper concludes that these are structural gaps, not engineering problems, and no amount of additional engineering will close them on its own.
The cost
Deploying SPIFFE and SPIRE changes how agents get packaged, orchestrated and granted access. It means teaching your authorization systems to understand the identities agents now present, and moving from credentials somebody created once to credentials the platform issues continuously.
For a small team that may not be worth it. Service accounts, imperfect as they are, can hold if you pair them with real permission reviews and a tool registry you maintain. How small is small enough depends on what you already run.
There is a middle path the standards framing skips. Before SPIRE there is federation you already own: workload identity federation on your cloud, impersonation instead of keys, and a boundary or SCP under the agent’s role. That gets you short-lived credentials, attested issuance and a hard ceiling without a new control plane to run. It does not give you portable cross-cloud identity or workload-to-workload authentication, which is what SPIFFE is actually for. It does close the static-credential hole, usually in a sprint rather than a quarter.
I have not deployed SPIFFE or SPIRE, and I have not taken that middle path either. The first is a capacity problem. The second is not.
For a larger team it’s infrastructure you need. IBM’s 2025 Cost of a Data Breach Report found 13% of organizations reported a breach of an AI model or application, and 97% of those lacked proper AI access controls IBM, 2025, though that second figure describes the already-breached rather than organizations in general. Entro Security puts 1 in 20 non-human identities at full administrative privilege Entro, H1 2025, on its own customer telemetry with no published sampling method. Treat both as a shape rather than a rate. They point weakly the same way: governing this by hand does not scale to the number of identities involved.
The static credentials this replaces are not a hypothetical risk. The TeamPCP campaign of March 2026, which backdoored LiteLLM, Trivy, Checkmarx KICS and the Telnyx SDK and is covered in the second piece in this series, worked because long-lived API keys sat in one place, readable by anything that could reach the process. That is why the AIMS draft calls static API keys an antipattern.
What the adversary switched off
In July 2026 Unit 42 recovered the configuration of an autonomous attack campaign, after the attacker’s own agent served its home directory over HTTP and exposed the workspace. The operator had turned off the client-side gates across four AI coding tools: dangerously-skip-permissions: true on Claude Code, approvalMode: "yolo" on Qwen Code, disable_response_storage = true on Codex, and CLAUDE_CODE_ATTRIBUTION_HEADER: "0" to suppress attribution.
Unit 42 attach a caveat that matters more than the list: those settings “[do] not impact server-side controls for vendor-hosted platforms.” The provider-side controls held. The actor “attempted to use Western models, but their provider-side controls likely limited their effectiveness,” OpenAI’s safety systems flagged and disabled a linked account, and the operator moved to a more permissive model. The autonomous attempts never achieved compromise; the campaign’s confirmed impact came from manual exploitation.
Every control the operator could switch off sat on their side of the boundary. The ones that held were enforced where they could not reach.
A month later, in the incidents Tenable analysed, agents “bypassed their own AI safety guardrails by reframing the offensive operation as ‘authorized penetration testing’.” A control written as an instruction, removed by an instruction.
Where each control sits
| Layer | What it settles | What it cannot settle | Available today |
|---|
| Workload identity | Which process is calling, proven cryptographically | What that process may do | SPIFFE/SPIRE; cloud workload identity federation |
| Delegated identity | On whose authority it calls | Whether the authority fits the task | OAuth 2.0, RFC 8693 act claim |
| Permission ceiling | The maximum reachable, set before runtime | Anything inside the ceiling | SCPs, permission boundaries, org policies |
| Runtime authorization | Whether this specific call is allowed now | Whether the mission was legitimate | Policy engines and gateways, built per deployment |
| Mission-to-permissions | Nothing | The gap the AIMS draft calls out of scope | No standard |
The first three rows are shipping software. The fourth is something you build. The fifth is open, and the draft says so.
What’s next
Four pieces in, every control covered so far bounds what an agent can reach: what its scope enumerates, what authority its tool calls carry, what its defences block, what its credentials prove. None of them bounds what enters the model’s context once a permitted read succeeds. The final piece is a design proposal for the control that is missing.
Primary sources
Standards and drafts
Cloud provider documentation
- AWS, Security best practices in IAM
- AWS, Policies and permissions in IAM, covering session policies, permission boundaries and SCPs
- AWS, Using SAML session tags for ABAC
- AWS, Security Reference Architecture for generative AI agents
- Microsoft, Apps and service principals in Entra ID
- Microsoft, Workload identity federation concepts
- Microsoft, Entra Workload ID with AKS
- Microsoft, Protect against consent phishing
- Google Cloud, Service account impersonation
- Google Cloud, Best practices for using service accounts securely
- Kubernetes, RBAC good practices
Research and incident reporting
- Otsuka et al., “AI Identity: Standards, Gaps, and Research Directions for AI Agents”, arXiv:2604.23280, April 2026
- CSA, The Non-Human Identity Governance Vacuum, May 2026
- NHIMG, “SPIFFE and AI agent identity expose the next authorization gap”
- Kenneth G. Hartman, “Your AI Agent Is an Easily Confused Deputy”, SANS, on the TeamPCP / LiteLLM compromise
- Unit 42, “Autonomous AI cyber attack campaign”, July 2026
- Tenable, “The agentic AI threat cluster”, August 2026
Earlier in this series