An agent wants to call several tools on several MCP servers, each fronted by its own Authorization Server. The authorization for each call should be least-privilege: not “the agent can act on these resource servers,” but “the agent is approved to perform these specific actions right now.”

The security boundary is not the model. The security boundary is the authority represented by a tool invocation. OAuth was deliberately scoped to model access grants, not the tasks those grants serve. That left a gap. The OAuth stack does not have a first-class object for the task that authority belongs to. It has credentials, scopes, RAR entries, and policy decisions. The task itself, the thing a least-privilege boundary should refer to, is implicit. Two architectures have emerged for MCP that work around that absence. Both work cleanly for one call to one server. Both fragment as soon as the task spans more than one call or authorization domain. Both surface the same ontology gap, because there is no shared object for the task to anchor on.

This post walks a concrete multi-call scenario through both paths, shows where each one breaks under fan-out and ontology pressure, and explains how a Mission record at the originating Authorization Server makes the user-approved task a typed protocol object that both paths can refer to. Then it compares that to AAuth R3, which makes a different diagnosis at the operation-vocabulary layer.

This post is the applied use case for the Mission stack. The Mission is the Missing Abstraction for Agents made the conceptual case. The Mission-Bound OAuth MVP added the Mission as a durable governance layer to the existing OAuth stack. The Runtime Enforcement Profile added the runtime enforcement layer on top.

Short version

There are two natural ways to authorize least-privilege MCP tool calls.

Token-side FGA: the agent discovers what the MCP server requires, asks the right Authorization Server for a narrow token, and retries the call with authority carried in authorization_details.

Resource-side FGA: the MCP server acts as the Policy Enforcement Point, asks a PDP whether this exact tool call is allowed, and uses AuthZEN Access Request when the denial is requestable.

Both work. Both share one blind spot. Tokens describe what authority a credential carries. PDP decisions describe whether a specific call is permitted. Neither describes the task the user actually approved.

A Mission makes the task an explicit protocol object. The originating AS owns the user-approved task. Each MCP server or Resource AS owns its domain semantics. Every token and PDP decision joins back to mission.id. The two FGA paths stop being competitors and become projections of the same Mission.

Board packet before and after

The board-packet example is the whole problem in miniature.

StepWithout a MissionWith a Mission
Finance readFresh token request or PDP approval for query_financials. Approval prompt has to restate the task contextChecked against the approved board-packet Mission. Finance system applies its own domain policy
Document creationSeparate AS/PDP decision for create_doc, with no protocol-level link to the finance readToken or PDP decision carries the same mission.id. Document system sees the same task context
Reviewer notificationAnother isolated approval for notify_reviewer. Audit has to stitch by time, user, and clientWorkflow action is evaluated as another projection of the same Mission
Scope expansionNew ad-hoc approval if the agent needs finance data outside Q3Mission Expansion references the existing Mission and preserves lineage
AuditThree unrelated decisions across three systemsOne task spine joined by mission.id and mission.origin

That is the standardization point. Least-privilege per call is necessary, but it is not sufficient for agent tasks. The calls need a common object to point back to.

The setup

An agent is preparing a board packet. It needs to make a sequence of tool calls across three different MCP servers, each protecting its resources through its own Authorization Server:

  1. query_financials(period="Q3 2026", entity="Example Corp") on a finance MCP server, with its own AS.
  2. create_doc(template="board-packet", title="Q3 Review") on a document MCP server, with a different AS.
  3. notify_reviewer(group="audit-committee", deadline="...") on a workflow MCP server, with a third AS.

The user approved the broader task in a session before the agent started: “prepare the Q3 board packet for the audit committee.” In today’s systems, that approval is usually application state, not protocol authority. It does not automatically authorize the individual tool calls. The agent starts with a coarse token, perhaps just a session-level token from its IdP, if it has any token at all for these servers.

Each tool call has to land at the right grain: not “agent can act on these resource servers,” but “agent is approved to read this specific financial period for this specific entity, draft this specific document, notify this specific reviewer group.” The agent does not know up front which actions each server permits, which RAR types each Authorization Server accepts, or which fields are required. Discovery is part of the protocol.

Before walking the two paths, it helps to be precise about what we are actually authorizing.

What we are authorizing

Everything downstream of this post follows from one distinction. The model is untrusted reasoning that proposes actions. Each tool invocation is a request to exercise specific authority against a specific resource. The protocol layer’s job is to govern the invocation, not the reasoning. That job is three different authorization problems, often conflated:

  • Tool discovery. Which tools does the agent see in the first place? The catalog returned by tools/list is itself an authorization decision. A tool the agent cannot see, it cannot propose. A tool that should not exist for this caller, in this context, should not appear in the listing.
  • Tool invocation. When the agent calls a tool, does the call sit within the authority the agent already holds? Token-side FGA and resource-side FGA both sit here. Most of this post is about this problem.
  • Tool approval. When the call sits outside current authority but is still potentially permissible, what runtime governance workflow turns the denial into a decision? Approval (a human reviewer authorizes the call), consent (the user grants additional consent in band or out of band), and access request (a general governed escalation that may compose risk evaluation, approval routing, and consent collection) are three different workflow shapes, all expressible through the AuthZEN Access Request and Approval Profile.

Both FGA paths follow the same capability acquisition pipeline, even though they implement it at different boundaries:

  1. Discover need. The task requires a specific action against a specific resource. The agent learns this from the task plan, the tool catalog, or a runtime failure that points at the missing capability.
  2. Request capability. The agent expresses the need on the wire (a Rich Authorization Request to the AS in Path A, a tool invocation against the MCP server in Path B).
  3. Evaluate. Policy evaluates the request against user-approved authority, client registration, deployment rules, and runtime risk posture.
  4. Grant or gate. The evaluation either produces a capability (a narrow token in Path A, a permit decision in Path B) or routes through a runtime governance workflow (approval, consent, or access request).
  5. Execute. The MCP server runs the tool against the granted capability.

The pipeline shape is uncontroversial. The interesting questions are where each step lives, what artifact step 4 produces, which runtime governance workflows step 4 can route through, and what protocol object the whole pipeline refers to as the task across many invocations. Those are the questions Path A, Path B, and the Mission layer answer differently.

Who is “the agent” on the wire?

Three identities show up at the protocol layer, and a real deployment has to be explicit about each.

  • User identity. The human (or service principal) who approved the task and consented to the Mission proposal.
  • Client identity and instance attestation. The agent runs as an OAuth client with a client_id. The Client Instance Assertion profile lets a registered client identify the specific instance making the call, so a compromised instance can be revoked without taking down the client.
  • Actor chain. When the agent delegates to a sub-agent or hops through multiple workloads, RFC 8693 Token Exchange builds an act claim chain. The Actor Profile extends the act claim with the structure needed for agent delegation chains, including instance identity and per-hop authority constraints.

Mission-Bound OAuth carries all three. The Mission is approved by the user. Tokens are issued to the client and tagged with the instance. The actor chain travels with the token and is recorded in decision evidence. Every PDP decision and every issued token reads from the same set of principals bound to the same task identifier.

Path A: Token-side FGA

In Path A, the client carries the authority. Each tool call is authorized by a token whose contents narrow down to the specific action. Steps 2 through 4 of the capability acquisition pipeline (request, evaluate, grant) all happen at the Authorization Server. The resulting token is what step 5 (execute) carries to the MCP server.

Discovery and request

The agent’s first call to a tool starts a multi-step discovery cycle. The MCP server validates the agent’s current token, sees that no authorization_details entries cover the requested action, and returns an OAuth WWW-Authenticate challenge naming the relevant Authorization Server via Protected Resource Metadata (RFC 9728). This is the layering MCP’s own authorization spec adopts. The client fetches the PRM document, finds the AS, and follows the AS metadata to learn which authentication methods, grant types, and authorization_details shapes are accepted. A draft is in flight to standardize AS-side discovery of supported RAR types and their schemas: draft-zehavi-oauth-rar-metadata defines metadata that advertises which RAR type values an AS understands and what fields each one requires.

The first request for a given task is often approved through a normal OAuth front-channel consent flow. The agent submits the proposal via PAR. The AS renders the proposal to the user in a browser, the user approves, and the AS issues a code that the client exchanges for a Mission-bound token. Asynchronous approval is the case the rest of this section focuses on, because it is the part the existing OAuth surface does not natively handle. The front-channel case still applies, especially for the initial Mission Proposal and for high-stakes step-up.

With the supported RAR types in hand, the client constructs an authorization_details entry that names the specific action. It submits via PAR, the AS evaluates the request, optionally consults a PDP via the AuthZEN Authorization API, and either mints a narrow access token or returns an asynchronous handle for out-of-band approval. On approval, the client retrieves the token and retries the tool call.

sequenceDiagram participant Agent participant MCP as MCP Server (RS) participant AS as Authorization Server participant PDP Agent->>MCP: tools/call query_financials MCP-->>Agent: 401 WWW-Authenticate
resource_metadata = PRM URL Agent->>MCP: GET PRM MCP-->>Agent: PRM: AS issuer, scopes_supported Agent->>AS: GET AS metadata + RAR-type metadata AS-->>Agent: authorization_details_types_supported
schemas per type Agent->>AS: PAR + RAR
authorization_details = action-narrow AS->>PDP: AuthZEN Evaluation alt In-bounds PDP-->>AS: permit AS-->>Agent: access_token narrowed to action else Approval needed PDP-->>AS: requestable denial AS-->>Agent: deferred handle + polling Note over AS: Access Request out of band Agent->>AS: poll AS-->>Agent: access_token after approval end Agent->>MCP: tools/call query_financials + token MCP-->>Agent: result

The shape Path A produces is a token the MCP server validates against authorization_details, with no PDP in the request path at execution time. The client carries the proof that the action was authorized. This cycle repeats every time the agent needs an action outside its current authorization_details, whether the new action lives on a different MCP server (different AS, different RAR types) or simply lies outside the prior grant’s bounds on the same server (a query_financials(period="Q4 2026") call after the prior grant was scoped to Q3).

Asynchronous approval options

When the AS cannot grant the request without an out-of-band decision, Path A has several mechanics to choose from. The AuthZEN-native shape is the AuthZEN Access Request and Approval Profile composed with OAuth 2.0 Deferred Code Processing. The AS returns a deferred code on a requestable denial, the client polls the token endpoint, and the AS reevaluates and issues the token when approval completes. This is the option that carries a structured requestable-denial signal and composes cleanly with Mission Expansion. CIBA is the alternative an existing AS is most likely to support today. It is mature and widely implemented, but it does not natively carry the “denied but requestable” semantics or a precise RAR-narrow request shape from the resource server, so deployments using CIBA for agent FGA reconstruct that signal out of band. RFC 8628 Device Grant and RFC 9470 Step-up cover adjacent cases. The base AuthZEN profile defines one completion mode, reevaluate, and leaves token issuance as a downstream extension point that any of these mechanics can fill.

The ontology problem

The “AS evaluates the request” step is where Path A meets domain reality. For the AS to mint a token whose RAR entries describe read Q3 financials for Example Corp, the AS has to be able to evaluate whether the request is sensible: whether the client may make this kind of request, whether the user’s role permits the action, whether the financial period and entity identifier are valid for this user, whether the constraints are compatible. That is Resource-Server-domain knowledge.

The AS in a typical multi-tenant SaaS IdP is generic. It knows OAuth, RAR, scope, and client registration. It does not natively know what financials means, what Q3 2026 resolves to in the finance system, or which entity identifiers are valid for this user. The RAR type and actions strings are opaque to the AS unless the AS has been taught them. There are three ways out, and each has a cost:

  1. Tight coupling. The AS is purpose-built for the RS. The finance system’s AS is part of the finance system. This is common for first-party deployments and does not generalize to the open-world MCP scenario where any agent can call any tool on any MCP server.
  2. Standardized vocabulary. A shared operation language across resources, like AAuth R3’s r3_operations or a common RAR-type registry. Real progress, but the vocabulary itself is a slow, committee-driven artifact, and not every RS adopts it.
  3. Delegated evaluation. The AS calls the RS or an RS-domain PDP to validate the RAR at issuance time. This works but reintroduces an RS-side decision into Path A. The “carry the authority” property weakens because the RS is back in the loop, just earlier than execution.

In practice, today’s RAR deployments lean on (1) and partial (3), often without published RAR-type discovery. Clients hard-code the RAR types they know. The Zehavi metadata draft helps surface the schemas, but it does not solve the question of how the AS validates the semantics behind those schemas. The ontology gap is one of the structural reasons RAR has not displaced scopes in most deployments.

Path B: Resource-side FGA

In Path B, the resource server evaluates. The client holds a coarse token, and the MCP server (acting as Policy Enforcement Point) calls the PDP per request. Steps 3 and 4 of the capability acquisition pipeline (evaluate, grant or gate) live at the MCP server’s PDP. Step 5 (execute) runs only when step 4 produces a permit.

This is the path that MCP SEP-2848 “Asynchronous Approval for Tool Calls” defines. The agent calls the tool. The MCP server evaluates against a PDP. On a denial that is requestable, the MCP server submits an AuthZEN Access Request, binds the returned task handle to a server-generated MCP taskId, and returns a CreateTaskResult (status working) in place of the tool result. Out-of-band approval completes the task. On approval, the MCP server reevaluates against the PDP and executes the tool exactly once.

sequenceDiagram participant Agent participant MCP as MCP Server (PEP) participant PDP as PDP / Access Request participant Approver Agent->>MCP: tools/call query_financials MCP->>PDP: AuthZEN Evaluation alt In-bounds PDP-->>MCP: permit MCP-->>Agent: tool result else Approval needed PDP-->>MCP: requestable denial MCP->>PDP: AuthZEN Access Request PDP-->>MCP: access_request_id MCP-->>Agent: CreateTaskResult, status = working Note over PDP,Approver: Approval out of band Approver->>PDP: approve Agent->>MCP: tasks/get MCP->>PDP: reevaluate PDP-->>MCP: permit MCP-->>Agent: completed + tool result end

The client only carries an MCP taskId. Authorization artifacts (binding_token, evaluation_id, the approval object, endpoints) never cross the MCP wire. No new token is minted. Approval is an input to the PDP, not a standing grant. The PDP reevaluates at execution time, which defends against TOCTOU drift between approval and execution.

As a concrete example, the user approves the agent to call transfer_funds(amount=1000, account=A). Between approval and execution, the user revokes the agent or marks account A as fraudulent. A Path-A token minted at approval time is still valid on its face. The MCP server has no reason to reject it. Path B’s per-call PDP evaluation closes that window, because the PDP re-reads current Mission state, risk posture, and revocation events at execution.

MCP defines an in-band consent mechanism called elicitation that the resource-side architecture can use directly. During a tools/call interaction, the MCP server returns an elicitation request that names a structured input schema. The client gathers the response from the user and returns it. The MCP server resumes the tool call with the gathered input. This is the MCP-native shape of the “consent” workflow type from the framework section, and the synchronous analogue of the asynchronous task flow that SEP-2848 defines. Common patterns include bounded selection (narrow which period or audit committee), step-up confirmation for sensitive operations, structured argument capture, and disambiguation when the agent’s request matches multiple resources. The PDP evaluates the call with the elicited value in scope, and the decision evidence records both.

Elicitation is synchronous and constrained to the active session. The server cannot send unsolicited elicitation requests, and the approver must be the user in the session. For supervising agents, automated risk engines, or out-of-session human reviewers, the durable task primitive from SEP-2848 is what fits. Real deployments mix both at the same MCP server, with the PDP deciding which is appropriate for each call. Either way, the Mission lifecycle is unaffected. Elicitation narrows a specific call within the Mission rather than expanding it.

Tool discovery falls out for free

A second strength of Path B is one Path A cannot match. The MCP server already owns the tool catalog. The tools/list response is itself an authorization decision the MCP server controls, so it can filter the catalog against the same PDP that gates invocation. A tool the agent should not call is also a tool it does not see in the first place.

Path A’s AS does not own the catalog. It can narrow what the agent is authorized to invoke, but it cannot reach into the MCP server’s listing surface. Tool discovery and tool invocation become one consistent enforcement layer in Path B. In Path A they remain split.

Iteration across tool calls

Path B’s iteration shape is symmetric to Path A’s but lives at a different boundary. Each new MCP server fronts its own PDP, with its own policy authored against its own domain. Each call is evaluated locally. The token does not have to change, because the agent keeps its coarse token. But every PDP independently reasons about whether the call is in-bounds, every requestable denial creates its own task with its own approver, and audit records accumulate per server. The token churn of Path A is absent. The approval and audit fragmentation is not.

Shape and ontology

The shape Path B produces is no minted token. The least-privilege grant lives in the PDP’s evaluation against the specific call, plus a per-decision audit record. The MCP server enforces. The PDP decides. The approval is a gating input.

Path B sidesteps the ontology problem at the AS layer. The MCP server is the domain expert for its own tools. It already knows what query_financials(period, entity) means because it implements the call. The PDP it consults can be authored against the RS’s actual domain model. There is no AS in the request path that needs to learn the resource’s vocabulary.

Concretely, the PDP can be Cedar, OpenFGA, OPA, or any policy engine the deployment already runs. The wire shape between the MCP server and the PDP can be the AuthZEN Authorization API, so the PDP choice stays decoupled from the MCP integration. Where the deployment already routes traffic through an API gateway (Envoy ext_authz, Istio AuthorizationPolicy, Kong, or similar), the gateway is a natural PEP, calling the PDP and short-circuiting the request before the MCP server processes it. Path B in production usually looks like an API gateway with a Mission-aware PDP and a tasks-aware MCP integration rather than a custom MCP server build-out.

The cost is portability. The decision lives at the MCP server and its PDP, and is not directly verifiable by another party without re-running the evaluation against the same domain model.

A bridge: Transaction Challenge

Path A and Path B share a structural assumption. The agent gets its authorization in one place. Either it mints a token at the AS up front, or it gets a permit at the MCP server’s PDP per call. The OAuth Transaction Challenge draft blends the two.

The shape goes like this. The MCP server (or any RS) detects that the agent’s existing token does not authorize the specific transaction in front of it. The RS issues a transaction challenge that names the resource, the action, and the transaction-specific context. The client takes the challenge to the AS. The AS evaluates the transaction, requesting user consent or step-up if needed. The AS issues a transaction-specific token bound to that exact transaction. The client retries the call.

The RS is back in the trigger path, like Path B. The AS still mints the token, like Path A. The token is per-transaction, not per-session. The decision involves both sides instead of being owned by one.

The tradeoff is shape against fit. Transaction Challenge is more disciplined than Path A’s WWW-Authenticate + RAR cycle, because the RS hands the AS a precise transaction description rather than relying on the client to construct a correct RAR from discovered metadata. It is less efficient than Path B for cases where the agent should never hold a transaction-bearer token in the first place, because the AS round-trip and the token issuance step are still in the request path. It composes with Missions the same way Path A and Path B do. The transaction-specific token carries mission.id and mission.origin, and the AS evaluates the transaction against Mission state at mission.origin.

Most production deployments end up mixing all three shapes. Path A’s narrow tokens for routine least-privilege grants. Path B’s PDP evaluation for high-risk consequential actions. Transaction Challenge for the cases in between, where the RS knows the call-specific context but the agent’s authority still wants to project from the AS.

What each path optimizes

The two paths are not enemies. They place the same five pipeline steps at different boundaries, and the tradeoffs follow from where each step lives.

Pipeline stepPath A: token-side FGAPath B: resource-side FGA
Discover needAgent infers from task plan or a WWW-Authenticate challengeAgent infers from task plan or a tools/list catalog the MCP server already filtered
Tool discoveryOut of scope for the AS, the MCP server has to filter on its ownNaturally falls under the same PDP that gates invocation
Request capabilityRAR authorization_details to the AS, narrowed to one actionTool invocation directly to the MCP server
EvaluateAt the AS, optionally consulting a PDP. The AS needs domain knowledge or must delegateAt the MCP server’s PDP, with the resource’s own domain model in scope
Grant or gateNarrow access token at the AS, or deferred handle on requestable denialPermit decision at the PDP, or an MCP task handle on requestable denial
ExecuteMCP server validates the token offline, no PDP in the request pathMCP server runs the tool only on permit. PDP re-reads state at execution time
Carried artifactSender-constrained Mission-bound token (DPoP or mTLS), portable proofMCP taskId, no portable proof exits the server
Latency profileOne token round-trip up front, then offline validation per callOne PDP round-trip per call, mitigated by PDP-decision caching
EasyOffline validation, token portability, low execution-time latencyDomain-specific policy, TOCTOU-resistant execution, no token explosion
HardAS ontology, RAR vocabulary convergence, token churnCross-server audit, approval fragmentation, portable proof
MissingDurable task context across callsDurable task context across calls

The practical rule is to carry when you can, evaluate when you must, and bind both to the Mission. Use token-side FGA when portable authority and offline validation matter. Use resource-side FGA when the MCP server owns rich domain semantics, the action is high risk, or TOCTOU drift matters. Once the task spans more than one call, server, or authorization domain, neither path should stand alone. Both need the same durable task context.

Where both paths break

Both paths work for one tool call to one MCP server. The board-packet agent has to make at least three calls across three MCP servers and three Authorization Servers, and may iterate further within each server. What does that look like at the protocol layer?

In Path A, each new MCP server starts its own discovery cycle, and each AS sees only its own tool calls and only its own operation vocabulary. No AS shares context with another. Each consent request lands in front of the user as if it were the agent’s first action. The agent accumulates a pile of narrow, short-lived tokens scoped to single calls. Each AS solves the ontology problem locally and inconsistently.

In Path B, each MCP server’s PDP evaluates calls in isolation, with no shared task context across servers. Each requestable denial creates a separate task with its own approver. Token churn disappears. Approval prompt proliferation, audit fragmentation, and PDP-by-PDP policy duplication do not.

flowchart LR Agent([Agent]) User([User / Approver]) subgraph PA["Path A: token-side"] AS1[AS-1] AS2[AS-2] AS3[AS-3] end subgraph PB["Path B: resource-side"] PDP1[MCP-1 PDP] PDP2[MCP-2 PDP] PDP3[MCP-3 PDP] end Agent -->|RAR tool 1| AS1 Agent -->|RAR tool 2| AS2 Agent -->|RAR tool 3| AS3 Agent -->|call tool 4| PDP1 Agent -->|call tool 5| PDP2 Agent -->|call tool 6| PDP3 AS3 -.->|isolated approval prompts| User PDP3 -.->|isolated approval prompts| User

The cliff is the same on both sides. The architecture has no durable, cross-call, cross-server notion of “the task the agent is doing.” Every approval is evaluated in isolation. Every token is scoped to one call (Path A) or every decision is local to one PDP (Path B). Every prompt asks the user to re-justify the task from scratch. The audit trail is a pile of disconnected decisions joined by approximate timestamps and the agent’s identity. The ontology gap from Path A is now N copies of itself across N Authorization Servers, each one independently asking “what does this resource and action mean.”

The root cause is structural, not a missing feature. Both paths build per-call authorization on top of a protocol stack that does not have a first-class object for the task. Path A makes per-call tokens. Path B makes per-call decisions. Both work around the absence and both break at the same place. There is no shared object for a token, a decision, an approval, or an audit record to refer to as “the same task.”

The user-visible failure mode is concrete:

  • The user sees repeated approval prompts for fragments of one task.
  • The agent accumulates narrow tokens or pending tasks with no shared lifecycle.
  • Audit joins depend on timestamps, client identifiers, and log correlation instead of a task identifier.
  • Out-of-bounds requests create new isolated approvals instead of governed expansion of the original task.
  • Each AS or PDP independently reconstructs what the board-packet task means, often inconsistently.

Fixing this with better client orchestration, smarter SDKs, batched RAR requests, or richer log shipping reduces symptoms. None of those moves close the structural gap. The protocol still does not name the task, so anything built on top of it has to infer the task from indirect signals every time.

What a Mission fixes

A Mission is what closes the gap: a typed protocol object for the task the user approved, owned by the originating Authorization Server, projectable into every token and PDP decision derived from it. As I argued in The Mission is the Missing Abstraction for Agents, the abstraction OAuth needs for agents is not another credential or another evaluation point. It is the task itself, as a first-class object on the wire.

The user approves the Mission once, against a structured proposal that describes the task: purpose, expiry, context, and the set of resource accesses needed to complete it. The originating AS stores the approved authority, hashes it for audit, and binds every derived token to the Mission via a mission claim carrying id and origin. This is the spec defined in the Mission-Bound OAuth MVP.

The Mission fixes both paths because it separates two questions that the architectures above conflate. The originating Authorization Server owns the user-approved task at a grain it can model: purpose, expiry, resources, actions, constraints. Each Resource Server owns the domain semantics for its own tools and applies the Mission’s bounds with that domain knowledge.

The originating AS does not have to know how query_financials resolves inside the finance system or how notify_reviewer maps to a workflow policy. It validates the proposal against client registration and deployment policy. It renders the proposal for approval. It stores the approved bounds. It makes those bounds available to downstream Resource ASes and PDPs. The finance, document, and workflow systems keep their own semantics.

For the board-packet task, the Mission Proposal might look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[
  {
    "type": "mission_intent",
    "purpose": "urn:example:mission:board-packet",
    "mission_expiry": "2026-10-15T18:00:00Z",
    "context": {
      "classification": "confidential",
      "tenant": "example-corp",
      "meeting": "audit-committee-q3-2026"
    }
  },
  {
    "type": "resource_access",
    "resource": "https://finance.example.com/mcp",
    "actions": ["query_financials"],
    "constraints": {
      "period": "Q3 2026",
      "entity": "Example Corp"
    }
  },
  {
    "type": "resource_access",
    "resource": "https://docs.example.com/mcp",
    "actions": ["create_doc"],
    "constraints": {
      "template": "board-packet",
      "classification": "confidential"
    }
  },
  {
    "type": "resource_access",
    "resource": "https://workflow.example.com/mcp",
    "actions": ["notify_reviewer"],
    "constraints": {
      "group": "audit-committee"
    }
  }
]

A Mission can carry exact MCP tool names when the ecosystem has a shared vocabulary, but it does not require that. The safer default is that resource_access.actions describe authority at a grain the originating AS can model. Each Resource Server then maps that authority to its concrete tools and arguments. The Mission is the contract between AS-side governance and RS-side enforcement.

The mechanics of how the Mission propagates across Authorization Servers (Token Exchange, ID-JAG, the Transaction Token Chaining Profile) are defined in the Mission-Bound OAuth MVP. The mechanics of how a PDP evaluates against a Mission’s compiled policy at execution time are defined in the Runtime Enforcement Profile. The contribution this post adds is showing how those mechanics land at the pipeline grain and at the three authorization problems from the framework section.

The pipeline with a Mission in scope

The five-step pipeline does not change shape. What each step refers to does.

  1. Discover need. tools/list becomes Mission-aware. The MCP server filters the returned catalog against the Mission’s resource_access entries. A tool unrelated to the approved task does not appear in the listing, so the agent does not propose it.
  2. Request capability. The agent’s RAR (Path A) or tool call (Path B) carries mission.id and mission.origin. There is now a typed handle for “the task this request belongs to.”
  3. Evaluate. The Resource AS or PDP reads the Mission claim. It validates Mission state at mission.origin. It evaluates against the Mission’s approved bounds, applying its own RS-domain knowledge. Domain semantics still live where the domain lives.
  4. Grant or gate. In-bounds requests produce a Mission-bound token (Path A) or a permit (Path B), with no fresh user prompt. The user already approved the task. Out-of-bounds requests route to Mission Expansion via AuthZEN Access Request.
  5. Execute. The MCP server executes against the token or permit. Decision evidence binds the executed call to mission.id, so audit records across every AS and every PDP join on the same task spine.

Tool discovery and tool approval with a Mission

The three authorization problems from earlier line up cleanly once the Mission is in scope.

Tool discovery. tools/list is filtered against the Mission’s resource_access entries. A tool unrelated to the approved task does not appear, so the agent does not propose it. This is consistent enforcement at the discovery layer that neither Path A nor Path B can achieve on its own. The AS does not own the catalog. A Path-B PDP without a Mission has no shared context across servers. With a Mission, the MCP server filters its catalog against the same task object the PDP evaluates against.

Tool invocation. Both FGA paths now have an object to point at. The Mission-bound token in Path A is least-privilege at the token grain and tagged with the task it serves. The PDP decision in Path B is least-privilege at the per-call grain and tagged with the same task. Either way, the invocation is bound to a specific user-approved task, not just to a specific resource.

Tool approval. Approval, consent, and access request stop being three disjoint workflows. They are three runtime shapes of the same Mission Expansion. Each one is a requestable denial against an existing Mission, routed through the AuthZEN Access Request profile, completed by some out-of-band decision (human, automated, or both), and committed as a successor Mission. The approver sees the Mission lineage, not a fragment of one.

Every PDP decision produces a decision evidence record bound to mission.id, mission.origin, the compiled policy version, the decision, and the actor chain at evaluation time. The Runtime Enforcement Profile specifies the record shape. What matters for this post is that the audit join across systems becomes mechanical. Every evidence record, every issued token, and every Access Request approval carries the same task identifier. Reconstructing “what did the agent do for the board-packet task” becomes a single query, not a stitching exercise across logs.

flowchart LR User([User]) Mission[("Mission Record
at originating AS
mission.id, proposal_hash")] Agent([Agent]) subgraph PA["Path A"] AS1[AS-1] AS2[AS-2] end subgraph PB["Path B"] PDP1[MCP-1 PDP] PDP2[MCP-2 PDP] end User -->|consent once
on Mission Proposal| Mission Agent -->|RAR + mission.id| AS1 Agent -->|RAR + mission.id| AS2 Agent -->|tool call + mission.id| PDP1 Agent -->|tool call + mission.id| PDP2 AS1 -.->|read Mission| Mission AS2 -.->|read Mission| Mission PDP1 -.->|read Mission| Mission PDP2 -.->|read Mission| Mission

The two paths converge on the Mission. One durable approval, projected as many tokens and many PDP decisions, all referring to one Mission. That is the abstraction that closes the scaling cliff.

The Mission is not a global operation vocabulary, and it does not eliminate the need for RAR-type metadata, R3-style operation descriptions, AuthZEN evaluations, or Resource Server policy. It supplies the shared task handle and lifecycle. Resource domains still define their own semantics. That division of concerns is the point:

ConcernOwned by
User-approved task, expiry, lifecycle, audit anchorOriginating AS / Mission record
Resource-specific operation meaningMCP server or Resource Server
Per-call enforcementResource AS, MCP server, or PDP
Cross-call audit joinmission.id and mission.origin
Out-of-bounds expansionMission Expansion through AuthZEN Access Request

That is why the Mission composes with both token-side and resource-side FGA. It does not pick one enforcement style. It gives both styles the same task authority to project from.

Does a Mission violate the lethal trifecta?

The lethal trifecta for agents is the combination of three capabilities in one execution loop:

  1. Access to private or sensitive data.
  2. Exposure to untrusted content that can influence the agent.
  3. Ability to cause external side effects or exfiltrate data.

The board-packet agent can easily touch all three. It reads confidential finance data, ingests public filings or partner documents, and sends notifications or publishes a packet. A Mission profile must not pretend that naming the task makes that safe.

The answer is: a Mission does not inherently violate the lethal trifecta, but a badly designed Mission can package it. If the Mission grants broad private-data reads, untrusted-web access, and external write/send authority as one undifferentiated blob, then the Mission has only renamed the dangerous bundle. It has not reduced the risk.

The useful Mission profile does the opposite. It gives the AS, Resource Servers, PDPs, and egress controls a common object for splitting and governing the bundle:

Trifecta elementMission control point
Private data accessresource_access entries limit which private systems, records, periods, tenants, and actions are in scope
Untrusted content exposureMission context and runtime policy classify sources and prevent untrusted content from expanding authority by itself
External side effectsRuntime Enforcement requires PDP evaluation, parameter binding, and step-up or Mission Expansion for sends, publishes, payments, or egress

The MVP mainly gives lifecycle and derivation control. That is useful, but it is not enough for a high-risk agent that touches all three sides of the trifecta. The Runtime Enforcement Profile is where the safer posture becomes concrete. Consequential actions are evaluated at execution time. Parameters are bound into the decision. Out-of-bounds actions route through Mission Expansion. Audit records show which Mission-authorized step caused the side effect.

The design rule is simple. A Mission may describe a task that spans all three elements, but it must not grant all three as ambient authority. Private reads, untrusted inputs, and external writes need to remain separately typed, separately evaluated, and separately auditable under the same mission.id.

How Missions compose with the AuthZEN profile

Path A and Path B compose with the AuthZEN Access Request and Approval Profile symmetrically. Path A gates token issuance. A requestable denial at the AS triggers an Access Request, and on approval the AS mints a Mission-bound token. Path B gates execution at the MCP server. A requestable denial at the PDP triggers an Access Request, and on approval the MCP server reevaluates and executes. The Access Request references the Mission in both cases. The Mission lifecycle is what makes the approval compose across calls instead of repeating per call. The Mission-identity-in-Access-Request mechanics and the token-issuance completion mode the base AuthZEN profile leaves open are defined in the Runtime Enforcement Profile and Mission-Bound OAuth MVP respectively.

Comparison to AAuth R3

AAuth R3 (Rich Resource Requests) is the operation-vocabulary layer in the AAuth stack. It defines a shared operation language that projects either as a carried token claim (r3_granted) or as a per-call evaluation (r3_conditional). One operation set, two delivery modes. Routine grants are carried. Sensitive or irreversible operations route to per-call evaluation. That is the cleanest unification of carry-vs-evaluate at the operation grain.

R3 also addresses the Path A ontology problem by standardizing the operation vocabulary itself. An AS that understands the R3 shape can evaluate requests across participating resources without learning each domain in detail. The cost is convergence. A shared operation vocabulary across thousands of MCP servers is a slow empirical artifact, and not every resource will adopt it.

R3 is not the whole AAuth story. AAuth pairs R3 with its own Mission layer, which I have written about in Mission Architecture on AAuth and AAuth Now Has a Mission Layer. The AAuth stack is a parallel of the OAuth + RAR + Mission-Bound OAuth stack this post otherwise focuses on. R3 sits at the operation grain. The AAuth Mission sits at the governance grain. The two layers stack the same way Mission-Bound OAuth and RAR types stack on the OAuth side.

The choice between the AAuth stack and the OAuth stack is largely substrate and ecosystem. AAuth is a clean-slate design with operation vocabulary, Mission, and credential format consistent with each other. The OAuth stack composes Mission-Bound OAuth and RAR onto already-deployed OAuth infrastructure. AAuth is the cleaner protocol surface. OAuth is the substrate already running everywhere.

In both stacks, the operation layer and the task layer compose. R3 unifies operations across carry and evaluate. The Mission unifies task identity across tokens, decisions, AS boundaries, and resource domains.

Agents do not only call tools

The MCP tool boundary is one place where this pattern surfaces. Agents also reach the open web through an egress proxy that enforces a destination allowlist. When the agent reaches a destination the allowlist does not cover, the result today is the same shape as a flat 401 with no machine-actionable recovery.

The same five-step pipeline applies at the egress boundary. Discover need (the agent tries to connect). Request capability (the connection attempt). Evaluate (the egress proxy is the PEP, calling its own PDP). Grant or gate (allow the connection, or route through a requestable-denial workflow). Execute (the connection completes).

The only changes are vantage point and visibility. The egress proxy only sees what its position reveals. Behind an opaque CONNECT tunnel it can govern hosts. At a TLS-terminating proxy it can match on HTTP method and URL. At an API-aware gateway it can govern named operations. The ontology problem reappears, with the proxy now the domain expert for what it can see at its altitude.

I wrote about that boundary in A Blocked Agent Is a Captive Client, which sketches two analogous architectures. Destination-level approval rides on the AuthZEN Access Request profile. Operation-level approval rides on AAuth R3 carried by Mission-bound tokens. Both reuse RFC 8908 as the captive-portal transport.

A Mission ties both boundaries together. The same Mission record gates the agent at MCP tool calls and at network egress. In-bounds tool calls and in-bounds destinations clear without a fresh prompt. Out-of-bounds events at either boundary route to Mission Expansion at the originating AS, referencing the same mission.id. The approver sees one expanding Mission, not one stream of MCP approvals plus a separate stream of egress approvals.

Real agents touch both boundaries on every non-trivial task. The board-packet agent does not only call MCP tools. It also fetches reference data from partner APIs and pulls public reports. The same governance object spanning both boundaries is what keeps the audit trail coherent.

Where to start

The smallest useful pieces are independent. Each one pays for itself before the rest arrives.

  • If you build MCP servers, the smallest useful move is to put a PDP behind tool execution and filter tools/list against the same PDP. SEP-2848 gives you the transport binding for asynchronous approval. Discovery, invocation, and approval become one enforcement layer at the MCP server. This is Path B with no Mission layer required. It works today.
  • If you run an Authorization Server for agent clients, the smallest useful move is to publish RAR-type metadata so clients can construct correct authorization_details. Then wire the AuthZEN Access Request profile to OAuth 2.0 Deferred Code Processing. That is Path A with asynchronous approval, also Mission-free, also useful on its own.
  • When you need approvals to compose across calls, servers, or authorization domains, the Mission-Bound OAuth MVP is the layer that makes Path A and Path B project from the same task object. The Runtime Enforcement Profile adds the runtime PDP contract and per-decision evidence on top.

R3 and Missions are not alternatives. R3 organizes operations across the carry-vs-evaluate boundary. Missions organize task identity across calls, servers, and authorization domains. Path A and Path B are how those objects reach the wire. Carry when authority must travel. Evaluate when context must stay local. Bind both to the Mission when the work spans calls, tools, or domains.