How the agent is deployed, and which protocols apply
Sequence diagrams live under Flows. This page is the other cut: the runtime topology — product UI, headless worker, MCP host, mesh sidecar, true p2p HTTP — and the specs that actually attach to that shape. 13 patterns, researched 15 September 2026. Drafts are marked; RFC numbers are not invented. If you are not sure which row you are on, the picker names the shape — it does not score you.
What is your shape · 1 question
Is a human in the loop for this call?
Not 'does the product have users.' Is a person authenticating or approving this hop. This is an explainer, not a score — it names the deployment row you are already in. AAuth p2p, A2A, and did:peer stay on separate exits.
In one board · four doors
Delegated · AAuth p2p · A2A · did:peer
AS in path?
Yes — an authorization server mints the access token
What token?
Bearer or DPoP pass; sub is the user; agent is client_id or act
access token
UserAgent (client)ASAPI
Wrong cousin: Not AAuth identity-based: there is very much an AS. Putting this pass on an A2A call without aud and actor binding is a confused deputy.
There is no IETF RFC titled P2P in this cluster. The word is meeting shorthand. Pick one door and stay in it.
Overview matrix
Rows are deployment patterns. Columns are the questions that decide the protocol: is a user in the loop, is an authorization server minting the credential, does a workload identity name the binary, and does the agent have an identity that is not an AS-local client_id. Each row is a tiny topology of actors. Primary protocol names link into the catalog.
Deployment patterns versus user presence, authorization server, workload identity, portable agent identity, and primary protocols. Each row includes a compact topology of the actors.
A human is in a product UI. The agent calls APIs as that user. This is still the production default: OAuth 2.1 authorization code + PKCE, OIDC for the user, audience-restricted access tokens.
When you see it
Chat UIs that connect Gmail or Jira, Copilot-in-the-IDE with a browser login, any SaaS 'enable the assistant' button that pops an authorization screen. The agent is an OAuth client; the human is the resource owner.
Actors and trust
User / resource ownerUser
Authenticates to the authorization server (OIDC). Consents to what this client may do.
Agent (OAuth client)Agent instance
Identified by client_id at this AS (or a CIMD URL). Not a portable agent identity. Public or confidential depending on the host.
Authorization serverOther
Issues the access token the API will accept. Often the company IdP or the API vendor's AS.
Resource server / APIResource
Trusts tokens from that AS, audience-restricted to itself (RFC 8707 / RFC 9068). Does not automatically learn which agent instance called.
Topology
User (browser)Agent (OAuth client)Authorization serverAPI / tool
User (browser)→ Asks the product to call an API →Agent (OAuth client)
Agent (OAuth client)→ Auth code + PKCE (PAR if the request is rich) →Authorization server
User (browser)→ Authenticates (OIDC) and consents →Authorization server
Bearer tokens exist, but unconstrained Bearer as the whole design is the 2012 default RFC 9700 is walking away from.
Why these, and not those
You have a browser and a human. Authorization code + PKCE is the OAuth 2.1 default; OIDC authenticates the user to the client; RFC 9728 tells the client which AS protects the API; RFC 8707 keeps the token from being replayed at a different API; RFC 9700 is the safety floor (no implicit, no password grant, exact redirects). PAR and RAR are for fat or fine-grained requests, not a different grant. DPoP or mTLS so a stolen access token is not enough. AAuth identity-based p2p is the wrong tool unless you are deliberately replacing the AS — it has no authorization-code redirect and no Bearer access token.
Related flows
Sequence diagrams, not this topology cut. All flows
The agent runs without a browser on its own device. A human still has to approve, but on another device. CIBA is the OpenID answer; RFC 9470 steps up an existing grant; AAuth interaction relay is the person-server-shaped alternative.
When you see it
A nightly research agent that must confirm before sending mail, a factory-floor bot whose operator has a phone, a CLI agent started over SSH, any 'approve this tool on your phone' prompt. If there is no human at all, that is unattended batch — a different row.
Actors and trust
Agent (no browser)Agent instance
Confidential client at the OpenID provider, or an AAuth agent with a person server.
User on another deviceUser
Approves a binding message (CIBA) or completes an interaction URL (AAuth PS / RFC 9470).
OpenID provider or person serverOther
Authenticates the person and mints the grant the agent will present.
Resource serverResource
Still enforces audience and policy. CIBA is not a replacement for RS checks.
Topology
Headless agentOpenID provider / person serverUser (other device)API / tool
Headless agent→ CIBA backchannel authorize, or AAuth 401 + interaction →OpenID provider / person server
Authorization-code redirect is the wrong grant when the agent has no browser. Use CIBA (or AAuth interaction), not a fake redirect.
Headless browser against the authorize endpoint
That is not a grant. It is scraping a login page.
Resource Owner Password Credentials
Never collect the user's password in the agent.
Why these, and not those
Authorization code needs a redirect user-agent the agent does not have. CIBA starts the grant on the back channel and pushes the human on an authentication device. RFC 9470 is for the case you already have a grant that is too weak or too stale for this tool. AAuth's person-server interaction relay is the same human-in-the-loop idea without an OAuth AS in the agent–resource hop: the PS parks the request, the person approves, the agent retries with an auth token. Do not automate a headless browser against an authorize endpoint, and do not stuff a user password into the agent.
Related flows
Sequence diagrams, not this topology cut. All flows
A company agent needs Slack, Google, or another SaaS the IdP already federates. The IdP brokers the grant (XAA / ID-JAG) instead of sending the human through a second OAuth circus at every app.
When you see it
Enterprise Copilot or a custom agent that files a ticket in ServiceNow and posts to Slack under the employee's identity, with admin policy deciding which apps are pre-approved. The user signed into the company IdP this morning; the agent should not pop a new consent screen per SaaS if policy already allows the connection.
Actors and trust
Employee (user)User
Has an SSO session at the company IdP. May never see a second consent if policy pre-approves the app connection.
Company agent / appAgent instance
Already registered at the IdP. Not a portable AAuth identity; it is an enterprise OAuth client.
Company IdPOther
Issues an identity-assertion JWT authorization grant (ID-JAG) for the target app's AS.
SaaS authorization server + APIResource
Already trusts this IdP for SSO. Redeems the JWT grant (RFC 7523) for an access token to its own API.
Topology
EmployeeCompany IdPCompany agentSaaS ASSaaS API
Employee→ SSO session (OIDC) →Company IdP
Company agent→ Request ID-JAG / identity-chaining grant; aud = SaaS AS →Company IdP
Company IdP→ JWT authorization grant →Company agent
Company agent→ RFC 7523 JWT bearer grant →SaaS AS
SaaS AS→ Access token for this SaaS →Company agent
Company agent→ Call Slack / Google / … →SaaS API
IdP already has the user session. It mints a JWT grant for the SaaS AS; the agent never collects a second password.
Enterprise SaaS APIs expect OAuth tokens from an AS they already trust, not Signature-Key.
Per-SaaS password or a user refresh token harvested at install time
The IdP is supposed to broker this. Storing a Google refresh token in the agent bypasses enterprise policy.
Why these, and not those
XAA / ID-JAG is the IdP-brokered profile of 'the user is already signed in here; mint a grant the other app's AS will accept.' Identity chaining is the general two-AS version of the same idea. OIDC is how the IdP authenticated the employee. FAPI 2.0 if the SaaS is high-risk (open banking, payments). This is not AAuth p2p (there is very much an AS in the path) and not MCP (the wire to Slack is Slack's API, not an MCP session). AIMS tells you to compose these RFCs rather than invent a company-specific token.
Related flows
Sequence diagrams, not this topology cut. All flows
A model host (Claude Desktop, an IDE, a custom runtime) calls tools on an HTTP MCP server. The host is the OAuth client. The MCP authorization spec is an OAuth 2.1 profile, not a new token type.
When you see it
Claude Desktop attached to a remote MCP server, Cursor or another IDE with MCP tools, any custom host that speaks MCP HTTP. Stdio MCP is a local pipe and MUST NOT use this OAuth profile — if your 'MCP server' is a subprocess, you are not on this row.
Actors and trust
UserUser
Sits at the host. Authorizes the host to call this MCP server as them.
MCP host (client)Agent instance
The OAuth client. Identified by CIMD URL or (deprecated) DCR. The model never sees OAuth.
MCP server (resource)Resource
The RS. Publishes RFC 9728 metadata, validates audience == itself, does not forward tokens.
Authorization serverOther
Discovered from PRM. Issues tokens audience-restricted to the MCP server URI.
Topology
UserMCP hostAuthorization serverMCP server (tools)
MCP host→ Unauthenticated MCP HTTP request →MCP server (tools)
Only if you deliberately replace MCP-OAuth with agent-native signatures. Default MCP hosts will not.
OAuth on stdio MCP
The MCP spec: stdio MUST NOT use the HTTP authorization profile.
Forwarding the host token to another server
Confused deputy. The MCP server is the audience, not a gateway.
Why these, and not those
MCP HTTP authorization is explicitly an OAuth 2.1 profile: Protected Resource Metadata to find the AS, CIMD preferred over Dynamic Client Registration, authorization code + PKCE, resource indicator = the MCP server. That is why this row is not 'invent a tool token.' AAuth applies only if you deliberately leave the MCP-OAuth profile and speak agent-native HTTP signatures instead — a different contract than the MCP spec, and one MCP hosts will not implement by default. Do not put OAuth on stdio MCP. Do not let the server forward the host's token to someone else.
Related flows
Sequence diagrams, not this topology cut. All flows
Others call your agent. You are the resource server: publish how to authorize, then enforce it on every request. RFC 9728, an OAuth-protected resource, A2A Agent Card security schemes, or AAuth resource-managed if you run consent yourself.
When you see it
You shipped an HTTP API that is 'the agent.' You host an MCP server. You publish an A2A Agent Card so other agents can assign you tasks. Callers are other products, other agents, or a mesh sidecar — you do not get to assume a browser on their side.
Actors and trust
Calling agent / clientAgent instance
Must obtain whatever your metadata advertised. May be an OAuth client, an AAuth signer, or a mesh workload.
Your agent (resource)Resource
Publishes PRM and/or an Agent Card. Verifies the advertised scheme on the request. Signed Agent Cards prove the card was not tampered with; they do not authenticate the request.
Optional authorization serverOther
Present if you are an OAuth-protected resource. Absent if you are AAuth resource-managed and issue your own session.
API keys / unconstrained Bearer as the only scheme. Last resort, not a design.
Signed Agent Card as request authentication
Card JWS is tamper evidence for the card. Still require a request-level scheme.
Why these, and not those
The caller needs a machine-readable answer to 'how do I authenticate to you?' RFC 9728 is that answer in OAuth. A2A puts the same idea on the Agent Card as securitySchemes (OAuth, OIDC, mTLS, API key). If you do not want an AS, AAuth two-party / resource-managed lets you run your own interaction and issue an opaque session bound to the caller's key. Do not treat a signed Agent Card as request authentication. Do not make API keys the primary scheme if you can avoid it.
Related flows
Sequence diagrams, not this topology cut. All flows
Two agents, Agent Cards, a task protocol. A2A v1.0 is how they talk. Authentication is whatever the card advertised — usually OAuth at those endpoints. This is not AAuth identity-based p2p, and it is not did:peer / DIDComm.
When you see it
A planner agent delegates a 'book travel' skill to a specialist that published /.well-known/agent-card.json. Enterprise agent fabrics that speak JSON-RPC/gRPC/HTTP+JSON with A2A-Version. Google-originated protocol, now under AAIF / Linux Foundation.
Actors and trust
Client agentAgent instance
Reads the server's Agent Card, obtains credentials out of band, then calls a supported interface.
Server agentResource
Advertises skills, interfaces, and securitySchemes. Enforces the scheme on each operation.
Optional enterprise ASOther
Present when the card says OAuth or OIDC. Absent when the card says mTLS or an API key.
Topology
Client agentAgent CardOptional ASServer agent
Server agent→ Publishes /.well-known/agent-card.json →Agent Card
A2A §7.6.3: secrets become visible to every hop. Prefer out-of-band.
Why these, and not those
A2A v1.0 is a task and discovery protocol. It does not mint a new identity layer: it reuses OAuth, OIDC, mTLS, or API keys at the advertised endpoints. That is why OAuth shows up here and must not show up on the AAuth p2p row. AAuth identity-based access is signed HTTP with Signature-Key and no AS — different wire, different identifier. did:peer / DIDComm is pairwise wallet messaging; Agent Cards are globally fetched JSON. Do not forward caller credentials in-band down an A2A chain (A2A §7.6.3). Implicit and password grants on cards are deprecated.
Related flows
Sequence diagrams, not this topology cut. All flows
No authorization server in the path. The agent signs the HTTP request; the resource decides from cryptographic identity (identity-based) or runs its own consent and issues a session (two-party). AAuth + RFC 9421 + Signature-Key. OAuth Bearer does not apply.
When you see it
Open-world HTTP clients that will not pre-register at every API's AS. A personal agent calling a small resource that is willing to trust an agent token and a signature. Two-party: the resource already has a login page and would rather issue its own session than stand up OAuth. Individual draft — pin a revision.
Actors and trust
AgentAgent instance
Holds an aa-agent+jwt bound to its signing key. Identifier is portable (aauth:local@domain), not an AS client_id.
Agent providerOther
Issues the agent token and hosts JWKS. The resource fetches keys; it does not call an AS token endpoint.
ResourceResource
Verifies RFC 9421 + Signature-Key, then applies local policy. In two-party it also runs interaction and issues an opaque session.
User (two-party only)User
Completes the resource's own page. May be ordinary OIDC behind that page; the agent never talks to that AS.
The whole point of this row is that there is no AS minting a Bearer access token. Authentication is RFC 9421 over the HTTP request, with the key conveyed by Signature-Key (draft-hardt-httpbis-signature-key) carrying the agent JWT. Authorization is local policy on that identity, or a resource-issued session in two-party mode. Optional R3 and missions constrain what the agent may do without turning the hop into OAuth. Listing OAuth Bearer as applicable would describe a different pattern. A2A is a task protocol with advertised OAuth; did:peer is pairwise and not resolvable by a stranger. Keep all three apart.
Related flows
Sequence diagrams, not this topology cut. All flows
Portable agent identity plus a user grant from the person's server. Three-party: the resource has no AS. Four-party: the resource has an access server the PS federates to. OIDC may sit behind the PS to authenticate the person.
When you see it
A personal agent that carries the user's consent to resources that will never register it as an OAuth client. The user approves a mission at their person server once; the agent retries with an aa-auth+jwt. Four-party shows up when the resource already has a policy engine and will not evaluate auth tokens itself.
Actors and trust
AgentAgent instance
Signs every HTTP call. Holds an agent token that names its person server (ps claim).
Person serverOther
Represents the user: consent, missions, auth tokens, optional interaction. May authenticate the person with ordinary OIDC behind the scenes.
User / personUser
Approves at the PS, not at each resource's OAuth screen.
ResourceResource
Issues a resource token (aud = PS), then accepts aa-auth+jwt and applies its own policy to (iss, sub).
Resource access server (four-party)Other
Optional. The PS federates to it; the agent still only talks to the resource and the PS.
Topology
PersonPerson serverAgentResourceResource AS (four-party)
Agent→ Signed request; resource sees ps on the agent token →Resource
Agent→ Signed POST of the resource token →Person server
Person→ Approve mission / scope (OIDC may authenticate here) →Person server
Person server→ Four-party: PS federates to the resource access server →Resource AS (four-party)
Person server→ aa-auth+jwt (user claims, cnf-bound) →Agent
Agent→ Retry signed, with auth token →Resource
Agent and resource still speak signed HTTP. The user grant comes from the person server. Four-party inserts a resource-side access server the PS talks to.
You want AAuth's portable agent identity and a user grant, which identity-based p2p does not carry. The grant is aa-auth+jwt from the PS (short-lived, cnf-bound, aud = resource), not an OAuth Bearer access token from a client_id the resource minted. R3 and missions are the authorization language at the PS. Four-party adds a resource-side access server; that federation is not OpenID Federation and not OAuth identity chaining. OIDC belongs behind the PS (authenticate the person), not on the agent–resource hop.
Related flows
Sequence diagrams, not this topology cut. All flows
Orchestrator → specialist → API, still inside one trust domain. RFC 8693 act records who is acting. Transaction tokens carry immutable purpose. WIMSE re-binds the workload identity at each hop. AAuth call chaining (upstream_token / subagent_token) if you are already on AAuth.
When you see it
An orchestrator agent that fans out to a retrieval agent and a payments agent, all in the same cluster, all acting for the employee who started the task. Internal toolchains where every hop is your mesh. If the next hop is another company's AS, that is the cross-domain row.
Actors and trust
User (at the start)User
Authorized the first agent. Must not be silently widened at a later hop.
Orchestrator agentAgent instance
Holds the original grant. Exchanges or re-binds before calling specialists — does not forward the raw user access token.
Specialist / downstream APIResource
Sees an attenuated token: subject = user, act = the calling agent, audience = itself, purpose unchanged.
Workload identity issuerWorkload
SPIRE / WIMSE names each binary so a stolen user token presented by the wrong pod is a different incident.
Topology
UserOrchestratorSpecialistAPISPIRE / WIMSE
User→ Original grant (OAuth or AAuth) →Orchestrator
SPIRE / WIMSE→ Workload identity for this binary →Orchestrator
SPIRE / WIMSE→ Hop re-bind for the specialist →Specialist
That draft is for crossing authorization servers / domains. Wrong row.
Why these, and not those
Inside one domain you do not need identity chaining across ASes. You do need a recorded actor (RFC 8693 act), a purpose that cannot grow (transaction tokens), and a workload identity that is re-bound at each hop (WIMSE). Agent-grants and AAP are individual OAuth profiles that try to say the same thing with extra claims — mark them draft/churn. If the fabric is AAuth, call chaining with upstream_token / subagent_token is the analogue: the sub-agent signs with its own key while nested act records the parent. Never expand scopes at a hop. Never forward the original user access token.
Related flows
Sequence diagrams, not this topology cut. All flows
The grant starts at AS A and must be accepted at AS B in another organization. Identity chaining (I-D) composes RFC 8693 and RFC 7523. RFC 9207 mix-up defenses exist because two issuers are now in play.
When you see it
An agent reads mail in the company tenant and files a ticket in a vendor SaaS whose AS is not yours. Partner integrations where each side has its own authorization server. Distinct from XAA only in that XAA is the IdP-brokered profile of a similar grant; this row is the general two-AS chain.
Actors and trust
Client in domain AAgent instance
Holds a token from AS A. Must not present it at API C in domain B.
AS AOther
Token-exchanges a JWT authorization grant audience-restricted to AS B.
AS BOther
Redeems that JWT via RFC 7523 and issues an access token for its own resource. Must not be mixed up with AS A.
Resource in domain BResource
Accepts only tokens from AS B, aud = itself.
Topology
UserAS AAgent in AAS BAPI in B
User→ Original delegation →AS A
Agent in A→ RFC 8693 exchange → JWT grant, aud = AS B →AS A
Agent in A→ RFC 7523 JWT bearer grant (iss checks / RFC 9207) →AS B
AS B→ Access token for API C →Agent in A
Agent in A→ Call in domain B →API in B
Two ASes, two audiences. The client exchanges at A for a grant B will redeem. Mix-up defenses are mandatory.
Two authorization servers means identity chaining, not a private JWT format and not a transaction token (txn-tokens are same-domain). RFC 8693 produces the grant; RFC 7523 is how B consumes a JWT assertion; the chaining I-D writes that down as a profile (RFC Editor queue as of July 2026 — no RFC number yet). RFC 9207 iss in the authorization response, plus exact issuer metadata checks, are how you stop mix-up when the client talks to more than one AS. XAA is the IdP-shaped variant; FAPI if B is high-risk.
Related flows
Sequence diagrams, not this topology cut. All flows
The agent is a binary in a mesh. SPIFFE/SPIRE names it, WIMSE WIT/WPT prove it, mTLS carries it. Client credentials or SPIFFE client auth if an AS is still in the picture. Not an OIDC user sub.
When you see it
An inference service in Kubernetes with a SPIRE agent (or mesh sidecar) issuing X.509-SVIDs. Internal tool-calling microservices with no human on the request. Sidecar proxies that present mTLS to the next hop so the app code never sees a static API key.
Actors and trust
Workload (agent binary)Workload
Identified by a SPIFFE ID / WIMSE identifier. That string is 'payment-api in prod', not 'Alice'.
SPIRE / identity serverOther
Attests the platform and issues short-lived SVIDs or WIT/WIC.
Sidecar / mesh proxyOther
Often the process that actually presents mTLS. The workload identity is still the app's, not the proxy vendor's.
Relying workload / APIResource
Authenticates the peer cert or WPT. Authorization is policy on the SPIFFE ID, optionally plus an OAuth client-credentials token.
Topology
SPIRE / WIMSE issuerSidecarAgent workloadOptional ASPeer API
SPIRE / WIMSE issuer→ X.509-SVID or WIT+WIC →Agent workload
Agent workload→ Workload API / identity for this pod →Sidecar
Sidecar→ mTLS / WPT / HTTP signatures →Peer API
Agent workload→ Optional: SPIFFE client auth + client_credentials →Optional AS
Platform attests the binary. Sidecar or the app presents mTLS / WPT. Optional AS only for client-credentials, never for a user sub.
Do not put the user sub in the SPIFFE ID, and do not send an ID Token to the API.
Static API keys in the sidecar env
The SVID is supposed to replace that.
Why these, and not those
There is no user on this hop, so OIDC user sub is the wrong identifier to stuff into a SPIFFE ID. SPIFFE/SPIRE is how production meshes already name binaries. WIMSE generalizes that across systems (WIT must not be used as Bearer; WPT or HTTP signatures or mTLS are the proof). If the API still wants OAuth, the client authenticates with SPIFFE (or mTLS RFC 8705) and uses the client-credentials grant — the token is the workload's, not Alice's. AIMS is the BCP that says this out loud. AAuth portable agent identity is a different scope (open-world HTTP clients, not your cluster).
Related flows
Sequence diagrams, not this topology cut. All flows
Where the OAuth client actually runs changes token storage and client type. RFC 10017 for browser-based hosts, RFC 8252 for native apps, confidential client + DPoP or mTLS for server-side runtimes. Same grant, different failure modes.
When you see it
A chat SPA that holds the agent's tokens in the page. A desktop companion (Claude Desktop, a CLI with a loopback redirect). A backend worker that is the confidential client and never shows tokens to the model or the browser. This row is orthogonal to the others: an interactive delegated agent is also one of these three hosts.
Actors and trust
HumanUser
Still authenticates at the AS. The host type decides which user-agent and where tokens land afterwards.
Agent host (the OAuth client)Agent instance
Public client in a browser or many native apps; confidential client on a server. Must not leak tokens into model context, logs, or XSS-reachable storage.
Token pitfall: XSS on the chat page is token theft. localStorage and sessionStorage survive XSS. Do not put access tokens in the DOM, in analytics, or in model prompts. Implicit flow is gone.
Native app host
Desktop or mobile companion: Claude Desktop, a CLI, an IDE plugin that opens a browser for login.
UserNative agent hostSystem browserAS
Native agent host→ Open authorize URL →System browser
User→ Authenticate and consent →System browser
System browser→ Authorization code on claimed HTTPS or loopback →Native agent host
Native agent host→ Code + PKCE exchange →AS
RFC 8252: system browser, PKCE, claimed HTTPS or loopback. No embedded webview.
Token pitfall: Embedded webviews are in-scope for phishing the password. Custom URI schemes are a last resort if claimed HTTPS is unavailable. OS token stores beat a plaintext file next to the binary.
Server-side agent runtime
The agent is a backend process. It can keep a client key. The browser, if any, never sees access tokens.
User (optional UI)Front end (no tokens)Server-side agentASAPI
User (optional UI)→ Session cookie only →Front end (no tokens)
Server-side agent→ Client auth (private_key_jwt / mTLS) + user grant or client_credentials →AS
Server-side agent→ DPoP or mTLS-bound access token →API
Confidential client. Authenticate with a key; sender-constrain the access token.
Token pitfall: Tokens in logs, traces, and tool arguments are the usual leak. Do not ship the client secret to the browser 'for convenience.' Do not hand the model the refresh token.
OAuth 2.1 does not change the fact that browsers cannot hide secrets, native apps must not embed a webview, and servers can keep a key. RFC 10017 is the browser BCP: prefer a Backend-for-Frontend with HTTP-only cookies; if tokens must live in the page, keep them in memory, never localStorage. RFC 8252 is the native BCP: system browser, PKCE, claimed HTTPS or loopback redirects. Server-side agents are confidential clients and should sender-constrain with DPoP or mTLS so a leaked access token is not replayable from a laptop. Token storage is the incident: XSS in the chat page, an embedded webview, a refresh token in localStorage, or a token concatenated into a prompt.
Related flows
Sequence diagrams, not this topology cut. All flows
A cron, a queue worker, a service account with no human on the request. Client credentials and workload identity. Never the password grant. Never a long-lived user refresh token stuffed into the job.
When you see it
Nightly summarization over a corpus the service owns, a pipeline that classifies tickets as itself, a scheduled agent that calls internal APIs with a workload identity. If a human must approve a specific action, that is headless/async (CIBA), not this row.
Actors and trust
Service agentWorkload
Acts as itself. Identified by client_id plus workload identity, not by a user sub.
Authorization server (optional)Other
Issues a client-credentials access token audience-restricted to the API.
ResourceResource
Authorizes a service account / SPIFFE ID. There is no 'on behalf of Alice' unless you moved to an OBO row.
No user on this hop. An ID Token is not an access token.
Why these, and not those
Client credentials (OAuth 2.1) and workload identity (SPIFFE/WIMSE) answer 'which robot is this?' They do not answer 'which human?' — and this row has no human. The password grant is gone (OAuth 2.1 / RFC 9700) and was always the wrong way to let a batch job impersonate someone. A long-lived user refresh token in a cron secret is delegated access with no session, no rotation story, and no way for the user to know the job is still running. If you need a user, use CIBA or an interactive grant at the time of action. AAP and AIMS are draft profiles/BCPs on this shape; treat them as churn.
Related flows
Sequence diagrams, not this topology cut. All flows
Pairwise, not globally resolvable, and not how a stranger's first HTTP call is authenticated. They sit in the catalog as adjacent identity/messaging. Do not substitute them for AAuth p2p, and do not substitute A2A Agent Cards for a DID document.
GNAP is finished, and not what these products speak
RFC 9635 is a complete IETF alternative to OAuth. Interactive agent UIs, MCP HTTP, and A2A cards overwhelmingly profile OAuth 2.1 / OIDC instead. It is omitted as a primary protocol on every row below for that reason, not because it is invalid.