The identity problem behind AI agents
An application that calls an API for a user normally answers one identity question: who is the user?
An AI agent introduces several more:
- Which user authorized the work?
- Which logical agent is acting?
- Which running workload actually made the call?
- Which agent execution is involved?
- Which transaction and purpose does the call belong to?
- Which service made the current network hop?
Putting every answer into a single sub claim creates a dangerous illusion. A logical agent name is not cryptographic proof of the running process. A workload identity is not the user. A transaction identifier is not a caller identity.
This implementation keeps five values separate:
-
UserID: the authenticated human or upstream principal -
AgentID: the approved logical agent definition -
AgentInstanceID: one execution of that agent -
SPIFFEID: the attested runtime workload -
TransactionID: the immutable identifier for the delegated action
Why a user access token is not enough
Passing the original user token through every service has three problems.
First, downstream services cannot reliably distinguish the user from the agent acting for the user. Second, a broadly scoped user token may reach systems that never needed it. Third, the token usually says little about the purpose of this specific transaction.
The safer model is the Transaction Tokens architecture implemented by Tokenetes. An external endpoint exchanges the incoming authorization at a controlled Transaction Token Service boundary. The result is a short-lived signed Txn-Token containing immutable identity and authorization context for one call chain.
Why an agent_id field is not proof
An HTTP request can claim any agent name. If the server authorizes that value directly, one workload can impersonate another by changing a string.
The logical AgentID must instead come from trusted policy that maps a cryptographically verified workload identity to an approved agent. The caller can request an operation, but it cannot choose its identity.
Immutable context and authenticated hops
The Txn-Token carries immutable delegated context:
user + logical agent + original workload + transaction + purpose
Each network connection independently proves the immediate caller through SPIFFE mTLS:
verified transaction context
AND verified immediate caller
AND target policy
The token is not rewritten at every hop. That avoids giving intermediate services the power to remove or forge earlier context. The same transaction ID can be correlated across the agent, gateway, MCP server, and protected API.
The target flow
User OAuth token
-> AI agent
-> PingFederate RFC 8693 token exchange
-> short-lived transaction JWT
-> MCP gateway
-> MCP server
-> protected API
In this design, PingFederate fills the logical Transaction Token Service role. SPIRE supplies a JWT-SVID as agent workload evidence during exchange and X.509-SVIDs for mTLS between workloads. PingAuthorize evaluates the verified Txn-Token context at the gateway.
Tokenetes is the reference point for the call-chain model: a Txn-Token is minted once for the external invocation, remains immutable as it moves downstream, and is accepted only inside its trust domain. The immediate network caller is still authenticated separately.
The result is not a new identity system. It is a way to combine existing user, workload, delegation, transport, and policy controls without confusing their responsibilities.
Next: Using PingFederate token exchange as the delegation boundary
GitHub Repository: https://github.com/darkedges/pf-tts
This article was originally published by DEV Community and written by DarkEdges.
Read original article on DEV Community