Hi Sangam,

Jumping in here as I'm one of the authors of the COAZ framework and the MCP
binding in the OIDF AuthZEN WG.

Short answer to your question, as I see it, is neither (ish). I'd split it
into three cases:

*1. Same hop: the message changes between decision and forward.*

This is inside COAZ and it's addressed as of last week:
https://github.com/openid/authzen/issues/603. The PEP now has to apply
every rewrite it knows about before evaluating, and before applying a
permit it has to check that the method, selected mapping and input values
are semantically unchanged from what was evaluated. If they changed,
re-evaluate or refuse, never apply the old permit. So "the PEP authorised
an upstream message rather than the effect" is now a conformance failure
when it happens within one PEP's own hop. Lifting that invariant into the
framework so every future binding gets it is still to do.

*2 - A later hop with its own information model*

If the MCP server, having received a permit for tools/call, then makes an
HTTP call, a DB write or a function call, that's another operation with its
own information model - it should be another PEP calling a PDP. I agree
with where this thread landed, that the boundary is a role in the
effectuation path, not a component.

*3 - Deferred effect with no natural PEP.*

A permit on tools/call followed by a queue or local dispatch that completes
later is where an AuthZEN decision alone doesn't bind as an allow is a
point-in-time answer to "may this actor do this". It isn't proof of
execution and it isn't an execution capability. Two adjacent proposals
under the access request lifecycle touch upon this layer where one binds
the decision to the exact call via a signed digest with one-attempt
admission and reconciliation that stays indeterminate until evidence
matches, the other mints a one-time capability from the decision so only an
unspent one can trigger the effect. This may not completely address what
you are trying to get at, but feels like there is some overlap.

The downstream point is another PEP on the same surface where a binding
describes its input, and it's a consequence-admission question rather than
a COAZ one where the effect is deferred past the last message any binding
can see. COAZ-MCP doesn't cover your in-process dispatch case and shouldn't
pretend to. If you want to push on the framework-level invariant, or think
the binding should say more about the effect boundary explicitly, issues on
https://github.com/openid/authzen tagged coaz are the place and I'd welcome
it.

Cheers
Alex

On Tue, 15 Sept 2026 at 08:16, Sangam Das <[email protected]> wrote:

> Hi Omri, Yaron, Jijie,
>
> Thanks — this is the distinction I was looking for.
>
> Agreed on the gateway/server path: COAZ-MCP gives a standard way to
> project the live MCP message into AuthZEN and obtain a per-call decision
> without minting a per-call token. Treating the declared mapping and
> arguments as untrusted, while anchoring the verified subject identity, is
> the right split for that hop.
>
> Also agreed that token issuance/exchange cannot see tool arguments that do
> not yet exist; that is a different surface.
>
> The case I am specifying is the one you flagged: an act that is not itself
> an MCP hop, or whose consequential effect remains completable after the
> authorized MCP hop.
>
> A PDP permit on a mapped message is an authorization decision over that
> message. The question I am trying to isolate is what binds that decision to
> the later component that can actually complete the consequential effect.
>
> For example:
>
> AI/host → MCP PEP → PDP permit → queue / local dispatch / downstream
> component → consequential effect
>
> If the final effect occurs after the MCP PEP — or through an in-process
> dispatch path with no COAZ-aware PEP — then COAZ-MCP has authorized the MCP
> operation, but the downstream effectuation boundary is a separate
> enforcement question.
>
> That is the placement I mean by execution finality: the candidate act
> remains non-effective until the authorization predicate for that exact act
> is bound to, and enforced at, the point capable of completing the effect.
>
> So the two layers can stay separate:
>
> • COAZ-MCP = how to obtain and enforce a fine-grained decision over the
> concrete MCP message.
>
> • Execution finality = how to prevent the consequential act from
> completing unless that predicate is still bound at the point of effect.
>
> The question I would value your view on: would you model that downstream
> effectuation point as simply another PEP in the same COAZ surface, or does
> it fall outside the intended COAZ-MCP enforcement surface — particularly
> where no PEP covers the consequential path, or where the PEP authorizes an
> upstream message rather than the later effect itself?
> Regards
> Sangam
>
> On Tue, 15 Sep 2026 at 3:22 AM, Omri Gazitt <[email protected]> wrote:
>
>> Hi Sangam, Yaron, Jijie,
>>
>> First - sorry to be a little late to this thread - I've been traveling.
>>
>> Sangam, on your original question, whether this is already solved
>> somewhere: for the part where the call crosses a gateway or an MCP server,
>> I think it largely is. The OpenID AuthZEN working group has a binding for
>> it, COAZ-MCP
>> <https://openid.github.io/authzen/authzen-coaz-mcp-binding-1_0.html>.
>>
>> The shape is that the PEP, either an MCP gateway or the MCP server
>> itself, maps the live JSON-RPC message into an AuthZEN authorization
>> request and calls a PDP before the message takes effect. Tool arguments are
>> addressable in that mapping, so the decision is over the concrete call
>> rather than the tool class. From a mapping declared in a tool's input
>> schema:
>>
>> "action":   { "name": "transfer_funds" },
>> "resource": { "type": "account", "id": "$params.arguments.from_account" }
>>
>> Two things in it speak to your first two questions.
>>
>> On where the authority comes from: the mapping is authored by the MCP
>> server and the arguments come from the caller, so the binding treats both
>> as untrusted input. Section 11.4 says policy MUST NOT treat any attribute
>> originating in a declared mapping as authoritative for identity or
>> privilege, and that only the subject identifier, which the PEP verifies
>> against the validated access token, is trustworthy. So the emitted
>> arguments are inputs to the decision and never the source of authority for
>> it. The host does not have to construct a finer-grained authority object
>> out of its own untrusted output.
>>
>> On reusable versus per-invocation authority: this gives you a per-call
>> decision without a per-call token. The token stays as coarse as it is, and
>> the PDP call is what narrows per invocation. Your deployment B is not
>> inherently unenforced. It is unenforced when nothing on the path is acting
>> as a PEP.
>>
>> What it does not cover is the case you and Jijie both arrived at. The
>> binding scopes itself to gateway-as-PEP and server-as-PEP, so a host's
>> in-process function dispatch sits outside it, and your placement point
>> stands for that path.
>>
>> One more thing, since Yaron kindly named my drafts: the token issuance
>> and token exchange profiles gate at the authorization server and decide
>> whether a token is issued and how it is shaped. They do not see tool
>> arguments, because at issuance time the arguments do not exist yet.
>> Different surface from the one you are asking about.
>>
>> Thanks,
>> Omri
>> --
>> Omri Gazitt
>>
>>
>> On Tue, Sep 1, 2026 at 12:53 AM Sangam Das <[email protected]> wrote:
>>
>>> Hi all,
>>>
>>> A question prompted by watching how MCP/tool-use agents actually fail in
>>> practice:
>>>
>>> DPoP sender-constrains a token to a key. RAR and ID-JAG can scope a
>>> token to a resource and a set of permitted actions. But once an agent holds
>>> a valid token, none of these constrain the *specific call* it's about
>>> to make — the tool name and arguments the model just emitted. A
>>> prompt-injected or poisoned-context agent can hold a fully valid,
>>> correctly-scoped token and still invoke the right tool with
>>> attacker-controlled arguments, and OAuth has no visibility into that
>>> argument payload at all.
>>>
>>> Is there existing or in-flight work that binds authorization to the
>>> content of a specific call (e.g., a digest of the tool name + arguments)
>>> rather than just to the resource/scope class — something closer to a
>>> per-invocation proof tying a grant to *this exact call*, not *this
>>> class of calls*? Or is this considered out of scope for OAuth/WIMSE and
>>> better handled at the host-application layer?
>>>
>>> I*'ve written up one possible approach in more detail as
>>> draft-das-agentic-tool-binding-02 ("tool_use Is Not invoke(): Binding
>>> Execution-Finality to Agentic Tool-Call Interfaces and MCP"), if useful as
>>> a starting point rather than a
>>> proposal: 
>>> https://datatracker.ietf.org/doc/draft-das-agentic-tool-binding/02/
>>> <https://datatracker.ietf.org/doc/draft-das-agentic-tool-binding/02/>*
>>>
>>> (Note: this builds on architecture covered by my pending patent
>>> applications, disclosed per RFC 8179 for transparency — flagging this now
>>> rather than later.)
>>>
>>> Mainly interested in whether this gap is already solved somewhere I'm
>>> missing.
>>>
>>> Thanks,
>>> Sangam
>>> _______________________________________________
>>> OAuth mailing list -- [email protected]
>>> To unsubscribe send an email to [email protected]
>>>
>> _______________________________________________
> OAuth mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
>
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to