[OAUTH-WG] Re: Binding OAuth-authorized calls to specific tool-call arguments in agentic/MCP flows
Alex Olivier <alex@cerbos.dev> Tue, 15 September 2026 08:51 UTC
Received: from mail-oa2-x10.google.com (mail-oa2-x10.google.com [IPv6:2607:f8b0:4864:30::10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by mx.ietf.org (Postfix) with ESMTPS id 05C8B5A for <oauth@ietf.org>; Tue, 15 Sep 2026 08:51:03 +0000 (UTC)
Authentication-Results: mx.ietf.org; dkim=pass header.d=cerbos.dev header.s=google header.b=fJrPPVZY; arc=pass ("google.com:s=arc-20260327:i=1"); dmarc=pass (policy=reject) header.from=cerbos.dev; spf=pass (mx.ietf.org: domain of alex@cerbos.dev designates 2607:f8b0:4864:30::10 as permitted sender) smtp.mailfrom=alex@cerbos.dev
Received: by mail-oa2-x10.google.com with SMTP id 586e51a60fabf-46a63c34533so3386020fac.1 for <oauth@ietf.org>; Tue, 15 Sep 2026 01:51:02 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1789462262; cv=none; d=google.com; s=arc-20260327; b=XLZ9bdxG02+61IqRXZxdzEJ3aIfb1Q2h46Ck+QS1cBvl3UzL6dyI9ylU1tAlmnea5L h3cdKYqxqTdnjdrHirS9PKtmyJudHw5f77hjS/PGOd5tcV2UH+9BDdZGF/QZvzpR3MQN ivFt6x1ToMvNppLrw/TEpgMyXy7QB6xCqQIms6xIyLaZ0UxN3Dq96AVQEwb0kT+eC2Wx 1mFSck+Go1hCsXoYYSN/0BS+97Wwb8QnKaZq673I7w1N4ehJ+xpOHn5IiO81H7nL7Rmj Ddu1RYGsO4Ju62HBZN9ToDmDRNSJ0KTZFgu7JwH37BXGGVdkpGe7Np7x0kBFE3nFGnGd Wu3w==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=klvTs0iylZt3Q7uB8rn5WCO138I3b7n/QUyJ+0LIRTI=; fh=FT9Z8YtCr+5XAZRimSYWzFaOzu7XU9ckWEh5R0t7zrQ=; b=isPK2XpgfG3anG/6hYiNvNHudMVEXV4OmS6ViOZxfRJIL6ObERJ3zEHNTJuP2n1Ffb OzRgO6LrumjEMiL022BBS8l2fVfJwLD3asqN69haGOvMKsa+ma1jWu4rJKP+L2I82unz 7orIvcLy8G4a5qTebG9toX6NkBJlEeX68LtC/2mU7MfcPDvIaXUs7S3PBYIVNGB4l7Cg K6ZWeTr0RtTlIARhCga25zkt0vTbCoj1LEhb/GqKvymVAap/97bkGbbTeeWk4nmGUlYc p6tikOQ2onbdXqnQXdLTefCd6WZ3RKXJ3Mvw+HWLJBQLL+/VAKpwTR0W6PKZOC60huv2 9GWw==; darn=ietf.org
ARC-Authentication-Results: i=1; mx.google.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerbos.dev; s=google; t=1789462262; x=1790067062; darn=ietf.org; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:from:to:cc:subject:date:message-id:reply-to :content-type; bh=klvTs0iylZt3Q7uB8rn5WCO138I3b7n/QUyJ+0LIRTI=; b=fJrPPVZYyk0KQbBc1drb9qx8RsbNxUua+Yw4ivHyQ6T9y6OHBP+MMxubdADDY5Ui6l EMnWJQyxE7KiZJZ5laPN9/icY1aF36MGHiPfzTZ5jgdTS4b37UWKptS71UsoOvQQV9gs qvpX6FnLnteD5jGaQRBIrYhYMLsxuaqiM+aKoMMbDS7wYGJnGa6G8QaacYr1YfAgpKrt bKo5Be79Okw/qb+z07+l5q69PRmHqtuC1JveFkK0j/2TPjmGgIGU62fRDUj3T+vtQCz3 fwy7T2DkG9u1s7Ql7smOtQStdlEAR/zDpT3ezMcBpn9WSF4ejcDCeAqUw95l0OYbG3p/ B2yQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789462262; x=1790067062; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to:content-type; bh=klvTs0iylZt3Q7uB8rn5WCO138I3b7n/QUyJ+0LIRTI=; b=gHjVfQnGPMx0UM6LF/xOOc0tXexjEPMePlApaIBLbELctK77ZXyQyhTHxvFwKuW6Wo HbR/mPkC1Aj2AIYlBe05ffpQHG4Or5z8jieYNfS+XzAiP68aYrKVvBzsZisMNOyKhk1W Ls9I1eWANCeJ7AM0Cm/R0+VyVf0xN4QYDfO4oYMIuQs8rb9xAqSeubkgX01ueom4hScy WEQ7O9q0W8feYogmW5m2gm4FYNV9ueRJXnfnbbO4E0ItIPBTVAZvTIqEtMxqzjKupLTd rFWj+v0dbugYLLEypuaSGNQrxLseGaNoXOCvpfU73So2qQ5ziQ+LHaGXNqfb9qFwZzhQ 1qLA==
X-Forwarded-Encrypted: i=1; AKwUvBwALLrAMzXIoUOl1nbyCClpjSHXCMVE6B0OpfV0XFM3zW1t3tASpnhS3ZijSGL4tfY3ZCId+Q==@ietf.org
X-Gm-Message-State: AFuF++kg6f9p8AiOCkUltpN48B9BiMD+UIHrhjg/HmdYcmzADgsBajnF 3aq33+gXfhtYIXQUJnfAteJysr+Rc0ngXZg2B7UiRvLaLYBfKcsMRvHdOfrR7n0m15eC3pPML15 xdS+uzI8gVLMfWLPWoQqbPCofdQLXXQ58qrk61jMdrg==
X-Gm-Gg: AYBFou1fSs56yTt3jpeV/rB+frI5f3g336xc4BEZEjEIUskhDprnaDYiEJgHUp3fZwZ HqafkR8tmjLy5S+cIxl+GNQ3DTx9vF6o4Ql8P+sO3lJEhiZ50lOS+tdeHSsLtlCo9MUGFm29uMA 9hjcZDu2zCqTix7d7fVnrn8uGiRb0FFRYxEWop1XOJFCqqxiNVm3wV5NxAxxiNBbZsMDcBvLqts Af8GHpaXMiDp2zKttYp+aPv6EzUQgn849z5K9APFXxifyxu+zwuR5Q6e9mGVvZr+QVkuDuhA/L9 KYnd0PrFRiB8fV3E6kfLgTyz8UpYwBWFwazqJnl7f4VngfCzanmzU2uTkJCWI4pLJX0FD8oLRVW rGUIXTkn437X1HaEhysLYa/mr0v1Y4EADJK2fh0O5D8TVpC331lrwIdnTpmJgTxb6CxWLeeYnYW hbZJNHUxERxCRild02wTzUvVyAtsuf1bcsr2BuYQ7xEDipG6IRePU=
X-Received: by 2002:a05:6871:5228:b0:448:8bdd:8358 with SMTP id 586e51a60fabf-481f8255548mr4438172fac.15.1789462262110; Tue, 15 Sep 2026 01:51:02 -0700 (PDT)
MIME-Version: 1.0
References: <CAHCJH6HA8EWiP63o+RcW4vum-xvZCob23GDYqgJZU3LjkcU2TA@mail.gmail.com> <CAHG5M7BWeXHreKt7=1Ws0Y6tpkqeNS+96hc2Wg9678=x46Qqyw@mail.gmail.com> <CAHCJH6G8Q-8f5GSK3SHeuM4RLm32kcNhc9a=9ARLcZLGYnC3=w@mail.gmail.com>
In-Reply-To: <CAHCJH6G8Q-8f5GSK3SHeuM4RLm32kcNhc9a=9ARLcZLGYnC3=w@mail.gmail.com>
From: Alex Olivier <alex@cerbos.dev>
Date: Tue, 15 Sep 2026 09:50:49 +0100
X-Gm-Features: AcwNN1W7PQQlhNyLNzChIS9jyt8rV-dGOzfRaR80y6rKsTVG_HTcTON2rfDGBWQ
Message-ID: <CACQKPJ_+tXKPUSMy4j8kYc6iWHiuHkhvbu2ZhWBRNpzY-mTZcA@mail.gmail.com>
To: Sangam Das <info@sangamdas.com>
Content-Type: multipart/alternative; boundary="00000000000078f0d3065b81a605"
X-Spamd-Bar: -
Message-ID-Hash: XOGNXFFYWXL66PPL7GLFSM4LV4ITJPTN
X-Message-ID-Hash: XOGNXFFYWXL66PPL7GLFSM4LV4ITJPTN
X-MailFrom: alex@cerbos.dev
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-oauth.ietf.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: Omri Gazitt <ogazitt@gmail.com>, oauth <oauth@ietf.org>, wimse@ietf.org
X-Mailman-Version: 3.3.10
Precedence: list
Subject: [OAUTH-WG] Re: Binding OAuth-authorized calls to specific tool-call arguments in agentic/MCP flows
List-Id: OAUTH WG <oauth.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/bseg55e9tx_37q4pqyRlWmksmts>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Owner: <mailto:oauth-owner@ietf.org>
List-Post: <mailto:oauth@ietf.org>
List-Subscribe: <mailto:oauth-join@ietf.org>
List-Unsubscribe: <mailto:oauth-leave@ietf.org>
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 <info@sangamdas.com> 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 <ogazitt@gmail.com> 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 <info@sangamdas.com> 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 -- oauth@ietf.org >>> To unsubscribe send an email to oauth-leave@ietf.org >>> >> _______________________________________________ > OAuth mailing list -- oauth@ietf.org > To unsubscribe send an email to oauth-leave@ietf.org >
- [OAUTH-WG] Binding OAuth-authorized calls to spec… Sangam Das
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Yaron ZEHAVI
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Sangam Das
- [OAUTH-WG] Re: [WIMSE] Re: Binding OAuth-authoriz… Raut, Ashay
- [OAUTH-WG] Re: [WIMSE] Re: Binding OAuth-authoriz… Sangam Das
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Yaron ZEHAVI
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Sangam Das
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Omri Gazitt
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Sangam Das
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Alex Olivier
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Sangam Das
- [OAUTH-WG] Re: [WIMSE] Re: Re: Binding OAuth-auth… Iman Schrock
- [OAUTH-WG] Re: [WIMSE] Re: Re: Binding OAuth-auth… Sangam Das
- [OAUTH-WG] Re: [WIMSE] Re: Re: Binding OAuth-auth… Iman Schrock
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Jijie Wei
- [OAUTH-WG] Re: [WIMSE] Re: Binding OAuth-authoriz… Sangam Das
- [OAUTH-WG] Re: [WIMSE] Binding OAuth-authorized c… Sangam Das
- [OAUTH-WG] Re: [WIMSE] Binding OAuth-authorized c… Sangam Das
- [OAUTH-WG] Re: [WIMSE] Binding OAuth-authorized c… Sangam Das
- [OAUTH-WG] Re: Binding OAuth-authorized calls to … Jijie Wei
- [OAUTH-WG] Re: [WIMSE] Re: Binding OAuth-authoriz… Mohamad Khalil Yossif
- [OAUTH-WG] Re: [WIMSE] Re: Binding OAuth-authoriz… Sangam Das
- [OAUTH-WG] Re: [WIMSE] Binding OAuth-authorized c… Kieran Sweeney