Your engineering team deployed an MCP server last week. It exposes three tools to the agent: a SQL query interface to the production database, a Slack-posting endpoint, and a write API for updating customer records. The agent authenticates with a service token your team generated through the admin console. That token lives in a shared password manager. It expires never.
Three questions you can't answer with confidence right now: who provisioned it, what scopes it has, what it did yesterday. The agent has been running for two weeks. The audit log shows a service account named "claude-prod-mcp" performing 1,400 database reads and 47 writes. For each of those actions, three scenarios are equally plausible: a human user requested it through the agent, an automated workflow triggered it, or the agent hallucinated and did it on its own. Your audit log can't tell them apart. The practitioner who named this problem, Kane Narraway, calls it the attribution gap, and your response to each of those three scenarios is supposed to be completely different.
This is AI agent identity governance. The problem didn't exist twenty-four months ago. It exists in every company shipping software now.
The diagnosis everyone shares
In the last twelve months three groups have converged on the same picture.
The practitioners (Kane Narraway's posts at kanenarraway.com being the most cited): OAuth scopes are too coarse for agent use cases. "You don't get 'read the last 5 emails about Project X.' You get 'read access to your entire inbox.' Forever." Tokens are persistent grants. Tooling to deploy agents is miles ahead of tooling to govern them.
The model labs (Anthropic's Zero Trust for AI Agents whitepaper, 2026): static API keys are no longer a legitimate entry point even at the Foundation tier. Traditional access controls won't prevent agents from misusing legitimate permissions. The design test that matters is "does this make the attack impossible, or just tedious?"
The identity vendors (Iden, internal POV): the unit of governance has to change. From a static entitlement to a session with declared intent, scoped credentials, behavioral baselines, and automatic expiry. The standing-entitlement model that worked for employees doesn't work for something that never sleeps.
The diagnosis is consensus. The interesting question is what to build next.
What's actually new about agent identity
Three things are different from the service-account model the industry has used for the last decade.
The decision boundary moved. Service accounts in the traditional model represent a system acting on its own. An agent represents an action that originated in a human request but executes outside that human's session. The attribution path runs through the agent.
The action surface expanded. A service account typically calls one API endpoint with a narrow scope. An MCP-style agent can call dozens of tools, chained, with different scopes per call. The same agent instance might query a database, post to Slack, and modify a record in the same task. The scope envelope is larger by an order of magnitude.
The lifecycle compressed. Agents get created during development, used during testing, sometimes promoted to production, often forgotten. The agent lifecycle resembles "feature-branch identity" more than "employee identity." The off-ramp is mostly missing.
These three shifts mean the controls that worked for service accounts don't work for agents.
The four identity patterns in production today
Four patterns, in order of how often we see them in the field.
Pattern 1: Service account with long-lived token (default, broken)
The agent authenticates with a token your team generated in the admin console. The token has wide scopes because narrowing them required more upfront thought than anyone had time for. It lives in a shared secret store. It expires never, or it expires in eighteen months when someone gets paged.
This is what most teams do first. It's exactly the model the security industry spent ten years trying to retire for service-to-service auth. Now we've reintroduced it for agents.
What goes wrong: no ownership, no expiry, no scope narrowing, no audit attribution. Anthropic's framing applies cleanly: rotating these tokens "does not raise the cost to an AI-assisted attacker meaningfully." If the credential is exfiltratable, model-assisted code analysis will find it before your rotation policy does.
Pattern 2: Federated identity with OAuth scopes
The agent obtains tokens through OAuth 2.0 with scoped permissions, refreshed via a refresh token, time-bounded per session. The authentication flow runs through your IdP (Okta, Entra, or similar), often using Okta's Cross-App Access (XAA) for token federation across SaaS apps. The agent's identity is registered as a first-class application with explicit scopes declared.
This is the right floor. It separates "who can authenticate the agent" from "what the agent can do." Scopes are declared in advance and reviewable.
What still goes wrong without IGA: scope sprawl, plus the coarse-scope problem Kane Narraway named. OAuth scopes give you inbox.read, not inbox.read where subject contains "Project X" and date > yesterday. Without a governance layer, the OAuth client accumulates scopes the same way users accumulate group memberships. Three quarters in, the agent has read-write on systems it never should have touched, and the runtime layer has no way to narrow the grant by task.
Pattern 3: Ephemeral credentials via STS-style brokering
The agent doesn't hold long-lived credentials at all. It exchanges a short-lived JWT (issued by the IdP based on the workload identity) for an even-shorter-lived scoped credential issued by a Security Token Service. AWS STS, GCP Workload Identity Federation, and Azure AD Workload Identity all implement variants of this. SPIFFE (Secure Production Identity Framework for Everyone) provides the cryptographic substrate that roots the workload identity in hardware-bound material.
This is the right ceiling for most production agents. Credentials never live in a password manager. The token-issuance audit trail captures every credential creation. Revocation is immediate because nothing persists. Anthropic ties this to its Advanced tier: an attacker who compromises the runtime "finds no cached credentials to steal."
What still requires work: the issuance policy. Some human or system decides who can request what scope at what frequency. That policy is governance work, separate from the issuance mechanism itself.
Pattern 4: MCP server with delegated authority
The Model Context Protocol introduces a different model. The agent doesn't hold credentials directly. The MCP server holds them, and the agent calls the server with a session token that delegates a narrower scope. The server enforces what the agent can do; the agent doesn't have a service account of its own.
This is the cleanest model architecturally. It separates agent identity from tool credentials. The MCP server becomes the audit and policy boundary.
What's new: most teams deploying MCP servers haven't worked out the governance layer yet. The MCP server itself is now a privileged identity. Who provisioned it, who can modify its tool config, what happens when it's retired. These are the same questions as service accounts, just one layer up. And the MCP guardrails the server enforces are bypassable: an agent willing to use a direct API key instead routes around them entirely. The first documented in-the-wild malicious MCP server (Anthropic, 2026) impersonated a legitimate email service and secretly copied every sent message.
Why these four patterns aren't enough on their own
Each identity pattern maps to a vendor category that does part of the work. None of them, alone or stacked, closes the gap for agents specifically.
| Category | Vendor example | What it does | Where it fails for agents | |---|---|---|---| | IAM (Cross-App Access) | Okta XAA | Federates tokens across SaaS apps with declared scopes. | Solves authentication. Does nothing about what the agent does once the token is in hand. | | IGA | SailPoint "agent identity" | Treats agents as a new identity type in the catalog. | Same quarterly reviews, same standing entitlements. The model breaks for ephemeral agents that exist for minutes. | | PAM | CyberArk | Vaults credentials, rotates them, brokers privileged sessions. | Still grants full blast radius during use. The session itself isn't intent-bound; the agent can do anything the vault gives it access to. | | MCP guardrails | In-band MCP servers | Enforce tool config at the server boundary. | Optional, in-band, agent-cooperative. An agent willing to ignore the MCP server or use a direct API key bypasses them entirely. | | AI gateways | Prompt-layer DLP | Pattern-match prompts and tool calls. | Can't enforce scope at the resource. The SaaS API still receives a privileged token. The gateway is a sieve, not a fence. |
This is the table you want to keep in your arsenal. Every conversation about AI agent governance starts with one of these categories assumed as "the answer." None of them, individually, can satisfy the audit, attribution, and least-agency requirements Anthropic's framework lays out.
Intent: the missing primitive
The diagnosis is well-mapped. The prescriptive answer, from where we sit, is that the missing primitive isn't another tier of scopes or another credential type. It's declared intent.
Today, when an agent acts, the runtime evaluates the question: does this credential hold the necessary permission for this API call? That question is too coarse for agent behavior, because the same credential is correct for a thousand legitimate tasks and a thousand misuse cases.
The richer question is: does this action align with the intent the session declared when it started?
A session begins. The user (or the upstream agent, or the scheduled trigger) declares: I am asking the agent to summarize the last quarter's revenue from the data warehouse and post a summary to the #finance Slack channel. That declaration becomes the runtime constraint. Every subsequent tool call gets evaluated against it: is SELECT * FROM customers aligned with the declared intent? Is slack.post(channel='#engineering') aligned? Is customers.update() aligned? Two of three are obviously not. The first is borderline (over-broad query when the task wanted aggregates) and could prompt the agent to narrow on its own.
What this changes:
- The unit of governance becomes the session, not the entitlement. Sessions have declared intent, scope, expected duration, and risk profile. Entitlements have none of those.
- Credentials are intent-bound and ephemeral. They exist while the session is open. They evaporate when it closes. There is no standing token to steal because the token is born and dies inside the session.
- The audit trail captures intent, action, and outcome. When the auditor asks "why did this happen," the answer is structured: the session declared this intent, performed these actions toward it, produced this outcome. Three scenarios that look identical in current audit logs become distinguishable.
- Behavioral baselines have something to compare against. Anthropic's whitepaper mentions behavioral conformance as monitoring (A1, p.30). With intent as a primitive, behavioral conformance becomes input to access decisions: an agent whose actions drift away from declared intent loses scope automatically.
This is where Iden's POV diverges from "AI-powered SailPoint." We don't believe the right answer is to add an "agent" identity type to the existing catalog and keep the quarterly-review model. The right answer is to change the unit of governance.
The attribution gap, in detail
The attribution gap deserves its own treatment because every other piece of agent governance depends on it.
Kane Narraway describes three scenarios that today produce identical audit log entries:
- The user requested this action directly. (They typed it into Claude or clicked through a workflow.)
- The user instructed an agent to perform it as part of a larger task. (The action is a tool call inside the agent's plan; the user authorized the goal, not the specific tool call.)
- The agent decided to perform it on its own. (No explicit user instruction; the agent inferred or hallucinated the need.)
In an Okta-or-Entra-style log: same actor, same timestamp, same API call, same outcome. The security team's response to each is materially different. Scenario 1 is normal. Scenario 2 needs verification that the goal-to-tool-call inference was reasonable. Scenario 3 is a potential confused-deputy or hallucination incident.
Closing the gap requires the audit log to capture five things per action:
- The agent identity that performed it (not a shared service account; a specific agent instance with version metadata).
- The session that contains it (with the declared intent).
- The triggering origin (the human prompt, the scheduled trigger, the upstream agent that delegated it).
- The scope under which the action ran.
- The outcome.
Reconstruct that, end to end, and the three scenarios stop looking identical. Most companies are nowhere close. The audit log most teams have today is a sequence of service-account API calls with no chain of custody back to a human user or a declared session.
The lifecycle problem
Agent lifecycle resembles software lifecycle more than identity lifecycle. The states:
- Built. Developer creates an agent and tool config during a feature branch.
- Tested. Agent runs against a staging environment with a development service account.
- Promoted. Production credentials get provisioned, often by hand, often with wider scopes than the feature requires.
- Operating. Agent runs against production until something changes.
- Updated. Tool config changes, scopes drift, credentials rotate (maybe).
- Retired. Often missing. Agent gets deprecated. Credentials stay live.
The retirement step is where most agents accumulate as ungoverned identities. Same pattern as the orphaned service account, with a faster generation rate.
Patterns that break agent governance
A few common failure modes worth naming.
The shared agent identity. One service account used by every agent the team has built. No way to differentiate "claude-prod-mcp running the data-pipeline task" from "claude-prod-mcp running the support automation task." Same identity, different intent, indistinguishable in the audit log.
The development-to-production token leak. An agent originally tested with a development token gets promoted to production with the same token still in the config. Production traffic flows through development credentials. Common in early-stage teams.
The scope-creep that nobody noticed. Each tool integration added a scope. After six months the agent's OAuth client has thirty scopes, four of which are write access to systems nobody remembers granting. Nobody runs access reviews on agent identities.
The retired agent that kept its credentials. The feature was deprecated. The agent's name was removed from the team's project board. The token never rotated. Six months later it's still in some script's environment variables, still active, still privileged.
The MCP server with no owner. The MCP server runs as a privileged identity but isn't in any HR system. Nobody owns it. When the engineer who created it leaves, the server keeps running with the same scopes, no longer attributed to anyone.
The confused deputy across agents. Anthropic, A1 p.10: a compromised low-privilege agent relays valid-looking instructions to a high-privilege agent, which executes them without verifying the original user's intent. Amplified when agents coordinate and delegate. Without intent-binding, the high-privilege agent has no way to know the upstream instruction is illegitimate; it sees a peer agent making a request and the request looks well-formed.
The MCP server impersonation incident. A real incident, documented by Anthropic in 2026: a malicious MCP server published to a public registry impersonated a legitimate email service. Agents that installed it routed messages through the imposter, which silently copied every sent message. The defense pattern is signed, owned MCP servers from a known provenance, plus runtime evaluation of tool behavior. Treating "the MCP server" as a trusted boundary breaks the moment a server is compromised or impersonated.
Memory and context poisoning. Shared multi-tenant memory or context windows can be manipulated so the agent's later actions drift toward goals it never declared. Defense pairs session isolation, context integrity validation, and intent-evaluation that catches drift before it produces harmful actions.
What working agent governance looks like
Seven things have to be true.
- Every agent has a first-class identity record. Not a shared service account. Each agent instance is registered separately, with owner, version, scope manifest, intended lifecycle. SPIFFE (or an equivalent substrate) cryptographically roots that identity where possible.
- Sessions declare intent at start. The runtime evaluates each subsequent action against the declared intent. Drift triggers either scope contraction or a halt-for-review.
- Scopes are declared explicitly and reviewed. The OAuth client's scope set or the MCP server's tool list is a governed artifact, reviewed continuously, not quarterly. Static API keys are not a legitimate entry point.
- Credentials are ephemeral by default. Long-lived tokens require explicit approval and time-bound expiry. The default is STS-style brokering with session-scoped credentials.
- Every action is attributable end to end. The audit log captures agent identity, session, triggering origin, scope, and outcome. The three indistinguishable scenarios become distinguishable.
- Retirement is a first-class lifecycle event. When an agent is deprecated, its credentials revoke, its identity is marked offboarded, its audit history is preserved for retention windows.
- Non-human identity is governed alongside human identity. The same access review covers people and agents. The same offboarding flow handles departing engineers and deprecated agents.
Anthropic's design test is the right one to apply to each: does this make the attack impossible, or just tedious? If the answer is "tedious," that's a control to layer with something stronger.
Where Iden fits
Iden treats agents as first-class identities, alongside humans, contractors, service accounts, and API keys. The same lifecycle that handles a new hire's birthright access handles an agent's deployment. The same access review that includes the engineering team includes the agents that engineering team built. The same offboarding flow that revokes a person's credentials revokes a retired agent's credentials.
What we add on top of the substrate (SPIFFE, OAuth, STS, MCP): intent-bound sessions, runtime evaluation against declared intent, behavioral baselines that earn or remove scope, and an audit trail that closes the attribution gap. SPIFFE answers who the agent is. Intent answers what it should be permitted to do in a given session. The two layers compose.
The teams hitting this hardest right now are the ones who shipped MCP servers in the last six months and haven't yet figured out who owns them. If that describes your team, the work isn't to build more agents. It's to make the ones you have legible: identified, intent-bound, audit-traceable, and governed by the same machinery that governs your people.