Hello Paul, For now, we haven't heard any blockers to the proposed solution using HTTP > OPTIONS and no better solutions were proposed either.
I've mentioned in the meeting that using OPTIONS on endpoints which already have CORS handlers is problematic because their OPTIONS HTTP method handling will now serve multiple purposes. This complicates implementation and hinders debugging (since from http logs you won't be able to discern between a CORS preflight and challenge-fetch). I was not the only one sharing that concern in the meeting and for the sake of being on the record, it is a blocker from my perspective. Let's search for better solutions. if we send some kind of fake request, it's unreliable because we don't know > which error will be triggered, e.g. runs validation far enough in AS code > to trigger nonce error? this behavior is not standardized and hence > unreliable We're discussing that very standardization right now. If we made any oauth 2.0 style endpoint error be accompanied by a server-provided challenge normatively, would that immediately be unreliable? No, because we'll define it properly. And i'm not saying to do a fake request, you're still making the same request as per usual, only instead of authenticating the client you just don't - i.e. instead of sending the regular set of auth-related parameters you send just a client_id (plus the rest of the request as per its definition), you change client auth from "attestation-based" to "none" for the sake of fetching a nonce. And it's not unreliable because we'll be the ones defining the behaviour. if we send a real request containing no nonce, it's potentially expensive, > if we use hardware key stores or remote key stores I am aware of what we're solving for and my suggestion *is* solving for not sending the expensive to form auth parameters when you don't have a challenge at all in the case of a cold start (or expired challenge - given I propose the challenge header to come with an expiration delta). We agree with your proposal but it does not solve the problem, and hence we > believe that explicit nonce requesting is still necessary. > I agree nonce requesting is still necessary, which is why I've included it in the suggestion, only through different means - without adding an overload to an existing http verb used for CORS preflights on existing endpoints and one that is within the boundaries of an OAuth 2.0 client-authenticated request. Summarizing, we should look for a different solution than OPTIONS on existing endpoints because it conflicts with existing unrelated behaviours (CORS). Any solution we consider that doesn't extend existing OAuth 2.0 responses should also likely stay within the confines of being a Simple Request <https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS#simple_requests> but preferably we'll consider extending our existing protocol messages and using their existing semantics before resorting to adding new endpoints. S pozdravem, *Filip Skokan* On Thu, 17 Apr 2025 at 14:18, Paul Bastian <paul.bast...@posteo.de> wrote: > Hi Filip, > > answers are inline: > On 4/11/25 12:18, Filip Skokan wrote: > > Hello Christian, > > I've deployed the following optimization for DPoP on the AS in the past > that we may get inspired by. Given the DPoP "nonce" mechanism, much like > what we're talking about in the attestation based client authentication > context here, is to ensure freshness and not be a real "number used only > once" the AS doesn't respond with traditional timestamped values but > instead have a server side TOTP-like mechanism. In this mechanism using a > TOTP-like step interval (and a secret only known to the server) the AS > keeps a list of currently acceptable values that get continuously rolled > following the step interval. At a given time the server accepts values > produced by 5 step counters, 2 steps from the past, current step, and 2 > future steps. When a new value needs to be returned (e.g. because the one > used is already not accepted or is about to not be acceptable soon) the AS > returns the current step + 1 value, leaving current step + 2 as a mechanism > for dealing with the different instance server side clock skew. This allows > the AS to always return a header value it knows would be accepted by any of > its instances regardless of whether a client needs one or not with no > computational burden and it allows the client that regularly communicates > with the AS to never not have a fresh value to use in its assertions at > hand. > > You are basically describing self-contained/state-less nonces. While we > agree that self-contained nonces are best practice, it's not the core > problem being addressed with nonce fetching. We may however add some > recommendations in the implementation consideration. > > Upon a cold start the client does metadata discovery and it can already > get a valid value there before kicking off e.g. a PAR request where it can > already submit a DPoP Proof for the purpose of Authorization Code and > Public Key Binding. This means in an ideal scenario that no additional > requests need to be made. > > Back to a general "freshness" mechanism. What if we designated an HTTP > Response Header parameter applicable to *any* AS HTTP response that > carries a currently accepted value? A client that regularly communicates > with the AS would always have a very likely usable value to use. Cold start > clients that perform discovery could get a value that way. The header value > could even carry a valid until timestamp or an expires_in delta value to > let the client know not to use an expired value. Much like in DPoP-Nonce > case a new header value received means to stop using the old one and use > the new. And to get a fresh value in the scenario where the value client > has is expired (based on the indicated delta or timestamp) the client can > do a request to the authenticated endpoint (e.g. PAR, or token endpoints) > without the expensive to generate credentials expecting an error response > in which a fresh value would be carried by HTTP Response Headers. > > We agree that returning nonces on any response is a good idea, that we > already have on the radar ( > https://github.com/oauth-wg/draft-ietf-oauth-attestation-based-client-auth/issues/101) > and plan to add for the next draft. Especially for ecosystems defining > their rules/setups, this can be handy. > > However, that does not solve the following two problems, that are the > actual motivation for explicit nonce fetching mechanism: > > - on a cold start, especially with PAR Request without any prior > communication, there is no previous communication > - in some situations, like Authorization Response through the user > agent/Browser, there is possibility to pass HTTP Headers in the response > > Furthermore, it was suggested to request nonces with errors, as being done > by DPoP. This solution is either unreliable or expensive: > > - if we send some kind of fake request, it's unreliable because we don't > know which error will be triggered, e.g. runs validation far enough in AS > code to trigger nonce error? this behavior is not standardized and hence > unreliable > - if we send a real request containing no nonce, it's potentially > expensive, if we use hardware key stores or remote key stores > > That's a long-winded way of saying, TL;DR, let's *consider *the > option of giving the AS the option to return a freshness challenge value in > every HTTP response via a header, have the header be structured to indicate > the value and its expiration, have the client behave right when new values > are received and, specific to Attestation-Based Client Authentication, tell > the client that if it doesn't have a valid challenge value to use - make > the request to the endpoint without credentials (or possibly with just a > client_id. We don't need to specify a new endpoint and end up with a > freshness mechanism that might be usable for future cases. Would AS > implementers tolerate the occasional client authentication error response > if it means no introduction of contentious endpoints? > > S pozdravem, > *Filip Skokan* > > Summarizing, we agree with your proposal but it does not solve the > problem, and hence we believe that explicit nonce requesting is still > necessary. For now, we haven't heard any blockers to the proposed solution > using HTTP OPTIONS and no better solutions were proposed either. > > Best regards, > > Paul > > > > On Sat, 5 Apr 2025 at 17:16, Christian Bormann <chris.bormann= > 40gmx...@dmarc.ietf.org> wrote: > >> Hi All, >> >> >> >> We had a discussion about a nonce fetching mechanism for the >> Attestation-Based Client Authentication draft at the >> >> IETF 122 session. Since we didn’t really reach a consensus there, we’d >> like to continue the discussion on the mailing list. >> >> >> >> To summarize the problem briefly: The draft specifies a proof of >> possession that optionally signs over a server-provided >> >> nonce to guarantee freshness of said proof of possession. Since we expect >> this specification to be used in some contexts >> >> where creating a PoP might be expensive (e.g., require a user >> interaction), we were searching for a mechanism where >> >> the nonce is not provided via an error (as is the case for DPoP - which >> would often require the generation of 2 PoPs), >> >> but in a way that guarantees that we have a fresh nonce before creating a >> PoP. >> >> We were thinking about either >> >> - a dedicated nonce endpoint (within the scope of an AS or RS) >> - or a mechanism to explicitly ask for a nonce in a request to an >> existing OAuth endpoint (e.g., the PAR endpoint). >> >> >> >> After some discussion at OAuth Security Workshop, we proposed to use a >> dedicated header to signal a request for a new >> >> nonce. This could work at any existing OAuth endpoint that wishes to use >> an attestation-based client authentication. Brian >> >> rightfully mentioned that only adding one header field and completely >> changing the behaviour of said endpoint does not >> >> sound like a good idea and proposed to use a different HTTP method. Brian >> initially proposed HEAD and after some more >> >> discussion we ended with an OPTIONS request as the seemingly best idea. >> >> >> >> The idea as currently document in the draft is to use an OPTIONS request >> with a specific header field to request a nonce. >> >> The current proposal would mean that for a request to a PAR endpoint >> >> 1. The client discovers via metadata that the PAR endpoint requires >> attestation-based client authentication with a nonce >> 2. The client sends an OPTIONS request: >> >> OPTIONS /as/par HTTP/1.1 >> >> Host: as.example.com >> >> attestation-nonce-request: true >> >> 3. The client receives a nonce in the response: >> >> HTTP/1.1 200 OK >> >> Host: as.example.com >> >> attestation-nonce: AYjcyMzY3ZDhiNmJkNTZ >> >> 4. The client does the “real” request to the PAR endpoint including >> the client authentication (via header fields): >> >> POST /as/par HTTP/1.1 >> >> Host: as.example.com >> >> Content-Type: application/x-www-form-urlencoded >> >> OAuth-Client-Attestation: eyJ0eXAiOiJvYXV0aC… >> >> OAuth-Client-Attestation-PoP: eyJhbGciOiJFUzI… >> >> >> >> response_type=code&state=af0ifjsldkj&client_id=s6BhdRkqt3 >> >> &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb >> >> &code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U >> >> &code_challenge_method=S256&scope=account-information >> >> >> >> At the IETF 122 session, Filip voiced concerns that since OPTIONS is used >> for CORS preflight requests, it would mean that at >> >> least for frontend clients, this mechanism would result in several >> OPTIONS requests. For JavaScript clients, the CORS preflight >> >> requests cannot be used or modified and the client would then manually >> create another OPTIONS request to get the nonce. >> >> From a simple OPTIONS (preflight) and POST requests (normal request to >> PAR), we would get to OPTIONS (preflight), >> >> OPTIONS (nonce fetch), OPTIONS (preflight), POST requests. >> >> >> >> We tried to capture those concerns in this issue: >> https://github.com/oauth-wg/draft-ietf-oauth-attestation-based-client-auth/issues/102 >> >> and would like to pick that discussion up again to find some consensus >> what the best option would be to for a nonce request. >> >> >> >> Would people be more comfortable if we instead point to an endpoint that >> can be used to request a nonce (dedicated endpoint >> >> that could for example, be discoverable via metadata), or is it fine to >> cause more requests and we should move ahead with the >> >> current variant based on OPTIONS? >> >> >> >> Best Regards, >> >> Christian, Paul, Tobias >> _______________________________________________ >> 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 > > _______________________________________________ > 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