Subject: Re: [Txauth] XYZ-08 vs XAuth-08
From: Justin Richer <[email-masked]>
To: Dick Hardt <[email-masked]>
Cc: [email-masked]
Date: Wed, 10 Jun 2020 10:54:25 -0400
List-Id: <txauth.ietf.org>

> On Jun 9, 2020, at 4:11 PM, Dick Hardt <[email-masked]> wrote:
> 
> Comments inline
> 
> Last item will be broken out to new thread.
> 
> On Tue, Jun 9, 2020 at 9:10 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> 
> 
>> On Jun 8, 2020, at 5:33 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> 
>> 
>> On Mon, Jun 8, 2020 at 1:02 PM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> <snip>
>>> A GS implementation can decide to only return an authorization from doing a GET on the AZ URL. Returning only an AZ URL is an option in XAuth. Similarly, we could do the same for a Grant URI. 
>> 
>> And that’s a lot of complex code paths for both the GS and client to deal with. With more ways that it might happen, the client has to be prepared for any of them — and get them all right. 
>> 
>> I don't see it being complex. The data either moves by reference or by value. Both parties will have to enable support by reference. Passing by value is an optimization so that the client does not have to make an additional call.
> 
> “Both parties will have to enable” is where the complexity comes into play. It’s putting a requirement on the client to anticipate several different ways to get the same information.
> 
> As I understand it, XYZ works the same way. The client may get a handle to the transaction in an Interaction Response or a Wait Response, or the client receives a transaction response.
> 
> There could be only one way in XAuth (pass by reference), but I expect that people will prefer an optimization of pass by value when it can be done and deal with the complexity that they may get the data in two different ways, just as in XYZ.

It’s not the same. What you’re missing, I believe, is that this is one of the benefits of having a single endpoint, as XYZ is defined today. The “grant response” comes from exactly one place regardless of where in the transaction it happens. This is why I think this is something the working group as a whole needs to weigh in on, to figure out the pros and cons of different designs. I personally don’t like the complexity, and a definitely don’t like the restrictions imposed by XAuth today, but there are benefits that might outweigh and justify that move. 

>  
> 
>> 
>>  <snip>
>> 
>>>  
>>> 
>>> Using a different URI, optionally, isn’t the problem, and that could easily be added to the. Removal of the separate handle is the problem I have with the XAuth approach.
>>> 
>>> In XAuth, the Grant URI is the GS URI + TBD + handle
>>> 
>>> Given we have asymmetric crypto as a requirement, it is unclear what having two pieces of random signal provide.
>> 
>> Asymmetric crypto is an implementation requirement in both the input drafts but it isn’t a requirement in the charter, and there are likely symmetric use cases and key proofing mechanisms that are going to be desirable for a lot of people.
>> 
>>>  
>>> 
>>>>  
>>>> 
>>>> Additionally, I find XAuth’s restrictions on the structure of the Grant URI potentially problematic, namely that it has to start with the server’s URL. This will lead to deployments needing to bend their setups with proxies or redirectors to make things fit, which you yourself have said is going to be an issue for things like supporting a short redirect URL vs. a long redirect URL. Your complaint there was one of latency and complexity, why does that not apply here? But most fundamentally, I do not see what value this restriction brings to the system. If the value is coming back from the GS endpoint, and the client is getting all of its pointers from there, what’s the point of dictating how that has to look?
>>>> 
>>>> Requiring the Grant URI to start with the GS URI is open to discussion. It is not clear to me why a deployment would need to have a redirector. Large scale deployments I have worked on have a router / proxy that routes requests to internal services. Having all the URIs start with the GS URI enables all GNAP operations to be routed in the same place.
>>> 
>>> You still haven’t addressed why you think that this is a reasonable requirement or assumption here but not when dealing with long/short URLs for QR codes. What is the difference?
>>> 
>>> Short URLs generally use a short host name as well as a short path. 
>>> 
>>> Most REST interfaces have the pattern I am proposing. A mental model many developers are familiar with. 
>> 
>> This is assuming a lot on the part of the GS implementation, still, and all of my arguments stand. 
>> 
>> 
>> That is not entirely correct. A pre-registered client can still pass its key by value, and a dynamic client can still use a (dynamically-acquired) handle. In all cases, the client is identifying itself by its key. The difference is how the server looks up that key — it’s either from the handle, or it’s from the key value itself. 
>> 
>> I don't understand this. 
>> 
>> How is the Client authenticating that it is a specific pre-registered client?
> 
> The client is identified by its key.
> 
> And you think that will be an easy concept for developers to migrate to from the mental model they have now? And what is the value? I believe your proposal for other pre-registered clients to migrate was to use the Client ID as the Key Handle. So the Key Handle may represent any of the pre-registered clients, but represents each instance of a dynamic client. Does not seem like it is any different than how a Client ID is used today.
> 
> Tom has started a new thread on other aspects of this section.

Not only do I think OAuth developers can migrate, I think it’s essential that we do in order to make this useful to non-OAuth developers. Vast swaths of the internet are already building out key-based systems, not using OAuth. In my own experience, I can say for a fact that the awkwardness of needing a client identifier ahead of time is one of the problems. The fact that there’s a place to use a legacy client ID within the protocol is a bonus feature, and important for migration. But it’s even more important that it’s not 

And we should look at history before we declare something impossible. We managed to get web developers away from thinking about accessing an API with a username and password and toward thinking in terms of accessing it with a token. This is a shift of the same kind, and an important one at that.

To me, this is one of the important fundamental shifts of this work away from the limits of OAuth’s models and assumptions, and one of the ones that will make this work applicable far outside of the space that OAuth 2 has already carved. I don’t see a compelling reason to limit ourselves.

If your primary goal is to keep OAuth 2 developers safe and happy, then in all honesty, just keep using OAuth 2. Why wouldn’t you? Use PAR and RAR and DPoP for advanced functionality. It’s a combination that, if a bit patched-together, does work. Move to a new protocol when it does something you can’t do, or it’s otherwise a better fit for what you’re trying to solve. And when you’re in a position to move, there’s a migration path. That doesn’t mean it’s a direct re-use, it means you can migrate — move, change — without tearing absolutely everything out. But you still need to move, and that’s expected. 

In all honesty, I think the gap between OAuth 2 and XYZ is less than the gap between OAuth 1 and OAuth 2, especially if you’re looking at using OAuth 2 with PAR, RAR, etc. I don’t see a compelling reason to artificially limit the new protocol with the constraints of the old, particularly when there’s a migration path between them. XYZ can make use of some of the familiar pieces of OAuth 2 without causing all clients to depend on them. That’s the difference between migration and straight re-use.

>  <snip>
>> In XAuth, if the server wants to protect itself from a session fixation attack in a given request, and it wants to support both "redirect" and "user_code" modes, 
>> the server will return only those two modes and not "indirect". The 
>> 
>> In XAuth, if the server wants to protect itself from a session fixation attack in a given request, and it wants to support both "redirect" and "user_code" modes, 
>> the server MUST return callback, redirect, and user_code. The client does not know that the "indirect" mode is not supported, and may try that.
>> 
> 
> In XYZ, if the server wants to protect against a session fixation attack, it will reject a request that doesn’t have a “callback” field in it. The AS always gets to choose which things it supports for any given request. If the client wants to support both “redirect” and “user_code’ modes AND has the ability to handle session fixation issues, it sends the “redirect”, “user_code’, and “callback” fields in its interaction request. 
> 
> If the client chooses to present the interaction_url as a scannable barcode, which is an option if it receives one, it will then get an error when it tries to do a transaction continue request as the AS protects itself. Unfortunately the user has scanned the barcode and is now at the AS. I don't see how the client learns it is not able to do what I call an "indirect" mode interaction. Would you explain how this situation is prevented in XYZ?

If the client has made a request with “redirect” and “callback” in its request, and then decides to display the interaction URL as a scannable code, then the AS will just redirect to the client’s callback URL when it’s done, whatever that URL was. If the client sends a “callback” URL that it can’t get information from, then that’s a poorly-written client, isn’t it?

If the client can’t get to the information in the callback URL unless it’s on the same device, then the client isn’t going to show the user a scannable code to be read by a secondary device. Why would it?

> 
> <snip>
>>  
>> 
>>> 
>>> For example: 
>>> 
>>> How is a transaction updated? 
>>> How are separate access tokens refreshed? 
>>> Refreshing an access token in XYZ returns a full transaction response per Section 9.3 which refers to Section 8.
> 
> Would you address these questions?

Transactions are updated by sending the transaction handle back with additional information. This is no different from the request made after a front channel callback, or what would be made in a challenge-response format. I haven’t written up a way to create a new transaction building on an old one (which I think is an important advanced use case), but it would amount to having a separate field in the initial transaction request to have the transaction handle of the old transaction in it. 

Multiple access tokens cannot be refreshed separately in the current implementation of XYZ. This is a noted gap in the spec, and I’m open to ideas on how it would be handled.

>  
>>> 
>>> 
>>> By using URIs and methods, XAuth has an easy to understand API for CRUD operations on Grants and Authorizations.
>>> 
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | request      | http verb | uri    | response                    |
>>>     +==============+===========+========+=============================+
>>>     | Create Grant | POST      | GS URI | interaction, wait, or grant |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | List Grants  | GET       | GS URI | grant list                  |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Verify Grant | PATCH     | Grant  | grant                       |
>>>     |              |           | URI    |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Read Grant   | GET       | Grant  | wait, or grant              |
>>>     |              |           | URI    |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Update Grant | PUT       | Grant  | interaction, wait, or grant |
>>>     |              |           | URI    |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Delete Grant | DELETE    | Grant  | success                     |
>>>     |              |           | URI    |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Read AuthZ   | GET       | AZ URI | authorization               |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Update AuthZ | PUT       | AZ URI | authorization               |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Delete AuthZ | DELETE    | AZ URI | success                     |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | GS Options   | OPTIONS   | GS URI | metadata                    |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | Grant        | OPTIONS   | Grant  | metadata                    |
>>>     | Options      |           | URI    |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>     | AuthZ        | OPTIONS   | AZ URI | metadata                    |
>>>     | Options      |           |        |                             |
>>>     +--------------+-----------+--------+-----------------------------+
>>>  
>> 
>> While this looks good on paper, there are very pragmatic reasons that many APIs have moved away from purely RESTful patterns over the last decade, including limitations on what can be sent with GET and DELETE requests, for example. I don’t think it’s as clean a win as you’re presenting it, but I think it’s worth checking out.
>> 
>> Agreed that RESTful does not work for everything. It does look like it maps well here.
> 
> I disagree that it maps well. I think this is an over-application of a design pattern and the details will be problematic in implementation.
> 
> What aspect does not map well?
> 
> What do you think will be problematic?
> 
> It seems much simpler to route a request based on URI and verb(XAuth), then parse and inspect a JSON payload (XYZ)

See above.

>  
> 
>>  
>> 
>>> 
>>>>  
>>>> 
>>>> The modes in XAuth are much more limiting, as the mixing of different interaction methods is already something that we need to start figuring out. Let’s say, for example, a client can do a redirect, accept a CIBA-style ping, or do a direct app2app communication. There’s a natural preference the client will have here: if it can talk to another app directly, it’ll try that first. If that doesn’t work, it can get a push notification sent, and if all that fails, it can pop open a browser. If I have to pick just one of those modes when I make the request, then the client needs to make three different requests to the AS before I get anything that works. 
>>>> 
>>>> Have you read the revised draft? As I noted above, I have added negotiation. The Client can state all the modes it wants, the GS can respond with the modes it will support, and the Client can offer the User any modes returned from the GS.
>>> 
>>> Yes, did you read what I wrote? I think we’re talking past each other.
>>> 
>>> This is not how XAuth is written currently. The Client can list all of the modes it wants to use. The Server will return all the modes that fit in its policy for the Grant Request. Why would the Client need to make different requests?
>>> 
>>> per
>>> 
>>> https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.4.2 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.4.2>  
>>> 
>>> The interaction object contains one or more interaction mode objects per Section 5
>>> 
>>> Three modes are defined here:
>>> 
>>> https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-5 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-5>
>>> 
>>> More modes may defined in extensions, or in this document.
>> 
>> Yes, this is an improvement, and I’m glad you’re moving your thinking in this direction. However, it’s still not as clear how things combine to solve different use cases, and it conflates the means of getting the user TO the interaction page with the way of getting them BACK from it. It’s these flexible combinations that I think are important, and I don’t think XAuth gets this quite right yet. 
>> 
>> I think how the user gets to and from the server is CRITICAL to the server if it wants to protect itself from a session fixation attack.
>> See above where the client does not know what it can actually do that the server will allow.
> 
> It is critical that the server knows how to protect itself, yes. It’s not critical that the way there and the way back are tightly bound to each other in this way. I think that model is limiting.
> 
> What other way back are you envisioning there could be besides a URI redirect?
> 
> Rolling between mobile apps is a URI redirect. What else could happen?
> 
> I expect there will be new ways of transferring control to a GS, or that the GS will reach out to the user directly.
> 

Push notifications on a mobile platform, COAP-style subscriptions at the HTTP layer, messages coming in over a blockchain fabric through a separate entity…

I think your view of what a client is and how it could communicate and interact is limited, and that’s informing XAuth’s design.

>  
> 
>>  
>> <snip>
>>> 
>>> It is an OR in that if the client is using the type "oauth_scope", they cannot have an "authorization_details" attribute, they can only have "scope"
>>> 
>>> If the client is using the type "oauth_rich", the client MUST include "authorization_details", and MAY include "scope"
>>>  
>>> I have updated the the doc to better capture that:
>>> 
>>> https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.4.4 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.4.4>
>>> 
>>> and example 2 now is of type "oauth_rich"
>>> 
>>> https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.2 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-10#section-3.2>
>>> 
>> 
>> It was not clear to me that both could be sent with that mode, so thank you for updating that. But the client still has to choose one or the other up front. Why not have a mechanism that it can send both at all times? Why have a “mode” type switch at all? XYZ allows clients to make these combined requests with a single consistent syntax.
>> 
>> And by completely externalizing this to OAuth 2, I would argue that we lose an opportunity to more clearly define how resources are described and used, and we inherit the same combination issues that are facing RAR today. We can do better because we get to define the context.
>> 
>> This group can define a new syntax if it wants, and it will be unencumbered by the OAuth 2 and RAR legacy if deployments that want to use the OAuth 2 and RAR syntax can use them directly. Ie, there can be a type "gnap" or some such.
> 
> 
> You did not respond to this response. 
> 

What I’m proposing in XYZ is exactly the new syntax that incorporates both RAR and scope natively by using handles and polymorphic JSON. Other resource request syntaxes could also be defined and added.

> The next section I have put into a separate email.
> 
> /Dick
> 
> ᐧ