Agentic Authentication & Authorization - Part 1: Fundamentals

Nov 14, 2026 min read

AI agents act for people, choose their own actions at runtime, and read content that may be hostile. The identity standards most systems run on assumed none of that. This post sets out the problem, the three layers needed to handle it, and a reference architecture built on standards that exist today.

The series has seven parts:

  1. Fundamentals (this post): the problem, the three layers, and the core architecture
  2. Agent identity: workload identity, client registration, SPIFFE and WIMSE
  3. Delegation: token exchange, actor chains, agent-to-agent hops
  4. MCP authorization in practice: OAuth 2.1, protected resource metadata, audience binding
  5. Tool-call authorization: AuthZEN and COAZ-MCP, decisions that depend on tool arguments
  6. Human in the loop: consent, step-up, approvals after a deny
  7. Operating in production: decision logs that record user and agent, policy lifecycle, signal stream health, revoking an agent, and incident response

Why agents break the identity model

Identity standards were built on two assumptions: a person is present, and the request reflects that person’s intent. When you click “Send” in a mail client, the OAuth token, the click and the intent all line up. AI agents break both assumptions. The agent decides at runtime which tools to call and with which arguments, often with nobody watching.

Every agent request therefore involves at least three parties:

  • The user (the principal): whose authority the work runs under
  • The agent (the actor): the software that decided to make this call
  • The tool or resource: the MCP server, API or dataset being called

Most deployments today collapse the first two into one. The agent holds the user’s token, so every call it makes looks exactly like the user made it. That is the classic confused-deputy problem: a component with legitimate authority is tricked, or simply reasons its way, into using that authority for something nobody asked for. Prompt injection makes this concrete. A poisoned document can turn “summarize my inbox” into “forward the finance thread to this address”, and the resulting API call is fully authorized.

The result: the agent holds the full scope of the user’s access, but uses it in ways the user never anticipated and the logs cannot tell apart. This series is about closing that gap with standards that exist today, and being honest about where they stop.

Three questions, three layers

“Agent auth” is usually discussed as one problem. It is three, and each has a different answer and a different set of standards.

LayerThe questionAnswered byStandards involved
Agent authenticationWhat software is this, and can it prove it?The agent’s own credentialOAuth client authentication, Client ID Metadata Documents (IETF draft), DPoP (RFC 9449), workload identity (SPIFFE, IETF WIMSE working group)
DelegationWho authorized it to act, for whom, and with what scope?The access token and its claimsOAuth 2.1 authorization code + PKCE (IETF draft), Resource Indicators (RFC 8707), Rich Authorization Requests (RFC 9396), Token Exchange (RFC 8693) with the act claim
Per-action authorizationCan this specific call, with these arguments, happen right now?A policy decision at call timeAuthZEN Authorization API 1.0 (Final), COAZ-MCP binding (Draft 1)

The first two layers decide whether a token is valid. The third decides whether a valid token should be used for this call. OAuth was designed for the first two. A scope like files.write tells you the agent may write files; it cannot tell you whether deleting 4,000 of them at 3 a.m. matches what the user wanted.

This split is the core idea of the series: each layer has its own owner, its own failure modes and its own maturity. Later parts of the series take them one at a time.

Agents are not service accounts

A service account is a non-human identity, but its intent is fixed in code: the nightly export job always exports, and you can read the code to know what it will do. An agent is non-human too, but it chooses its actions at runtime, on someone else’s behalf, from inputs that may be hostile.

Human userService accountAI agent
IdentityA person, authenticated by the IdPA workload credentialA workload credential plus a delegating user
Where intent comes fromThe person, at the moment of the requestCode, reviewed before deploymentA model’s reasoning over prompts, documents and tool output
PredictabilityMostlyFullyLow: the same task can produce different calls
SessionInteractive, boundedLong-running, no userLong-running, often with no user present
Can be manipulated by content it readsPhishing, rarely at scaleNoYes: prompt injection
Accountable partyThe personThe owning teamUnclear unless the token records both user and agent

The last row is the one that matters most in an incident. If your logs cannot say “agent X did this on behalf of user Y”, you cannot tell an agent mistake from a stolen session, and you cannot revoke one without the other.

In practice, agents need both treatments at once: a workload identity of their own (like a service account) and a delegated, bounded grant from a user (like a person’s session).

Where OAuth scopes stop

Scopes are often enough. A read-only tool on low-sensitivity data needs a well-scoped, short-lived, audience-bound token and nothing more. Putting a policy engine in front of it adds latency and a new failure mode, with no real security gain.

The calculation changes in three situations:

  1. The answer depends on conditions at call time. Rich Authorization Requests (RFC 9396) let a token carry structured details fixed at consent, such as a payment’s amount, currency and creditor. What a token cannot do is evaluate what only exists when the call happens: today’s running total, the user’s current risk, a payee added five minutes ago. Once those matter, you need a decision at call time.
  2. Nobody is watching. Background agents and agent-to-agent chains have no user to notice a strange call. The token must carry who delegated what, to whom, and expire quickly.
  3. One record across tools. If an auditor asks “what did agents do on Alice’s behalf last week?”, a central decision log answers it. Logs scattered across ten MCP servers do not.
Scopes are enough only for low-risk calls whose arguments don't matterIs the tool read-only,on low-sensitivity data?Does the answer depend on call-timeconditions (running total, risk, payee)?Does the agent run with no user present,or call other agents?Do auditors need one record of agentdecisions across tools?Scopes are enoughKeep tokens short-lived and audience-boundAdd a per-call decisionAuthZEN PDP at the MCP gatewayAdd delegation controlsToken exchange with an act claimAdd a per-call decisionOne decision log across toolsScopes are enoughPlus audience binding and short token lifetimesyesyesyesyesnononono
Scopes are enough only for low-risk callswhose arguments don't matterIs the tool read-only,on low-sensitivity data?Does the answer depend on call-timeconditions (running total, risk, payee)?Does the agent run with no user present,or call other agents?Do auditors need one record of agentdecisions across tools?Scopes are enoughKeep tokens short-lived and audience-boundAdd a per-call decisionAuthZEN PDP at the MCP gatewayAdd delegation controlsToken exchange with an act claimAdd a per-call decisionOne decision log across toolsScopes are enoughPlus audience binding and short token lifetimesyesyesyesyesnononono

Work down the questions in order: the first “yes” tells you which layer to add. Most tools in a typical deployment stop at the first question, and that is fine.

Reference architecture

The reference architecture has four paths: one to get a token, one to carry delegation across hops, one to decide each call, and one to react when something changes.

Every tool call carries both user and agent, and is checked before it runsUserthe principalAuthorization serverIdP, issues tokensAgent (MCP client)the actorMCP gateway (PEP)enforces each callMCP server (tool)OAuth resource serverRisk signalsIdP, MDM, EDRAuthZEN PDPdecides per callDownstream APIits own audience1 consents (code + PKCE, resource)delegates2 token for one audience3 tools/call5 if permit4 evaluatedecision6 new token, act claimSSF / CAEP
Every tool call carries both user and agent,and is checked before it runsUserthe principalAuthorization serverIdP, issues tokensAgent (MCP client)the actorRisk signalsIdP, MDM, EDRMCP gateway (PEP)enforces each callAuthZEN PDPdecides per callMCP server (tool)OAuth resource serverDownstream APIits own audiencedelegatesSSF / CAEPdecision1234561consents (code + PKCE, resource)2token for one audience3tools/call4evaluate5if permit6new token, act claim

Steps 1 and 2 are authentication and delegation, steps 3 to 5 are the per-action layer, and step 6 keeps delegation intact across the next hop. The risk-signal path runs the whole time, independently of any request.

The authentication path: getting a token

Under the current MCP authorization spec, a protected MCP server is an OAuth 2.1 resource server and the MCP client is an OAuth client. The client calls the server, gets a 401 pointing to the server’s Protected Resource Metadata (RFC 9728), and discovers the authorization server from there.

The client then needs a client ID. The spec now prefers Client ID Metadata Documents, where the client is identified by an HTTPS URL it controls, and marks Dynamic Client Registration as deprecated. The user consents through authorization code with PKCE, and the client validates the iss in the response (RFC 9207) to stop mix-up attacks.

The delegation path: one token, one audience

The client must send the RFC 8707 resource parameter in both the authorization and token requests, and the server must reject any token not issued for it. A server must not accept or pass along any other token.

That creates a problem for the next hop. When the MCP server needs to call a downstream API, it cannot reuse the token it received. It exchanges it through OAuth 2.0 Token Exchange (RFC 8693) for a new token aimed at the downstream API.

The new token carries an act claim naming the current actor. Nested act claims record earlier actors, so the chain stays visible: Alice, via the finance assistant, via this MCP server. RFC 8693 is explicit that prior actors are informational only and must not drive access control, so policy should key on the user and the current actor.

Two OAuth working-group drafts extend this. Identity Chaining, now in the RFC Editor queue, carries identity across trust domains by combining Token Exchange with JWT authorization grants (RFC 7523). Transaction Tokens carry identity and authorization context through internal services inside one trust domain. The Delegation part of the series covers the mechanics.

The per-action path: deciding each call

The gateway (or the MCP server itself) acts as a Policy Enforcement Point. Before forwarding a tools/call, it sends an AuthZEN evaluation request to a PDP with the user, the agent, the tool and the arguments. Only "decision": true lets the call through. The COAZ-MCP draft standardizes this mapping; until it is final, you write the mapping yourself.

When a scope is simply missing, the MCP spec has its own step-up: the server answers 403 with insufficient_scope, and the client re-authorizes with the larger scope set. That handles “you need more scope”. It does not handle “this specific transfer needs a human”, which is the PDP’s job.

The async path: reacting when something changes

Tokens are issued once; risk changes all the time. If the user’s session is revoked or their device falls out of compliance, a CAEP event delivered over the OpenID Shared Signals Framework (both Final) should reach the PDP and the authorization server. The next tool call is then denied, even though the agent’s token is still valid. Agents often hold tokens far longer than people do, so this path matters more for them than for interactive users.

What a per-call decision looks like

Here is an AuthZEN evaluation request an MCP gateway might send before letting an agent call a transfer_funds tool. It follows the shape of a COAZ-MCP declared mapping: the user from the token’s sub, the agent from its client_id, the action and resource taken from the tool call, and the arguments placed in context where policy can act on them. The gateway sends it as POST /access/v1/evaluation:

{
  "subject":  { "type": "identity", "id": "alice@example.com" },
  "action":   { "name": "transfer_funds" },
  "resource": { "type": "account", "id": "acct-ops-001" },
  "context": {
    "agent": "https://agents.example.com/finance-assistant",
    "amount": 25000,
    "currency": "EUR",
    "payee_known": false,
    "user_present": false
  }
}

A policy can now say something a token alone cannot evaluate: an agent may initiate payments up to 1,000 EUR to known payees; anything larger, or to a new payee, needs the user’s confirmation. The PDP returns "decision": false with context telling the PEP to ask the user. The Human in the loop part of the series covers that flow.

The request and response shape is Final in AuthZEN Authorization API 1.0: subject, action and resource are required, context is optional, and the response is a boolean decision with an optional context the PEP can use. The mapping from an MCP tool call is defined by COAZ-MCP, still Draft 1. Without a declared mapping, its default uses tools/call as the action and the tool name as the resource; the payment fields above assume the tool declares its own mapping.

Failure modes

Failure modeWhat goes wrongMitigationReference
Token passthroughEvery MCP server becomes a credential relay, and the downstream API can no longer tell who is callingA new token per hop, issued for that hop’s audienceMCP Authorization 2026-07-28; RFC 8693
Tokens without a bound audienceA compromised server can replay a token it received at any other serverSend resource on every authorization and token request; servers reject tokens not issued for themRFC 8707
Long-lived bearer tokens held by agentsA standing credential with no user present; if stolen, it works from anywhereShort lifetimes, re-delegation for long tasks, sender-constrained tokens, revocation that reaches the agentRFC 9449 (DPoP); CAEP 1.0
Injected intentA prompt-injected agent makes a call its token fully allowsA decision per call on high-risk tools, using the arguments; user confirmation where neededAuthZEN 1.0; CIBA Core 1.0
Fail-open by accidentThe gateway cannot reach the PDP and lets tools/call throughDecide per tool: fail-closed for payments and deletion, fail-open with logging only for low-risk readsNo standard; a design decision

Token hygiene fixes the first three rows. It cannot fix the fourth, which is why the per-action layer exists. The fifth is decided whether or not you write it down: if you haven’t, your gateway’s default has decided for you.

Standards status (November 2026)

The authentication and delegation layers rest on finished RFCs. The per-action layer has a final core API and draft agent profiles. The agent-identity layer is the least settled: one IETF working-group draft addresses AI agents directly, next to many individual drafts.

StandardStatus (checked 14 Nov 2026)LayerWhat it gives you
MCP Authorization, revision 2026-07-28Current revision; authorization itself is OPTIONALAuthentication + delegationMCP server as OAuth resource server, PRM discovery, mandatory resource parameter, audience validation, no token passthrough
OAuth 2.1IETF WG draft -17 (Oct 2026); MCP still cites -13DelegationPKCE everywhere, no implicit grant
RFC 9728 Protected Resource MetadataRFCAuthenticationHow a client discovers which authorization server protects a resource
RFC 8707 Resource IndicatorsRFCDelegationTokens bound to one audience
RFC 8693 Token ExchangeRFC (Jan 2020)DelegationA narrower token for the next hop, with an act claim naming the actor
RFC 9396 Rich Authorization RequestsRFC (May 2023)DelegationStructured grants (actions, amounts, creditors) fixed at consent
RFC 9449 DPoPRFC (Sep 2023)Agent authenticationTokens bound to the client’s key pair
OAuth Client ID Metadata DocumentIETF WG draft -03 (Nov 2026); MCP says SHOULD support and deprecates Dynamic Client RegistrationAgent authenticationA client identified by an HTTPS URL it controls
OAuth Identity ChainingIETF WG draft -17, in the RFC Editor queueDelegationCarrying identity across trust domains
OAuth Transaction TokensIETF WG draft -11, WG consensusDelegationIdentity and authorization context through internal services
IETF WIMSE working groupActive WG; its working-group draft draft-ietf-wimse-aims (-01, Nov 2026) applies WIMSE and OAuth to AI agentsAgent authenticationWorkload identity for HTTP/REST call chains
AuthZEN Authorization API 1.0Final (11 Jan 2026)Per-actionA standard PEP-to-PDP decision call
COAZ-MCP BindingOpenID WG draft, Draft 1 (13 Feb 2026)Per-actionA standard mapping from MCP tools/call to an AuthZEN request
AuthZEN Access Request and Approval ProfileOpenID WG draftHuman in the loopWhat a PEP does with a “denied but requestable” decision
CIBA Core 1.0Final (2021)Human in the loopUser approval on a separate device, with no browser redirect
Shared Signals Framework 1.0 and CAEP 1.0FinalAsyncSession and risk events pushed between systems
Individual IETF agent draftsMany, several already expired (for example On-Behalf-Of User Authorization for AI Agents)Agent identity + delegationIdeas, not standards: watch, don’t build on them yet

Final is not the same as deployed. AuthZEN 1.0 is Final, but its agent bindings are drafts, and OAuth 2.1 itself is still a working-group draft. When a vendor says “standards-based agent authorization”, ask which documents and which versions from this table.

Open question to verify before publishing: the GA status and scope of vendor agent-identity products (for example Okta for AI Agents and Microsoft Entra Agent ID), and whether either uses these standards.

What’s next

The three layers are not equally mature, so start where the standards are solid. Get audience-bound, short-lived, delegated tokens right first. Then add per-call decisions for the handful of tools that can move money, delete data or reach outside your tenant.

Part 2 starts at the bottom of the stack: how an agent proves what it is before anyone asks whom it acts for. That covers workload identity, client ID metadata documents, SPIFFE and WIMSE, and why “the agent uses the user’s token” is not an identity.

Sources