I would say it is a significant limitation in OAuth 2 that the logical client 
instances can only be uniquely identified across authorization requests via a 
unique client_id and persisted AS state. For instance, there's no 
“reauthorization_state” you get along with your AT/RT (or in response to a 
failed refresh token grant) that can be used to link a prior authorization and 
consent to the new request hitting through the user agent.

We see this in public clients in particular, where the single shared client_id 
across many instances (running in browsers and within native apps on phones) 
results in stronger consent processes needed on periodic reauthorizations, and 
a push toward using implementation-specific tricks (DCR using software 
statements, long lived DPoP public keys as secondary identifiers, and more) to 
try to optimize the reauthorization business processes and UX by acknowledging 
this is a continuation of previously authorized access, and to allow for 
improved audibility and user self-service UX by representing these public 
clients as distinct.

If with this proposal each request from a client is now a distinct risk 
decision made ephemerally, would it not mean that this is potentially a new 
type of client even broader than public clients, where they are effectively a 
distinct client on subsequent authorization requests?

That would seem to imply an even stronger privacy approval/consent requirement 
by the AS than we have today, make end user management of those tokens/consents 
conceptually difficult, and potentially would have an impact on how access to 
protected resources would work across reauthorizations in practice (since an 
ongoing transaction may now be seeing access from two distinct "clients")

I’m trying to understand better what trade-offs would guide implementer 
decision on whether to deploy.

-DW

> On Jun 26, 2025, at 3:12 PM, Justin Richer <jric...@mit.edu> wrote:
> 
> I’ve been seeing a lot of recent conversations trying to work around the 
> limitations of OAuth needing a client_id as part of the syntax of the 
> protocol. This is especially pertinent with proxy protocols like MCP, in 
> which the client could be very ephemeral and have no real way to establish 
> itself with the AS ahead of time. Dynamic Client Registration does work, of 
> course, as do public clients — but both of these have their limitations. With 
> DynReg, you end up with a client_id that might never get used again. With 
> public clients, you still require a pre-registration but don’t really get the 
> security benefits of registration. And for a highly dynamic system, the 
> pre-registration doesn’t make sense. There are other approaches like having 
> the AS fetch the client’s info from a URL, but that assumes the client can 
> host something accessible to the AS and the AS is protected against SSRF 
> attacks.
> 
> After talking through some ideas with Aaron, we came up with a pattern that 
> leverages PAR and the authz code flow to allow a client to push its 
> registration information as part of the PAR request and continue the OAuth 
> process using a stand-in client identifier for syntactical compatibility. 
> 
> https://www.ietf.org/archive/id/draft-richer-oauth-pushed-client-registration-00.html
> 
> The short version of the process goes like this:
> 
> 1. Client makes a PAR request with a special client_id value to trigger this 
> (we’ll use “dynamic” in the example but it’s a fixed string that’s always the 
> same for all clients). The request includes its redirect URI and optionally 
> any other DynReg client metadata, and can also include any keys and 
> challenges for PKCE and client auth
> 2. AS returns a request_uri like normal PAR, but this creates an internal 
> transaction that is bound to the parameters sent in (1)
> 3. Client calls the authz endpoint with the request_uri and the special 
> client_id value, “dynamic”
> 4. AS loads the configuration based on the request_uri and processes the 
> request as usual
> 5. AS returns the “code” and anything else relevant, as usual
> 6. Client calls the token endpoint with the code, PKCE verifier, proof of its 
> keys from (1), and the client_id value of “dynamic”; could include a 
> DPoP/MTLS proof too
> 7. AS loads the approved request from the “code” value and processes it as 
> usual
> 8. AS returns a token as usual
> 9. Client uses the token as usual
> 
> 
> While it was MCP that brought this up, the pattern also shows up in other 
> places like connecting instances of an email client to instances of an email 
> server. 
> 
> I’d like to get some time on the agenda for Madrid to discuss this draft in 
> greater detail.
> 
>  — Justin
> _______________________________________________
> OAuth mailing list -- oauth@ietf.org
> To unsubscribe send an email to oauth-le...@ietf.org

_______________________________________________
OAuth mailing list -- oauth@ietf.org
To unsubscribe send an email to oauth-le...@ietf.org

Reply via email to