Agent infrastructure
Platform integration
Agent identity vs user identity: why collapsing them breaks audit trails, and how delegated auth at the runtime layer is the boundary that actually holds.

The agent isn't the user. Treat it like one and you'll ship a system your security team can't approve, your auditors can't reconcile, and your customers can't trust.
Most AI agent deployments we've seen collapse identity in one of two ways: they run everything as a shared service account, or they hand the agent a user's session and call it delegation. Both feel expedient. Both create the same problem — the audit log stops answering the question that matters. Who actually did this, and were they allowed to?
Here's the position: agent identity and user identity are two different things, they need to stay two different things, and the runtime — not the prompt, not the framework — is where that separation gets enforced.
The fastest way to ship an agent is to give it a service account with broad permissions and let it act on behalf of anyone who talks to it. It works in a demo. It fails the first serious security review.
When every tool call executes as agent-service-01, three things collapse at once. Permissions no longer reflect the requesting user — the agent can reach data the user couldn't. Audit logs record the agent, not the person whose intent triggered the action, so incident response can't reconstruct what happened. And rate limits, quotas, and data residency rules all get evaluated against the wrong identity.
This isn't a theoretical concern. It's the reason Gartner has predicted that over 40% of agentic AI projects will be cancelled by end of 2027 — inadequate risk controls sit near the top of the list. Service-account agents are one of the clearest examples of that risk pattern.
The correct model is delegation. The user authenticates. The agent acts as that user, through a token the user granted, scoped to what the user is allowed to do. Every tool call inherits the user's permissions, appears in the user's audit trail, and counts against the user's quota.
This is what OAuth 2.1 was built for, and it's the model MCP's authentication spec adopts. If you've done the work of standing up delegated auth for your APIs, you already have the primitives — you just need to keep them intact when the caller happens to be an agent instead of a browser. We've written more on the mechanics in our guide to OAuth for AI agents and a comparison of agent authentication methods.
The key move is refusing to compress two identities into one. The user identity says who authorised the action. The agent identity says which system executed it. You want both, on every call, in every log line.
The agent needs its own identity too. Not as a substitute for the user's — as a second dimension.
Why does this matter? Because "a Claude agent built by the internal ops team acting on behalf of user X" and "a third-party agent embedded in a partner's product acting on behalf of user X" have very different risk profiles, even when the user is the same. You want to be able to revoke the third-party agent's access without revoking the user's account. You want to see which agents are generating anomalous call patterns. You want to enforce different rate limits for different classes of caller.
That requires the agent to carry its own verifiable identity — a client ID, a registered application, a signed identifier — alongside the user token. The runtime that executes tool calls needs to check both.
Prompt-level rules don't enforce identity. A system prompt that says "only act on data belonging to the authenticated user" is a suggestion, not a control. Frameworks that pass a user ID as an argument to a tool are relying on the tool to check it — which every tool then has to remember to do, correctly, in every code path.
The boundary holds when tool execution runs under the authenticated user's credentials by default, at the runtime layer, with no path around it. The tool doesn't receive a user_id parameter it might forget to validate. It receives a request that is already scoped to that user, because the runtime injected the user's token into the call. This is the same argument we made about AI agent guardrails — the wrong layer keeps getting blamed for problems the runtime should solve.
Run the identity check where it can't be forgotten. That's the runtime.
This is one of the things we made a design decision about early. In the Pontil model, tool calls execute as the authenticated user — always, at the runtime layer, not as a shared service account. The user's OAuth token flows into every downstream API call. Permissions, data visibility, and audit trails honour the real identity of the person whose intent triggered the action.
Agent identity is separate. The agent that invoked the tool is recorded as a distinct dimension in the audit trail, so you can answer "which agent did this on whose behalf" without collapsing the two. That separation is what makes the security review tractable — and it's part of why we describe Tools-as-a-Service as infrastructure for agent access rather than a framework for building agents.
If you're evaluating an agent architecture right now, run this test: pick a tool call your agent might make and trace how identity flows through it. Which credentials hit the downstream API? Whose name appears in the audit log? What happens when the user's permissions change mid-session?
If the answer involves a service account, a user_id argument the tool has to check itself, or a token that outlives the user's session, you have work to do before production. Not because it will break the demo — it won't. Because it will break the day your first customer's security team asks for the audit trail and you can't produce one that names a person.
The agent isn't the user. Keep them separate. Let the runtime prove it on every call.
Stay up to date on the ever changing agentic landscape.