[OAUTH-WG] Re: Security Consideration: Delegation Chain Splicing in RFC 8693 Token Exchange
cbchhaya@pm.me Fri, 13 March 2026 16:53 UTC
Return-Path: <cbchhaya@pm.me>
X-Original-To: oauth@mail2.ietf.org
Delivered-To: oauth@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 272D9C97756E for <oauth@mail2.ietf.org>; Fri, 13 Mar 2026 09:53:53 -0700 (PDT)
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -2.796
X-Spam-Level:
X-Spam-Status: No, score=-2.796 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=unavailable autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=pm.me
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PAsPrj4o-lZC for <oauth@mail2.ietf.org>; Fri, 13 Mar 2026 09:53:49 -0700 (PDT)
Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id 83560C97755A for <oauth@ietf.org>; Fri, 13 Mar 2026 09:53:49 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1773420819; x=1773680019; bh=vKY4WAZdAwbNrzBRV+bEpjfFva62IDPUmnDDSm0Xinw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=l1wDa+J8DVQejw+1Vyid4f+5sZotkP9xbRFBwUGGU+57bilbxhmQTLBTpQDEo/Pik AkBhhNWWqYbYSZN5F3OrSckvU2nsLDCJDbon0b9KJ03aZJQkGgo3Fh/P1HT/cpjo+F vi/TwfMl9hHxOHC9tzjiT3T44Z2nWXiaMWoRk+4lKWFS3mbMMPSHVCKSs8ombvMhDU C75LXxzjaUNvtVPz8oHvicS0OlMsjKfMpoU9Gmvwf8NfufMShKsGi1XcYb24kq6aIR /df2nwGbNVgPunS4/Ur5fYK9Hbcbq8/neW/bngUOSxNU7stP5omDAXe/+4oO5TsuY0 IvYUsck64kisw==
Date: Fri, 13 Mar 2026 16:53:35 +0000
To: "Lombardo, Jeff" <jeffsec@amazon.com>
From: cbchhaya@pm.me
Message-ID: <urKQaQSdHTPuK3ModDWv9ZXRWYghDNOA0Q6FUyJt1qtaavpRHx8HQX3MiL88bU-Yewd6wJmccEPHoi4WGq7I5n7ZKH-cfH-nZe5yRiMNgNk=@pm.me>
In-Reply-To: <CO1PR18MB4684B704BDE52B5B4BB9B85CD944A@CO1PR18MB4684.namprd18.prod.outlook.com>
References: <5vGZ1KgxwggnpbATPByNeu8UmLUqsorvYJ4_zUuhlBHZ9cd2zukuREUQZ3Lh1xLWd-0ImwtFPxEiXMyiij1YwQy2uh9dTtdHdGSCPCvjLsc=@pm.me> <CAPKc7S_QYbcGN7TEJa1cDZpYUcz==B+jPC=HizioaYqGNvVJ9g@mail.gmail.com> <9QXL--I5RVrce1YFWN6ZK9aTuDT2jAh194VsrQ6L7Ua5dDLjPMtYJ-UnyNbeo_98NWgCnfA0eZtIvpKH5E7Hm1UPNIyEmO77y75X3ZviDa4=@pm.me> <CAPKc7S-bpnkO3Z_Ba_UKU4FO0Ew3XNtWB89dCRBpCJAz+=cBVw@mail.gmail.com> <CO1PR18MB4684B704BDE52B5B4BB9B85CD944A@CO1PR18MB4684.namprd18.prod.outlook.com>
Feedback-ID: 32252813:user:proton
X-Pm-Message-ID: 03165c3d67d4e2086d195d5c3581e8b204b11e2f
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="b1=_ZBRRPn21EKdNa7xfqDBaEg8QzTyFD2hmGnwjbGl5o"
Message-ID-Hash: GDJSIDLHCHRHT5A4DY5FBTP65IUZ3S6I
X-Message-ID-Hash: GDJSIDLHCHRHT5A4DY5FBTP65IUZ3S6I
X-MailFrom: cbchhaya@pm.me
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-oauth.ietf.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: Ayesha Dissanayaka <ayshsandu@gmail.com>, "oauth@ietf.org" <oauth@ietf.org>, "brian.d.campbell@gmail.com" <brian.d.campbell@gmail.com>, "thilinasenarath97@gmail.com" <thilinasenarath97@gmail.com>, Aaron Parecki <aaron=40parecki.com@dmarc.ietf.org>
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [OAUTH-WG] Re: Security Consideration: Delegation Chain Splicing in RFC 8693 Token Exchange
List-Id: OAUTH WG <oauth.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/raNBfRf9DrYuLLf1TOry9YoQ7xM>
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>
Jeff, On CVE-2025-55241 — fair point. The root cause was unsigned JWTs and missing tenant ID validation, not act/sub binding. I cited it as a real-world example of delegation token abuse, but the structural connection to chain splicing is weaker than I originally framed it. I'll be more precise going forward. On the risk-based framing — I agree for the complex cases. Upstream delegation splice, multi-instance actors, multi-audience tokens — these genuinely depend on deployment topology and there's no single right answer. The AS is the right place for those decisions. But here's the problem: "risk-based" only works if implementers know what risks to evaluate. Right now, no mainstream AS validates delegation chain integrity (to the best of my knowledge). Not because they looked at it and decided the risk was acceptable — because nobody told them to look. Considering it takes an audience with this background to trigger that analysis, a mid-tier SaaS team building on top of RFC 8693 has no chance of arriving there independently. What I'm actually asking for is narrower than new requirements. Just name the attacks. If implementers encounter them in the spec, they'll evaluate them. If the threats aren't there, most won't. For the handful of cases where there's a clear default regardless of deployment — like verifying the presenter is an intended audience member whenaudis present — SHOULD-level guidance sets an expectation without constraining anyone. On the separate draft — agreed, this doesn't belong in 8693. You and Ayesha both point to draft-oauth-ai-agents-on-behalf-of-user as the right place. That draft handles single-hop OBO well but doesn't cover multi-hop chains,may_act, or these security considerations yet. I'm going to reach out to Ayesha about whether there's room for this in their next revision. The AuthZEN, Client ID Metadata Document, and Parecki RAR references are useful — I'll work those in where they fit. Chiradeep Sent with [Proton Mail](https://proton.me/mail/home) secure email. On Thursday, March 12th, 2026 at 11:13 AM, Lombardo, Jeff <jeffsec@amazon.com> wrote: > Hi, > > I investigated this because it was called out into another personal Draft feedback. > > I want to start by talking about the real world precedent cited in relation to the issue raise: CVE-2025-55241. This CVE is composed of two failures: > > - Actor tokens were wrapped inside an unsigned JSON web token (JWT), > - RS (in this case Azure AD Graph API) did not validate that the tenant ID field of the actor token matched the tenant being accessed > > Which means that CVE-2025-55241 would not have existed if just signature of the JWT was enforced as it is best practice. The attacker would not have been able to brute force the NetId of an existing user in the attacked tenant by changing values on client side. While this CVE is Actor token abusem I don’t see the relation in between this issue and the topic at stake as the Root Cause is neither the binding of Act or May_Act to Sub. > > Still the issue you raise is interesting. I think the edge cases Chiradeep raises prove that the security section needs more guidance. I am not sure the RFC needs more mandatory requirements. Going deeper: > > - Upstream delegation splice.Token Exchange (RFC 8693) does not provide guidance on how AS needs to check if agent-X is authorized to redelegate to agent-N cause this is a risk based approach from the AS to implement and I am not convinced there is a one guidance than can fit all. > > AI Agents are non deterministic in their way to choose a path for resolution ahead of time and to understand. Therefore there are few chances than the AS at the time of issuance can know with certitude what would be the exact audiences that the token issued could be used for future sub delegation. > > Even if the audience claim is set, and the subject claim is part of this audience there can be a lot of other reasons for the AS to refuse to comply. > > Therefore if a Token Exchange must be accepted or denied is an AS risk decision. > > For this to work, agent must provide all the context on what the intent of the Token Exchange request is, for example: > > - Agent can already use the audience parameter to try to influence the AS. > - Aaron Parecki proposed on Fri, Dec 5, 2025 at 9:24 AM – Subject: Identity Assertion JWT Authorization Grant – RAR to make RAR (RFC 9396) authorization_details parameter more apparent in RFC 8693 as well as in the Draft for ID-JAG [https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant] > > Then the guidance must be “the AS to apply the proper validation to meet its risks mitigation”. Side note: OpenID Foundation AuthZEN worked on such scenario of doing Policy Based Acces Control from the AS to a PDP to support complex use case. > > Finally, the guidance may say “the AS MAY set the audience claim to known future clients potentially authorized to sub-delegate. Please note, that any client might still request sub delegation and that it is up to the AS to accept or refuse such sub delegation whatever the subject is part of the presented audience or not”. > > - Multi-instance actors.This notion of does the client identifier represents a technical instance of a client or a functional client that can be instantiated multiple times has been raised at IETF 124 OAuth WG. > > Based on [1] answer, this is again a risk based decision of the AS. The AS can now rely on OAuth Client ID Metadata Document Draft to get more context and help to the decisionhttps://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document > > I am inclined to second the proposal that the security section may include such guidance. I don’t think we can do more. > > - Multi-audience tokens. > As presented in [1] and [2], we try to standardize a risk decision and there are more than fifty shades of decision in this spectrum. Can I resolve an audience claim value to a known disambiguated entity is a risk decision of the AS (for Token Exchange) and more largely to any RS. > > This discussion should be brought to JWT Best Practices [https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rfc8725bis-04] as section 3.9 states: > > 3.9. Use and Validate Audience > > If the same issuer can issue JWTs that are intended for use by more than one relying party or application, or may do so in the future, the JWT MUST contain an "aud" (audience) claim that can be used to determine whether the JWT is being used by an intended party or was substituted by an attacker. > > In such cases, the relying party or application MUST validate the audience value, and if no audience value is present or none of the values are associated with the recipient, it MUST reject the JWT. > > - Missing audience claimsAgain Delegation is more than audience control. In [1] we established that this could not necessarily ne defined ahead of time,. Here in [3] you want 1:1 and then here you want it do be a MUST. > > This needs to be aligned at to JWT Best Practices [https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rfc8725bis-04] > > - STS-to-STS federation. > Token Exchange is the wrong RFC for this, you need to look at ID-JAG [https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant] for that , which is mostly 2 Token Exchange flows and each of the AS / STS involved would have to do their own risk assessments. > > As pointed in [2] client can only provide as much context as possible to each of the two AS involved (the identity one and the resource one). > > - Revocation propagationThat is true. But OAuth has a lot of mechanisms for the AS to perform additional checks on revocation. For example, not exhaustively: > > - Token introspection > - Status List > > OpenID Foundation has even Shared Signals Framewrork [https://openid.net/specs/openid-sharedsignals-framework-1_0.html] to support that. > > - Token refresh as a bypass. > Token Exchange section 2.2.1 is clear: > > refresh_token > > OPTIONAL. A refresh token will typically not be issued when the exchange is of one temporary credential (the subject_token) for a different temporary credential (the issued token) for use in some other context. A refresh token can be issued in cases where the client of the token exchange needs the ability to access a resource even when the original credential is no longer valid (e.g., user-not-present or offline scenarios where there is no longer any user entertaining an active session with the client). Profiles or deployments of this specification should clearly document the conditions under which a client should expect a refresh token in response to urn:ietf:params:oauth:grant-type:token-exchange grant type requests. > > This is not recommended and again it is up to the AS to decide if it has a sense (risk decision). > > From STS/STS federation (aka cross trust domains) ID-JAG clearly states: > > [4.4.3.](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-02.html#section-4.4.3)[Refresh Token](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-02.html#name-refresh-token) > > The Resource Authorization Server SHOULD NOT return a Refresh Token when an Identity Assertion JWT Authorization is exchanged for an Access Token per [Section 5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-identity-chaining-08#section-5.2) of [[I-D.ietf-oauth-identity-chaining](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-02.html#I-D.ietf-oauth-identity-chaining)] > > When the access token has expired, clients SHOULD re-submit the original Identity Assertion JWT Authorization Grant to obtain a new Access Token. The ID-JAG replaces the use Refresh Token for the Resource Authorization Server.If the ID-JAG has expired, the Client SHOULD request a new ID-JAG from the IdP Authorization Server before presenting it to the Resource Authorization Sever using the original Identity Assertion from the IdP (e.g ID Token)If the ID Token is expired, the Client MAY use the Refresh Token obtained from the IdP during SSO to obtain a new ID Token which it can exchange for a new ID-JAG. If the Client is unable to obtain a new Identity Assertion with a Refresh Token then it SHOULD re-authenticate the user by redirecting to the IdP.If the IdP Authorization Server supports Refresh Tokens as a subject_token in Token Exchange, the client can skip renewing the Identity Assertion and directly request a new ID-JAG by presenting the Refresh Token (see [Section 4.3.1.1](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-02.html#token-exchange-refresh-token-example)) > > This being said, standardising a chain of actor is indeed something that need to happen. The fact that it could be mandatory and a breaking point into a Token Exchange flow is an expectation the AS could expose through its Authorization Server Metadata. But this is not something we can expect from all AS, for all scenarios of Token Exchange as while it provides an audit trail it also discloses past interactions. > > In any case, IMO, this should not be integrated in Token Exchange but into its own Draft proposal – like draft-oauth-ai-agents-on-behalf-of-user. > > Jeff > > Jean-François “Jeff” Lombardo|Amazon Web Services > > Architecte Principal de Solutions, Spécialiste de Sécurité > Principal Solution Architect, Security Specialist > Montréal, Canada > > Commentaires à propos de notre échange? Exprimez-vous [ici](https://urldefense.com/v3/__https:/feedback.aws.amazon.com/?ea=jeffsec&fn=Jean*20Francois&ln=Lombardo__;JQ!!Pe07N362zA!0k9CkAV8Djpw_8EfIAKrbhP3TQrJr0oMnznlUgBJ3V3NoEk6hihx7dNHnQuejn6SSH2CP8Iow3G-tTzppHeg$). > > Thoughts on our interaction? Provide feedback [here](https://urldefense.com/v3/__https:/feedback.aws.amazon.com/?ea=jeffsec&fn=Jean*20Francois&ln=Lombardo__;JQ!!Pe07N362zA!0k9CkAV8Djpw_8EfIAKrbhP3TQrJr0oMnznlUgBJ3V3NoEk6hihx7dNHnQuejn6SSH2CP8Iow3G-tTzppHeg$). > > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe. > > AVERTISSEMENT: Ce courrier électronique provient d’un expéditeur externe. Ne cliquez sur aucun lien et n’ouvrez aucune pièce jointe si vous ne pouvez pas confirmer l’identité de l’expéditeur et si vous n’êtes pas certain que le contenu ne présente aucun risque. > > Thank you for the detailed response, Chiradeep. I'll review it thoroughly and get back to you with my comments. > > On Fri, Feb 27, 2026 at 6:14 PM <cbchhaya@pm.me> wrote: > >> Dear Ayesha, >> >> Thanks for the detailed response -- good to know this lines up with discussions you're already having. The mechanisms you're evaluating are exactly what I think is needed here. >> >> Jumping into your questions: >> >> On the Intermediate Consent Step and "Verifiable Provenance" >> >> Your precondition check is closer to my first mitigation (cross-validation at the exchange boundary) than to my third (per-step delegation receipts). Worth separating these: >> >> - Cross-validation (what you're describing): The AS verifies at exchange time that the delegation is authorized -- "Is this sub-agent in a trusted tier? Does the user consent?" This stops the splice in real time. >> - Per-step delegation receipts (my mitigation #3): Each exchange step produces a signed artifact that downstream parties can verify independently, without calling back to the AS. A chain of signed assertions: "AS-1 authorized Agent-X to delegate to Agent-Y at time T with scope S." >> >> So your consent step prevents the splice; receipts prove after the fact that each step was authorized. They're complementary -- you could issue the receipt as part of the consent step. >> >> I'd prioritize the consent step for the draft. Receipts matter in audit-heavy environments (healthcare, financial services) but add token size and complexity. They also help with an operational concern I'll get to below. >> >> On aud/sub Binding: Is It Strong Enough? >> >> Short answer: yes, aud/sub binding is the right primitive. How well it holds up depends on enforcement and a few edge cases I've been thinking through. >> >> The core mechanic works: If Alice's token carries aud: "agent-X", and the STS requires actor_token.sub to match, then Agent-X can't present Agent-N's actor_token -- sub: "agent-N" doesn't match aud: "agent-X". Splice blocked. >> >> But there are edge cases worth working through: >> >> - Upstream delegation splice. This one concerns me the most. Agent-X legitimately holds Alice's token (aud: "agent-X"). Agent-X then requests a new token from the AS with aud: "agent-N" to enable sub-delegation. If the AS issues this without checking whether Agent-X is actually authorized to re-delegate to Agent-N on Alice's behalf, the splice just moves upstream -- Agent-X gets the AS to produce the mismatched token for it. Your precondition check is what closes this hole: the AS has to verify the re-delegation before issuing the new token. I'd suggest calling this out explicitly in the draft -- aud/sub binding prevents splicing at the exchange boundary, but without the precondition check, a malicious agent can effectively get the AS to splice on its behalf. >> - Multi-instance actors. In production, an "agent" is often a horizontally-scaled service behind a load balancer. Alice's token might have aud: "agent-x-service", but the instance presenting the actor_token has sub: "agent-x-instance-47". The simple equality check breaks. The AS would need to resolve service principal identifiers to sets of valid instance-level subjects. Not a blocker, but it's real implementation complexity. >> - Multi-audience tokens. A token with aud: ["agent-X", "agent-Y", "agent-N"] weakens the binding since multiple actors could satisfy the match. For delegation, I'd push for single-valued audience claims to keep the 1:1 binding strict. >> - Missing audience claims.aud is optional in JWTs. No aud on the subject_token means no binding, which means the splice is back on the table. Strong argument for making aud mandatory when tokens participate in delegation chains. >> - STS-to-STS federation. When delegation chains span multiple STSs across trust domains, each STS sets the audience for its own leg. A downstream STS trusts the upstream token's audience claim but can't verify the upstream STS actually performed the aud/sub check. A misconfigured upstream STS could issue tokens with overly permissive audience values. >> - Revocation propagation. If Alice revokes consent for Agent-X, the consent step prevents new delegations. But tokens already held by downstream agents (Agent-Y, Agent-Z) are still valid until they expire. We'd need to address chain-wide invalidation -- short lifetimes, back-channel revocation, or requiring resource servers to re-validate the full chain on each request. >> - Token refresh as a bypass. Related to revocation: if the AS issues refresh tokens alongside exchanged access tokens, the refresh flow (RFC 6749 Section 6) doesn't require re-presenting the subject_token or actor_token. An agent whose delegation has been revoked could still refresh its way to a new access token if the refresh endpoint doesn't re-validate the delegation context. DPoP (RFC 9449) dealt with a similar gap by requiring proof presentation on refresh, not just on initial requests. I'd suggest the draft include guidance along the lines of: "When refreshing tokens issued via delegated token exchange, the AS SHOULD re-validate the delegation context, including verifying that upstream consents remain active." Without that, the consent-per-step model has a quiet backdoor through the refresh endpoint. >> >> On may_act vs aud -- Simultaneous or Either/Or? >> >> I think you need both, enforced together. They cover different failure modes: >> >> - aud/sub binding: "Was this token intended for the actor presenting it?" -- a per-transaction binding that prevents misuse at the exchange boundary. >> - may_act: "Is this actor authorized to act on behalf of this subject?" -- a policy declaration from the subject (or the AS on their behalf). >> >> Each alone has gaps: - aud/sub alone: Without the precondition check, a malicious agent can ask the AS to issue a token with aud matching any downstream actor (the upstream delegation splice from edge case #1). - may_act alone: Validates identity but not that the actor_token came from the same delegation context -- the original gap. >> >> Both together: the token has to be intended for the actor (aud) AND the subject has to have authorized that actor (may_act). >> >> On the Dynamic Discovery Problem >> >> Agreed -- requiring the full chain upfront is impractical for real agent systems. The intermediate consent step handles this well: the AS verifies each delegation at exchange time while the chain gets built incrementally as agents discover what they need downstream. >> >> There are some operational costs to this approach worth documenting in the draft: >> >> - Latency: Every delegation hop in a chain of N agents adds a synchronous round-trip to the AS. For latency-sensitive orchestration this adds up. >> - Availability: The AS becomes a single point of failure for every agent-to-agent delegation, not just user logins. An AS outage halts all agent collaboration. That's a meaningfully higher availability bar for AS infrastructure. >> - Offline/disconnected scenarios: Consent-per-step is inherently online. For edge computing or intermittent connectivity, pre-signed delegation receipts (mitigation #3) are probably the better fit since they don't require an AS callback. >> - Backward compatibility: On the upside, this should be backward-compatible at the protocol level. RFC 8693 is a framework; these are AS-side validation rules. Existing clients don't change -- the AS just gets stricter about what it permits. >> >> Not reasons to avoid the approach, but trade-offs that implementers should understand. >> >> Pulling This Together >> >> If I were writing a concrete mitigation profile, I'd combine your consent step with the binding mechanisms: >> >> - The AS MUST verify subject_token.aud matches actor_token.sub at each token exchange (with support for resolving service principal identifiers to instance-level subjects). >> - For delegation chains, the subject_token MUST carry a single-valued aud claim identifying the intended next actor. >> - The AS MUST validate the delegation against policy (may_act or equivalent) before issuing the new token. >> - The AS SHOULD issue the new token with aud set to the intended downstream actor, maintaining the binding through the chain. >> - Implementers SHOULD use short token lifetimes and consider back-channel revocation to limit exposure for downstream tokens after consent is withdrawn. >> - When refreshing tokens issued via delegated exchange, the AS SHOULD re-validate the delegation context, including verifying that upstream consents remain active. >> >> Happy to keep this going and contribute to the draft if it's useful. >> >> Best. >> >> On Friday, February 27th, 2026 at 1:20 AM, Ayesha Dissanayaka <ayshsandu@gmail.com> wrote: >> >>> Dear Chiradeep, >>> >>> Thank you for this detailed and timely analysis, and I find your "delegation chain splicing" concept particularly relevant. Your timing is impeccable; we have been actively discussing how to securely bind the requested party beyond the initial delegation point to prevent exactly the kind of context-switching you’ve described. >>> >>> I agree with your assessment regarding the gap between the subject_token and actor_token. The lack of a normative requirement to bind the may_act claim of the subject token to the actual identity presented in the actor token is a structural blind spot. >>> >>> Practical Challenges: The Dynamic Discovery Problem >>> >>> While I agree with the need for stronger binding, I see significant practical limitations in requiring the delegation chain to be fully defined upfront. >>> >>> In sophisticated multi-agent systems, agent discovery is often dynamic. A primary agent might not know which specific downstream sub-agents (e.g., a specialized medical coding agent or a specific CI/CD runner) will be required to fulfill a request until the execution phase. >>> >>> - The Scalability Issue: Listing every potential actor in a may_act claim at the start of the flow could lead to massive tokens and require the user (or the initial STS) to have perfect foresight of the entire downstream topology. >>> - The Flexibility Issue: Hard-coding the chain limits the ability of the system to adapt to runtime failures or load balancing, where a different, but still trusted, agent needs to step in. >>> >>> Evaluating "Exchangeable" Subject Tokens via Intermediate Consent >>> >>> To solve the "Dynamic Discovery" problem while maintaining the security you've identified, we are evaluating an improvement to the draft-oauth-ai-agents-on-behalf-of-user draft: The Intermediate Consent/Exchange Step. >>> >>> Instead of a static chain, we are exploring a flow where the incoming subject_token is exchanged for a specifically "exchangeable" subject token. >>> >>> - Request for Delegation: When a primary agent discovers it needs a sub-agent, it requests a refined token from the Authorization Server (AS). >>> - Precondition/Policy Check: The AS evaluates the request against a precondition (e.g., "Is this sub-agent in a 'Highly Trusted' tier?") or triggers a dynamic user delegation (e.g., a push notification to the user for high-risk sub-agent access). >>> - Binding: The AS issues a token where the aud (audience) is explicitly bound to the sub (subject) of the intended actor, and/or has may_act, including the requested actor, intending to exchange the token. >>> >>> Does the introduction of a "precondition check" at the AS provide the "verifiable provenance" you suggested in your third mitigation (Per-step delegation receipts)? >>> >>> Additionally, this step would grant a mechanism for dynamic authorization delegation (step-up) for the downstream actors. >>> >>> Exploring Audience (aud) to Subject (sub) Binding >>> >>> One mechanism we have also been evaluating and implementing at the token exchange is, without requiring a pre-defined list of all actors, is a stricter enforcement of the Audience (aud) claim. Specifically, we are looking at a requirement where: >>> >>> The aud (Audience) of the subject_token must match the sub (Subject) of the actor_token. >>> >>> In theory, this ensures that the token being exchanged was specifically intended for the party currently acting as the "actor." This would prevent an intermediary from taking a token meant for "Agent A" and using it as a subject_token in a request where "Agent B" is the actor. >>> >>> I'm also looking forward for everyones thoughts on this: Is the cryptographic link created by requiring the aud (audience) of step 'N' to match the sub (subject) of step 'N+1' strong enough to prevent splicing? Are there edge cases where an attacker could still manipulate the context? Should both may_act and aud validations occur simultaneously, or is one of them sufficient? >>> >>> Regards, >>> Ayesha >>> >>> On Fri, Feb 27, 2026 at 9:58 AM <cbchhaya@pm.me> wrote: >>> >>>> Dear OAuth Working Group, >>>> >>>> I am writing to share a potential security finding related to the act (actor) claim in RFC 8693 (OAuth 2.0 Token Exchange) that I believe warrants consideration, particularly as the working group advances specifications for agentic OAuth flows (draft-oauth-ai-agents-on-behalf-of-user, transaction tokens, etc.). >>>> >>>> Summary >>>> >>>> I may have identified a structural weakness I call "delegation chain splicing" -- a technique by which a compromised intermediary can present mismatched subject_token and actor_token inputs to the token exchange endpoint from different delegation contexts. The STS validates each token independently (per Section2.1-2.2), finds both valid, and issues a new properly-signed token asserting a delegation chain that never actually occurred. >>>> >>>> The root cause is that RFC 8693 does not require cross-validation between the subject_token and actor_token -- specifically, there is no mechanism to verify they belong to the same delegation flow, authorization session, or trust context. >>>> >>>> Why This Matters Now >>>> >>>> While RFC 8693 Section4.1 correctly states that nested act claims are "informational only" for access control, the proliferation of agentic AI systems creates deployment contexts where delegation chain history is increasingly relied upon for: >>>> >>>> - Audit trail integrity (required under HIPAA, SOC 2) >>>> - Policy enforcement ("was there a human in the loop?", "how many delegation hops?") >>>> - Anomaly detection and trust scoring >>>> - Compliance reporting >>>> >>>> The may_act claim (Section4.4) provides partial mitigation by restricting which actors may exchange a token, but it validates the actor's identity, not that the actor credential was acquired within the same delegation context. It is also optional -- there is no normative requirement that subject tokens carry may_act or that the STS enforce it. >>>> >>>> The draft-oauth-ai-agents-on-behalf-of-user specification takes a step in the right direction by binding the authorization code to the actor (Section5.5), but this protects only the initial user-to-agent delegation. Subsequent agent-to-agent token exchanges -- where chain splicing occurs -- remain unaddressed. >>>> >>>> Real-World Precedent >>>> >>>> CVE-2025-55241 (Microsoft Entra ID, patched July 2025) demonstrated that actor token validation failures have Critical-severity impact in production. That vulnerability involved unsigned actor tokens enabling cross-tenant impersonation -- a closely related class of act claim misuse. >>>> >>>> Suggested Mitigations for Consideration >>>> >>>> - Cross-validation requirement: The STS should verify that the actor_token subject matches an authorized next-actor declared in the subject_token (strengthening may_act from optional to normative). >>>> - aud/sub chaining within act claims: Require that nested act claims include fields forming a verifiable chain -- similar to what OIDC-A 1.0 specifies for delegation_chain, where the aud of step N must match the sub of step N+1. >>>> - Per-step delegation receipts: Each STS that performs a token exchange includes a signed attestation of the delegation step, providing independently-verifiable provenance. >>>> >>>> Full Write-Up >>>> >>>> A detailed write-up with three concrete scenarios (healthcare, multi-tenant SaaS, CI/CD), mechanism description, conditions for exploitability, anticipated counterarguments, and mitigations is attached. >>>> >>>> This finding was independently validated by multiple analyses working from the RFC 8693 specification text alone. >>>> >>>> I welcome feedback and am happy to discuss further. >>>> >>>> Best regards, >>>> >>>> Chiradeep Chhaya >>>> >>>> --------------------------------------------------------------- >>>> >>>> Note: This finding was identified during security research with the assistance of AI tools (Claude by Anthropic and Gemini by Google), which were used for collaborative analysis, adversarial review, and independent validation. I am sharing it with the working group for independent validation and consideration in ongoing specification work. > >> From: Ayesha Dissanayaka <ayshsandu@gmail.com> >> Sent: March 3, 2026 11:21 AM >> To: cbchhaya@pm.me >> Cc: oauth@ietf.org; brian.d.campbell@gmail.com; thilinasenarath97@gmail.com >> Subject: [EXT] [OAUTH-WG] Re: Security Consideration: Delegation Chain Splicing in RFC 8693 Token Exchange
- [OAUTH-WG] Security Consideration: Delegation Cha… cbchhaya
- [OAUTH-WG] Re: Security Consideration: Delegation… Ayesha Dissanayaka
- [OAUTH-WG] Re: Security Consideration: Delegation… cbchhaya
- [OAUTH-WG] Re: Security Consideration: Delegation… Ayesha Dissanayaka
- [OAUTH-WG] Re: Security Consideration: Delegation… Lombardo, Jeff
- [OAUTH-WG] Re: Security Consideration: Delegation… cbchhaya