Subject: Re: [Txauth] XAuth - a revision of TxAuth

From: Justin Richer <[email-masked]>
Date: Sat, 1 Feb 2020 18:19:18 -0500

> On Jan 31, 2020, at 5:28 PM, Dick Hardt <[email-masked]> wrote:
> 
> On Fri, Jan 31, 2020 at 3:22 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jan 30, 2020, at 11:13 PM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>> On Thu, Jan 30, 2020 at 1:05 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>> On Jan 30, 2020, at 12:25 AM, Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>> On Wed, Jan 29, 2020 at 8:26 AM Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
>>> I think XAuth has an interesting take on the problem space that TxAuth is looking to solve, but in my opinion it generally veers too closely to OAuth2/OIDC/JWT in its solution approach.
>>> 
>>> Reusing aspects of OAuth2/OIDC/JWT that are working fine for deployments will minimize the migration effort for them to take advantage of the security features of this work such as not using the redirect for passing parameters. I think XAuth supports the following clause of the current draft charter: "the group will attempt to simplify porting from OAuth 2.0 and OpenID Connect to the new protocol where possible.”
>> 
>> I understand the goals here, but I disagree that using the constructs as directly as they have been here is the most appropriate approach.
>> 
>> Ok. I think we have reasonable clarity on the disagreement.
>>  
>> 
>>> 
>>> <snip>
>>>  
>>> 1. XAuth removes “handles” as stand-ins for various elements. In XYZ, the “handle” concept is a key abstraction point with specific semantics. A “handle” is an identifier to a specific instantiation of a JSON object structure. Using the “handle” for Keys, for Resources, and even the whole Transaction lets you do a lot of core things in a parallel and reusable way. XAuth re-invents a few of these as separate items, listed below, and I see this as a regression.
>>> 
>>> XAuth took the transaction handle and forked it into a completion handle and a refresh handle so that it is clear what the Client is wanting to happen.
>>> 
>>> It was not clear the value of the other handles that were listed in XYZ. 
>> 
>> I think this may be that you misunderstood the purposes of the handles, as you’ve reinvented nearly all of them with different labels in XAuth. :)
>> 
>> I understand what a handle is, and what it represents. It appears that the handles provide a reference to the display, resource, user, and key objects. XYZ says the AS may issue those, but I could not find determine when the AS sends them back to the RC. I understand the value of the transaction handle XYZ, and built on that in XAuth, but XAuth always sends the display, resource, user and key information by value, not by reference, so your statement 
>> 
>> you’ve reinvented nearly all of them with different labels in XAuth
>> 
>> is confusing.
> 
> I think what you’re missing is that the dynamically generated handles are not the only handles in the system.
> 
> I did not understand that handles could be generated by the AS and hand configured, and had missed the sentence in Section 2 for each object that the RC can present a handle instead.
> 
> The Client ID in most deployments is a handle by this definition. The AS generates it, and the Client presents it in future calls to represent all the Client information.
> 
> My assumption is you did not want to call them identifiers, as you want to use the term handle everywhere, and make dynamic handles and static handles interchangeable. Correct?

I wanted “static” and “dynamic” handles to be the same kind of entity, with the only difference being how they came into existence. What they represent and how they’re used is the same. 

As for the term, I didn’t want to use “identifier” because that was already weighed down with the history of “client ID” and there’s a certain specificity to it that I didn’t like. I also rejected using “artifact”, “ticket”, and “token” for similar baggage, but “handle” seemed to have the right kind of connotation for “this is a small simple thing that represents a big complex thing”. I’m more than happy to bike shed the name of this construct, but I feel strongly on the nature of the element itself.

> 
> It is unclear what value a dynamic display, resource, user, or key handle has for a given transaction, as the information is all represented by your transaction handle. 
> 
> Static handles, and reusing a dynamic handle in a subsequent request allows a developer to pass by reference rather than value, but it is not clear what real benefit that provides over just passing the value. 

These handles are for use across transactions. It’s an optimization for where you want to do it. I designed this as an equivalent to a dynamic client registration, but instead of getting back a single identifier representing the client (the client ID), you get back identifiers (which I called handles as per the above) that represent parts of the presented information.

I split them out because each section of the request could vary independently. One of the things I did when I first started implementing XYZ was to refactor the request into specific sections that were somewhat orthogonal and internally related. What’s in there is what I’d come up with from OAuth 2, OIDC, and UMA:

 - The key that the client uses to identify itself and protect the requests to the AS
 - The things the client needs to display to the user for UX purposes at the AS
 - How the client is able to interact with the user (including any information the AS needs to know in order to get the user back in a secure way)
 - Information the client has about the user
 - Information about the resources the client is requesting

From XAuth I think we can also add:

 - Identity information about the user being requested by the client

All of these can be established separately at different points of a client’s lifecycle. A dynamic client is probably going to want to call the same AS multiple times, possibly even for multiple users. Therefore giving it a way to identify its key and its display information makes sense to me. (I’ll note that I considered collapsing these two into one, but that didn’t feel right for reasons I can’t quite articulate yet — so this is something to debate during the WG). But the things that it asks for (resources and identity), the details of interaction, and the information the client might have about the current user are all things that we already know are going to vary based on the circumstances of the request. 

So why not have all of those be passed by value? Currently in XYZ, interaction is always passed by value because I’m not convinced that it should have a shortcut, but I could be wrong there. The ability to use OAuth2 style scope strings as well as rich objects is something that I think is clearly desired, both in terms of a means of transition from OAuth2 but also in terms of making things easier for developers. The pattern of assigning a human-readable string to a set of API access details is well established. The user handle, and in particular the dynamic user handle issued by the AS, is a porting of UMA2’s “persisted claims token”, which lets the client say “I’m pretty sure this is the same user as before, I’m just making a new request on that same user’s behalf”. The AS can figure out if it needs to interact with the user or not depending on how much it trusts the client and what is being asked for. This is particularly useful for step-up authorizations over time. 

The key handle is a little special in that it can help the AS determine :how: the rest of the fields could vary, or even which fields could vary at all, much in the way a client ID does. I called it a key handle because fundamentally, it represents a way for the AS to reference a public key in lieu of having the key itself passed by value.

> 
> The transaction handle is different as it represents all the context the AS has for the transaction, which the Client does not have access to. All the other handles seem like they are just shorter version, and are more of an identifier.

I agree that the transaction handle is different from the others in some ways, since it represents an ongoing context. However, I realized that it has much of the same properties as the rest of them — in that it’s a string that stands in for a larger object known by the AS, it has a value assigned by the AS, and it’s a value presented by the client. It’s possible that these concepts are further apart from each other than I think they are, so it’s something to consider.

> 
>  
>> What is broken with Client ID? What identifier are you proposing in XYZ?
> 
> I am proposing that the key information takes the place of the client ID for all kinds of clients. As discussed below, the key handle is not a key ID or a key hash — but more on that in a bit. What’s important is that it’s an identifier that the AS can look at and ask itself, “I’ve seen this ID, what authentication method and policy should I use for its requests?” This is the first step in an OAuth 2 AS implementation, where the AS sees the client ID and asks “what authentication method and policy should I use for this request?” This is why I see the key handle — and not a higher level construct like a client handle / client ID — as the component that you would branch your decisions off of at the AS. Once I’ve validated the key, whether by value or by reference, I now know which client I’m talking to. I don’t need a separate client identifier.
> 
> Got it.
> 
> So far the Client ID and the key handle look to me to be the same for Registered Clients. What is the information referenced by a Client ID at the AS, that would NOT be referenced by a key handle?

I’m not sure there’s a clean answer to that question, but here’s how things look:

The redirect URL value (which is now able to vary within rules, as it can in PAR), the specific display information that the client wants to use in the context of this request (which might be locale-specific or context specific), and even the details of a rich request. All of these could be :limited: by either the key handle or client ID. 

>  
> I know that we don’t do it this way in OAuth 2, and I think that’s a limiting decision that we’ve gotten incorrect.
> 
> Use cases that are limited by that decision would help understand why you think it was incorrect. 

It limits us to a model that “all clients have a single identifier, and the identifier is the key to all aspects of a client’s policies. 

Instead, I think we need to think in terms of “what can the presenter of this key do?”, especially if it’s a key we’ve never seen before. This kind of thinking allows us to move beyond a client identifier that the AS already knows into a world where the AS can make a policy decision based on the authentication properties of the request. It’s a shift in mental model that I’m trying to get at here.

>  
> 
> In the mental model of XYZ, the policy is then tied to whatever software that key represents, and since keys aren’t shared between clients, you get the property of a unique identification system as well. For dynamic clients, they don’t have to send an ID at all — they send the key itself by value, since the ID won’t reference anything that the AS knows about.
> So we have an identifier for the clients that want a stable reference, a method for passing values for clients that don’t have a stable reference, and a clear way to upgrade from passing by value to passing by reference for clients that want to do the equivalent of “Dynamic Registration”. There are a number of deployments where DynReg is used :just: to give clients in the field a client ID because OAuth 2 requires a client ID, and there’s a key that’s recognized during the DynReg process. But if the server can recognize my key, I ask: why not just start there when you do the request? You can’t in OAuth 2 because of the redirect-first model and keys don’t even show up there. You can in TxAuth because the model allows the client to talk to the AS directly first, and present its keys. 
> 
> 
> So calling it a key handle lets you call it the same thing for both Registered Clients and Dynamic Clients? The advantage to a Dynamic Client is that it can present a reference instead of its public key again on subsequent calls? Is there another advantage?
> 
> The AS could also compute a fingerprint of the Dynamic Client key and use that as its ephemeral identifier for the Dynamic Client.

If the AS chooses, it could do that, yes. But the AS might decide it doesn’t need any kind of “identifier” for such an ephemeral client. 

>   
> And it’s really important to know that handles do not need to match or be derived from the information that they represent.
> 
> Yes. I understand what a handle is. =)
>  
> 
> No, my proposal is that a public key is what the AS uses to recognize a preregistered client, and that public key can be represented by a handle. I would expect the handle to be stable over time, like a client ID, but more specific. 
> 
> Which public key?  XAuth describes how different instances of a Registered Client can have their own private key, so the matching public key is different for each Client instance. The Client can have a certificate signed by a private key matching the public key registered for the Client at the As. 

So here we start to see where the OAuth2 model of what a “Client” is breaks down: instances of a client vs. a client. There is no “instance of a client” in XYZ, there’s just a client. If it’s got its own key, it’s its own client, even if they’re running the exact same software. 

If you want to tie several pieces of software together, that should be done at a different layer like we did with the “software ID” in DynReg, or by using information associated with the public keys as you mention above. So I think ultimately we have the same kind of model between XYZ and XAuth, but using different terms and underlying imagery. 

>  
> 
> In OAuth 2, the client ID wraps together all of the different aspects of the client and its associated policies. In XYZ, I sought to separate those into different handles because, as we’ve found in OAuth 2, different parts of the client system can vary over time. Our notion of what a “client” is in OAuth 2 is also pretty vague. We have developers all over the place sharing client IDs between different web servers (production and development environments, for example), different instances of software (mobile applications, SPAs, and “public” clients), and different pieces of software altogether (micro-components that are tied together in a single pseudo-app).
> 
> I don't think it is vague. The "client" is not a specific piece of software. From the User or RS's perspective, it is the "service" that was provided the identity claims and/or authorization. They don't want to have to re-authorize as they move between a mobile client, a desktop client, or a web client for the same service.

Are you sure they don’t want to re-authorize? I would be really freaked out if I installed Twitter on my phone and it knew my account information without me telling it.

> 
> What is clearly problematic is sharing the client secret across all of these places. Implementations I have worked on have centralized the client secret in one place, and then handed out the access token to the software component for it to directly call the RS.
> 
> As I discussed above, certificates let a complex Client have each component independently make calls to the AS.

I think those are specific deployment considerations that need to be discussed and considered. 

>   
>  
> And we also have the explosion of Client IDs for apps using DynReg for things like ephemeral instances that get used once and then stop existing. 
> 
> As we have discussed, Client IDs for Dynamic Clients is problematic. The only information an AS has about a Dynamic Client is what it has done with the Client previously. Note that a mobile app can be a Dynamic Client, and have a long lifetime.

Right, and this is where some of the value of the handles comes in. It lets a long-lived dynamic client identify itself and its values in future transactions, without having an explicit, separate “Registration” step. 

In other words, XYZ seeks to collapse the discovery, registration, and authorization-start steps into a single call using a sensible mechanism. 

>  
>> The AS would return interaction responses that are the intersection of:
>> 
>>  - methods the client indicates it can do in the request
>>  - methods the AS knows it can support
>>  - methods allowed by the policy governing the request
>> 
>> I don’t understand the second part of this question, because the AS still “supports the one the client wants to use” in the XYZ model.
>> 
>> I'm looking for a use case where the AS needs to select from a list, rather than use the one mechanism that the Client wants to use. Why the extra negotiation?
> 
> The AS isn’t selecting a single value from the list. It’s responding to what the client wants to use, and it could respond to all of them. If the client wants to use one mechanism, it sends only one mechanism. XYZ enables all of the functions of XAuth’s interaction methods, and then some.
> 
> I understand how it works, and that it is more powerful. It is also more complex. What does practical value does this provide an implementor?

It allows developers of clients to support multiple interaction methods simultaneously and not have to pick a single one before they know what’s possible. It’s the client telling the AS “if you need to talk to the user, these are the ways that I can do it”. If there’s only one way, then the client developer sends only one way. 

It allows AS developers to choose the appropriate interaction method based on the context of the request, including any internal policies governing consent and information release. So from the other thread you have a question about the AS knowing whether it has the consent to release updated claims information to a client, and this lets the client say with each login request “if you need to talk to the user, these are the ways I can do it”. 

And again, having actually implemented both of these types, it’s actually much LESS complicated to do it the way that XYZ does, on both the client and AS side.

>  
> 
>>  
>> 
>> As for a concrete example, look at how we handle the “qrcode” interaction case, based on OAuth 2’s device flow. In this, you want to send a URI to the client that it can render as a QR code as well as a code that the user can type into a page, in case they can’t scan the QR code. OAuth 2 manages this by having a user code as well as a pre-composed URL containing the code to be used for rendering. XYZ used to have a mode for this similar to XAuth, but we realized that we could describe this using two separate flags: 
>> 
>>  - I can communicate a short code that the user can type in at a static URL
>>  - I can get the user to go to an arbitrary URL
>> 
>> The second one is the same mechanism we can use for redirect-based auth. 
>> 
>> I got that. I thought being more crisp in the interaction makes it easier for implementors to understand. 
> 
> I don’t think it’s more crisp, I think it’s more limiting, and it leads to more confusing code paths. Having implemented both styles in XYZ in several languages, I vastly prefer the current XYZ style. 
> 
> It is more crisp. And it is more limiting, and I think it leads to simpler code paths.

Again, I’ve implemented this, and the code paths are simpler for XYZ. I know this because I have written the code paths. The XAuth style is not more crisp, just more limiting. 

> 
>  
> 
> When you have the “type” field, you then have to specify what different responses mean in the context of different types, like what XAuth does in §4.2. In XYZ, the response fields have a single meaning, and the client does what it can with them. I think it’s presumptuous to assume “qrcode” as a scannable format, for instance.
> 
> A QR Code is a scannable format by definition.
>  
> Does the AS actually care how the client communicates the URL to the user? Not really.
> 
> As I noted in XAuth, the AS does care. While a really long URL works fine in a redirect or popup, it does not work in a QR code. The AS can return a short URL for the QR code that redirects to the long URL. The AS does not want to impose the redirect latency on the redirect or popup.

That’s not really true in either the specific or the abstract. QR codes don’t have a lot of trouble scaling for rendering. And if the AS has the capability of having enough information in the short URL to redirect to a URL that it can actually use, wouldn’t it just get the information directly at the short URL without a redirect? Yes you could implement it as a redirect from short to long, but if you’re worried about latency, then don’t do that.

>  
> Even if we were to optimize this for the client and have the AS return an image instead of a URL, I think the AS should be able to return an arbitrary image for the client to display to the user. 
> 
> In XAuth I asked if we wanted to allow the Client to over a webview for the AS to load whatever it wants.

Again, it’s all about getting the user in front of the AS with a web page. I don’t agree that the AS cares much how the user gets there.

> 
> Additionally, since we are designing all of this to be extensible, if another use case comes up with a different interaction method, we can just add a new type.

And in XYZ, if there’s a new interaction method, you add a new flag (or object) to the interaction object to signal that. If the AS supports it, it can give whatever the appropriate response for that is to the client. If the AS doesn’t, it can still pick another type.

I’ll note here that in XYZ, you’ve also got the ability for the client to support a legacy interaction method while a new one rolls out in parallel. With XAuth, you’ve got to make sure that it’s supported at every possible AS the client can talk to before the client makes that switch. 

>  
> 
>> 
>>  
>> 
>>> 
>>> In the case where the AS interacts with an RO that is not the User, there would be nothing the Client would need to do. Perhaps there is a use case for something different? If so, please elaborate.
>>>  
>>> 
>>> 4. XAuth allows OAuth-style scopes next to RAR-style data structures (and next to OIDC claims structures). They are treated as completely separate from each other. In OAuth 2, RAR is defined in the context of scope (and resource and audience and other parameters), and this combination is a matter of some debate still that needs to be solved. However, it’s clear that they’re combined. In XYZ, the only resource request defined is the object inside the resource request. You can mimic “scope” behavior by using a Resource Handle, which again is defined as a single string that stands in for the whole object and could be defined by the AS (or the API it’s protecting). 
>>> 
>>> I think you need to reread the 00 draft. Only one type of authorization request is allowed.
>>> 
>>> - OAuth style for deployments where that works fine.
>>> - RAR style for deployments that need the extra granularity of RAR
>>> - list of RAR style for deployments that support multiple resource servers that require independent access tokens.
>>>  
>>> 
>>> 5. The different kinds of authz requests in (4) create separate tokens.This is very different from both OAuth 2 and XYZ, where you get back a single access token. And in XAuth there is no way to get, for example, two access tokens that are both described by RAR requests, so this seems like a very arbitrary and syntactically-driven separation. 
>>> 
>>> I don't think you understood what is in the draft. See above.
>> 
>> Apologies on these points — I didn’t catch that this had changed from the earlier drafts. 
>> 
>> We can scratch this concern from the list then. Yeah!
> 
> Well, kind of — XAuth doesn’t allow the combination of an API-specified element (a scope, a simple string value) and a more fine grained access request.
> 
> I don't think you went back to reread -00. The oauth-rich type includes a scope, and an authorizations_details. 
> 
> I made that change as it was not clear when I looked at RAR (which is still developing) that it did not include the scope.

I did go back to re-read. It seems that you are re-stating what my stated assumption was: that the RAR does not include scope internally, and that since XAuth makes them exclusive with each other then it’s a choice. What am I missing? 

>  
>> Yes. I think freedom from having to make a choice makes things easier to implement and deploy. 
>> For deployments where another mechanism will be significantly better, the choice is available. ‘
> 
> These statements contradict each other. Are you advocating for “freedom from choice” or that the “choice is available” for this particular feature? I am arguing in favor of making choice available in the case of key presentation and removing choice in terms of request format (as in, the core payload). 
> 
> Freedom from choice: if I don't want to have to make a choice, the choice is made. These are frequently called defaults. They have proven useful. =)
> 
> Stated another way: here is what you do unless you have a good reason to do something else. 
> 
> While I think JOSE is a better default, I'm open to another method being a default. I do strongly think there should be a default.

What I think is more valuable is a mandatory-to-implement, specifically for the AS to support. That tends to make a better “default”, especially for security mechanisms like this. I think :what: the mandatory implement item is can be up for debate.

>  
> 
>> 
>> Is there something about JOSE that you think is problematic to make it the default?
> 
> Yes, it leads to reliance on putting everything of note in the JOSE payload as part of the base protocol.
> 
> In XAuth, I factored out all the JOSE. Once again, have you read -00, or -01?
> 
> https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-3 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-3>
> 
> All payloads are JSON. The JOSE section describes how to use JOSE for message and header signing.
> 
> https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-8 <https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-8>

Yes, I did read; please stop assuming that I haven’t, which you have done several times in your replies on this thread. In fact, I have already thanked you for refactoring, and have stated that I think that’s moving in a good direction.

I answered a specific and direct question specific and directly. You asked what the problem with JOSE as the default was, which is the question that I answered. I did not state that XAuth, as currently written, suffers from these deficiencies, but that they are problematic trends the I have seen in many JOSE-based designs in the past. JOSE isn’t the problem, over-reliance on JOSE as the sole container for information is.

>  
> As explained previously, I want to be able to use HTTP as more than an entity body carrier. We should be using headers and methods and URLs — and importantly, content types.
> 
> I agree. 
> 
> XAuth uses POST, GET and DELETE
> 
> It uses the Authorization header and different parameters to indicate the type of token.
> It uses content type to indicate what the content type is. This will assist an AS that supports multiple Client authentication methods 

Good.

>  
> I think JOSE should be switched with things like Content-Type headers and Accept headers, and that JSON bodies should be the default as they’re more universal across different signing and presentation mechanisms. 
> 
> My Java XYZ implementation does use JOSE, but by using JWS in a detached fashion to sign the body instead of an internal fashion. The reason for this is that it allows the request and response to be “application/json” and not “application/jws”. 
> 
> Detached signatures work, but I have found them to be problematic in practice, which is why I chose "application/jws". There is no canonical form for JSON, so it can get modified, and still be valid JSON, but the signature does not match. Passing around the signature independent of the payload is more complex.
> 
> A JWS can be easily passed between components and is self contained, with no worries that the JSON was modified by parsing and re-serializing it.

I understand and agree with the limitations of detached signatures. This is the key brilliance of JOSE, and what I love most about it. But the internal payload also makes it difficult to impossible to incorporate additional information, such as headers and other bits of context that we might want to protect. 

>  
> 
> In all of these cases, I do not think it is a good idea to use JWT claims in the TxAuth request or response namespaces. Where we use JOSE, we should avoid JWT.
> 
> I agree. JWT is good for claims. Not so good messages.

Great. 

>  
> 
> I still agree that they should be able to easily use TxAuth, which just a stronger argument for the signature/proofing mechanism to be a pluggable thing and that the request/response bodies not be JOSE objects but JSON objects.
> 
> We discussed this in early drafts, and XAuth is JSON, with JOSE added on.

Yes, and this is the right way to layer it. But I also think that the “default" method should use “application/json” specifically, though I could be convinced if there’s a better approach.

>  
>> 
>> The word transaction is muddying what I think you are suggesting here. It more like a conversation. Transactions from a DB point of view are a set of actions that all happen, or none happen.
> 
> I’ve explained previously that the database interpretation is not the only or full interpretation of the word “transaction” here, so I won’t go back into it. Conversation is perhaps more accurate, but “CxAuth” is a problematic acronym. :-D
> 
> Naming is hard. =)
>  
> 
>>  
>> 
>> Both continuation and refresh are saying to the AS “run this transaction again and if I can get a token (or claims or whatever) in its current state, give me that”. However, they can’t really exist at the same time, so having two separate items to ask the same question doesn’t make much sense. 
>> 
>> They have different purposes. The completion (now authorization) handle is to check if the AS is done with its request processing, and if so, provide the results, which includes zero or more identity claims, and zero or more access tokens/handles.
>> 
>> The refresh handle is to refresh a specific access token/handle.
>> 
> 
> I don’t see these as being different, and that’s where we disagree. The access token is the end result of the processing. Refreshing is an act of continuing that processing. I do not see a good argument for treating them separately. 
> 
> Developers are already familiar with refreshing a token

Some are, many get it wrong today. 

For those that are doing it right today, we’re telling them a new way to do what they’re already doing that largely amounts to the same thing they’re doing today: “take this value that I give you alongside the access token and send it back to me with your credentials to get a new access token”. In XYZ that’s the same exact call that they make to continue the transaction, in XAuth it’s a different (but similar) call to a different endpoint.

>  
> 
>>  
>> 
>>> 
>>> I think a transaction handle is to course grained. I don't think that the AS should be returning all the claims in a refresh. And if there are multiple access tokens returned from the AS, then each has their own refresh handle.
>> 
>> I think this requires a deeper discussion, since the whole idea of multiple access tokens is a very different kind of approach here. 
>> 
>> It is a feature of XAuth. 
> 
> Kind of. XAuth allows multiple access tokens in one limited context, and only when using rich authorization requests to do so.
> 
> Given that existing implementations using scopes only support one access token, it did not seem limiting to only have a oauth_rich_list, particularly since a RAR request is a superset of functionality of a scope request.
>  
> I would rather see us have a general mechanism that allows us to get multiple access tokens in a way that’s parallel to how you get one access token.
> 
> A general mechanism sounds fine and dandy. Currently we don't have other ways to request authorization except for oauth scopes and RAR, which is a super set of RAR. If and when we need a more general mechanism, we could define a new type. 

I think instead we should define a syntactical way to say “I want multiple kinds of things and I want them back in different access tokens”. Maybe it’s as simple as a list of resource lists instead of a single list of resources? But I think it’s cleaner to have them be more in parallel with the single token request. 

>  
> 
>> 
>> In OAuth today, the bearer token is like a movie ticket. Whoever has the movie ticket gets in the movie.
>> Using OAuth to obtain a bearer token is like buying a movie ticket.
>> 
>> Sometimes I want to go to more than one movie. OAuth today makes me wait in line to buy each ticket. Why not let me buy multiple tickets at once?
> 
> That’s not true. You can get one ticket that’s good for two movies, to borrow your metaphor. 
> 
> Which is all you can do in OAuth today. Get one ticket.
>  
> 
> The semantics of requesting multiple access tokens in parallel is something the working group might want to consider. I am not a fan of how XAuth handles this, with packing things into the authorization list. I think it’s a concept we should consider though.
> 
> If you have other ideas, please share them!

So here’s a terrible straw man: taking XYZ’s “resources” component as the basis, what I’d like to see is a way for a client to send multiple “resources” requests in parallel, indicating that it wants several access tokens. So let’s say the client sends:

resources: [
   “foo",
   “bar”,
   { “name”: “batman”,
     “knight”: “dark”
   }
]

Then it means “I want one access token that does all these three things”. But if the client sends:

resources: [
   [“foo”],
   [“bar”],
   [{ “name”: “batman”,
     “knight”: “dark”
   }]
]

Then it means “I want three access tokens, one for each of these three things”. 

There’s a lot I hate about this syntax (like the fact that it could be easy to smush the two together and make things really confusing), so please don’t tear down the specifics of the example. But the concept of being able to ask for one or more-than-one of the same kind of thing is what I’m after. We could use two different field names like XAuth does for the different structures, and make them mutually exclusive, but that’s got drawbacks too. 

We could alternatively force the client to pick identifiers for its different access tokens, like:

resources: {
   “footoken”: [“foo”],
   “bartoken": [“bar”],
   “batmanisnotatoken": [{ “name”: “batman”,
     “knight”: “dark”
   }]
}

This means that the client wants three tokens, as above, but that it wants them back with specific names in the output. So you’d get something like:

access_tokens: {
   “footoken”: { value: …, proof: … }
   “bartoken”: { value: …., proof: …. }
   “batmanisnotatoken”: { value …, proof: … }
}

This has the downside of making the client pick values, but the upside of having a clear way to reference which token goes with which part of the request. This might be a complex enough use case that making the client pay the complexity cost might pay off here. 

The output would need to have similar parallels, regardless of how we do it.

> 
> To elaborate on my metaphor.
> 
> A family is going to the movies. The Father (one component of the family), is going to purchase tickets. Billy (age 8) can pick from the G rated movies. Sally (age 15) can pick from G, PG, and PG-13 movies, and Father can pick anything. 
> 
> Father does not want to buy 3 tickets that are identical and can work for any movie. (effectively what an access token is today) He only wants them to go to a movie he has approved, at the time he has selected.
> 
> Father wants to buy 3 different tickets, and give the appropriate ticket to each child.
> 
> The metaphor breaks down here, but each child needs to be able to refresh their ticket independent of the other's, which is why a refresh handle is required. The transaction handle is not granular enough.

I understand what you’re describing, but I question how realistic it is. That would require a very sophisticated client doing a very specific set of optimizations. Is it worth it doing that kind of optimization?

And it actually makes me wonder if your use case is less of a “refresh” and more of an “token exchange” with some kind of augmentation. I don’t have a syntax for that defined in XYZ yet, but it’s in my notes as something we might want to consider. It’s already in charter because OAuth has several mechanisms for access token exchange.

>  
> 
>>  
>> 
>> I see refresh much as it is in OAuth2 and UMA, where it refers to the authorization that was granted. This means that you can do downscoping to get lower-powered access tokens that are a subset of the overall grant, and I think that TxAuth should be able to do a step-up auth where you can build some additional request on top of an existing approval. 
>> 
>> Is "step-up auth" authentication or authorization, ... or both?
> 
> I think the question you asked is unintentionally misleading because “step up” authentication could be seen from the client or the AS’s perspective. 
> 
> Well, your statement was unclear as "auth" can be one or the other! From below, you intended authorization.
>  
> 
> The “step up” that I mean here is from the client’s perspective, not from the AS/IdP’s perspective. The client wants more of something — more access to an API, more user information, etc. It’s likely that the AS is going to want to interact with the user to include whatever additional access the client is asking for, but the client doesn’t want to start from scratch. You’ve got a ticket that’s good to see one movie, and you want to add another movie to it for after. The theater already knows who you are and how to get your money, so they can just add it on.
> 
> It’s entirely feasible that the process of asking for more information would prompt the AS to re-authenticate the user, including prompting them for additional credentials. However, from the client’s view, that’s a side-effect of its request.
> 
> The step-up authentication is a policy decision independent of the Client. The User is having to provide additional authorization.

But the user might have to provide it at the request of the client, because of what the client wants to know about the user (as stated by the AS).

>  
>> Remembering user consent and delivering claims are two completely separate problems and should not be conflated here. I was addressing the former. 
>> 
>> They are related though. If you are not wanting to ask for consent on each delivery, how do you know you have consent?
> 
> We are talking past each other. They’re related in the sense that they’re both a part of the authorization process, but consenting to the release of information and the delivery of that information are completely separate from each other. 
> 
> Consent is required to release the information. That is how they are related. 
>  
> 
> Consent is not the client’s policy, that’s the AS’s policy. My consent is stored on the AS.
> 
> Maybe. Maybe not.

The client can’t know what I consented to, only what it got back from its request. And it’s certainly in no position to know what I’ve consented to if it’s asking me to log in, since it doesn’t know who I am.

>  
> The client can't know if this is the “first” time or not because it doesn’t know who I am yet, so it can’t ask if I should consent again. If the client knows who I am, it doesn’t need to ask the AS to log me in in the first place. 
> 
> Did you spend anytime looking at my "authentication first" proposal in -01?

Yes.

> 
> The Client asks the AS to authenticate the User, and send that result, then the Client can decide what, if anything it wants to request for that User. The AS no longer needs to maintain state.
>  
> 
> However, once I’m interacting with the AS, the AS has a chance of figuring things out. The AS can determine if it’s seen the same client before, if it’s seen the same user before, and if the same client is making the same request for the same user, and the AS knows that it can make that decision without prompting the user. We already do exactly this today with OAuth 2 and OIDC systems. 
> 
> Sometimes. Sometimes not. The specifications are mute on saving state.

I think you might be reading too much into “saving state” as being something like a database write operation. I just mean that the AS needs to know, somehow, that it’s made a decision. There are a lot of ways to pull that off, including wrapping information about the user that the client can present again.

In fact, XYZ’s “user handle” construct is a great way to manage that.

>  
> 
> But the AS does :not: know which profile and identity claims the client actually :needs:. The only party able to make that decision is the client, and it can only make that decision once it has a reference to which user is there (in terms of an identifier). The AS can (and I argue should) give the client some kind of key for helping make that decision. 
> 
> The push of user information into an OAuth-protected API, and separating it from the authentication context, is one of the best parts of OpenID Connect. Yes, the client can always request the user info as long as it has the access token — and to me that’s a feature, because the client is the component that knows when it needs updated info. 
> 
> This is where consent and delivery are related. If the user info has been updated, has the User provided consent for the Client to receive it? The AS is the endpoint that can interact with the user, not the UserInfo endpoint.
> 
> Why not just go back to the AS and ask for the data again. If consent is not required, the AS returns the data. If consent is required, the AS can interact with the User to get it.
> 
> The UserInfo endpoint seems redundant if the Client can get the claims from the AS.

If the client is just going to go back to the AS with a separate call to get profile information, why conflate it with the transaction request, especially when doing so can lead to the privacy issues that I’ve outlined? I’m not convinced the optimization is worth the risk, much in the way that the implicit flow was an optimization that’s turned out to be not worth the risk.

> 
>  
> 
>>  
>> 
>>> 
>>> Your comments have inspired me on a solution that can be done with XAuth (or XYZ) that can't be done with OAuth 2.0/OIDC.
>>> 
>>> I'll add that to the XAuth draft and publish it. 
>>>  
>>> 
>>> 11. XAuth defines an explicit discovery step because the client now needs to know several things about the server. The mix-up attack and a few other attacks in OAuth 2 stem from this kind of process. In XYZ, the client really only needs to know the transaction endpoint URL and it learns everything else from that point. Yes, the client needs to discover that someplace — but it was a deliberate decision in limiting the amount of upfront information that the client needs to get started.
>>> 
>>> That is still discovery, is it not?
>> 
>> I literally just called it that in the sentence above, so yes. :) What you’re discovering is different though. And doesn’t the client still need to “discover” the discovery endpoint in XAuth?
>> 
>> What discovery endpoint?  
> 
> The charter currently includes “AS discovery”, per your request to add it. To me, and I would argue to most, “discovery” is a programmatic process. If it’s manual, it’s not really the client “discovering” anything, it’s being told things manually by a developer. That’s not discovery as the term is generally known, and I think this is a key source of confusion here. There is no “discovery” that’s not programmatic — that’s configuration.
> 
> I think of discovery is going to the AS and learning what it can do -- since discovery is learning. That can be the developer going to the AS docs and reading, or the Client calling a discovery API. 
> 
> After manual discovery, the developer decides how to manually configure the Client, based on what was discovered when reading the documentation.
> 
> I have found it useful to call out the manual discovery so that implementors know where the information comes from. IE it is not in the specification.
> 

I would recommend not using the term “discovery” to refer to this, as I believe “discovery” is well-known* to be a programmatic process.

*Pun fully intended. :)

 — Justin
> ᐧ

---

From: Dick Hardt <[email-masked]>
Date: Fri, 7 Feb 2020 19:48:43 -0800

I have updated XAuth to -02 based on your comments, and some new insights.
=)

Only a few questions left below ... =)

>
> So far the Client ID and the key handle look to me to be the same for
> Registered Clients. What is the information referenced by a Client ID at
> the AS, that would NOT be referenced by a key handle?
>
>
> The redirect URL value (which is now able to vary within rules, as it can
> in PAR),
>

In XAuth, the redirect URL is passed by value. It is no longer needed to
identify the Client. There may be security issues related to the Client
being able to specify its redirect URL, but none come to mind.

> the specific display information that the client wants to use in the
> context of this request (which might be locale-specific or context
> specific),
>

If it is a Registered Client, the AS will often want to ensure the
information presented to the User is correct, particularly if the
transaction is sensitive.

> and even the details of a rich request. All of these could be :limited: by
> either the key handle or client ID.
>
>
>
>> I know that we don’t do it this way in OAuth 2, and I think that’s a
>> limiting decision that we’ve gotten incorrect.
>>
>
> It limits us to a model that “all clients have a single identifier, and
> the identifier is the key to all aspects of a client’s policies.
>

Each Registered Client has a single identifier. That let's the GS have
policies for that Client, and the information displayed to the User about
the Client.

>
> Instead, I think we need to think in terms of “what can the presenter of
> this key do?”, especially if it’s a key we’ve never seen before. This kind
> of thinking allows us to move beyond a client identifier that the AS
> already knows into a world where the AS can make a policy decision based on
> the authentication properties of the request. It’s a shift in mental model
> that I’m trying to get at here.
>

I can see this for Dynamic Clients, but it seems problematic for a
Registered Client.

>
>
>
>>
>> In the mental model of XYZ, the policy is then tied to whatever software
>> that key represents, and since keys aren’t shared between clients, you get
>> the property of a unique identification system as well. For dynamic
>> clients, they don’t have to send an ID at all — they send the key itself by
>> value, since the ID won’t reference anything that the AS knows about.
>>
> So we have an identifier for the clients that want a stable reference, a
>> method for passing values for clients that don’t have a stable reference,
>> and a clear way to upgrade from passing by value to passing by reference
>> for clients that want to do the equivalent of “Dynamic Registration”. There
>> are a number of deployments where DynReg is used :just: to give clients in
>> the field a client ID because OAuth 2 requires a client ID, and there’s a
>> key that’s recognized during the DynReg process. But if the server can
>> recognize my key, I ask: why not just start there when you do the request?
>> You can’t in OAuth 2 because of the redirect-first model and keys don’t
>> even show up there. You can in TxAuth because the model allows the client
>> to talk to the AS directly first, and present its keys.
>>
>
>
> So calling it a key handle lets you call it the same thing for both
> Registered Clients and Dynamic Clients? The advantage to a Dynamic Client
> is that it can present a reference instead of its public key again on
> subsequent calls? Is there another advantage?
>
> The AS could also compute a fingerprint of the Dynamic Client key and use
> that as its ephemeral identifier for the Dynamic Client.
>
>
> If the AS chooses, it could do that, yes. But the AS might decide it
> doesn’t need any kind of “identifier” for such an ephemeral client.
>

It will want to know it is the same Client on subsequent requests won't it?

>
>
>
>> And it’s really important to know that handles do not need to match or be
>> derived from the information that they represent.
>>
>
>> No, my proposal is that a public key is what the AS uses to recognize a
>> preregistered client, and that public key can be represented by a handle. I
>> would expect the handle to be stable over time, like a client ID, but more
>> specific.
>>
>
> Which public key?  XAuth describes how different instances of a Registered
> Client can have their own private key, so the matching public key is
> different for each Client instance. The Client can have a certificate
> signed by a private key matching the public key registered for the Client
> at the As.
>
>
> So here we start to see where the OAuth2 model of what a “Client” is
> breaks down: instances of a client vs. a client. There is no “instance of a
> client” in XYZ, there’s just a client. If it’s got its own key, it’s its
> own client, even if they’re running the exact same software.
>

I'm confused. The GS will want to have policies that apply to all instances
of a Client.

>
> If you want to tie several pieces of software together, that should be
> done at a different layer like we did with the “software ID” in DynReg, or
> by using information associated with the public keys as you mention above.
> So I think ultimately we have the same kind of model between XYZ and XAuth,
> but using different terms and underlying imagery.
>

In XYZ the handle represents the instance and the transaction. It is not
clear what advantage there is for separating the instance from the
transaction for Registered Clients.

>
>
>
>>
>> In OAuth 2, the client ID wraps together all of the different aspects of
>> the client and its associated policies. In XYZ, I sought to separate those
>> into different handles because, as we’ve found in OAuth 2, different parts
>> of the client system can vary over time. Our notion of what a “client” is
>> in OAuth 2 is also pretty vague. We have developers all over the place
>> sharing client IDs between different web servers (production and
>> development environments, for example), different instances of software
>> (mobile applications, SPAs, and “public” clients), and different pieces of
>> software altogether (micro-components that are tied together in a single
>> pseudo-app).
>>
>
> I don't think it is vague. The "client" is not a specific piece of
> software. From the User or RS's perspective, it is the "service" that was
> provided the identity claims and/or authorization. They don't want to have
> to re-authorize as they move between a mobile client, a desktop client, or
> a web client for the same service.
>
>
> Are you sure they don’t want to re-authorize? I would be really freaked
> out if I installed Twitter on my phone and it knew my account information
> without me telling it.
>

Your example is confusing authentication with authorization.

If I install the the LinkedIn App on my phone, I would like it to be able
to post to Twitter just as the LinkedIn web site is able to post to Twitter
from a previous authorization.

>> I don’t think it’s more crisp, I think it’s more limiting, and it leads
>> to more confusing code paths. Having implemented both styles in XYZ in
>> several languages, I vastly prefer the current XYZ style.
>>
>
> Again, I’ve implemented this, and the code paths are simpler for XYZ. I
> know this because I have written the code paths. The XAuth style is not
> more crisp, just more limiting.
>

We disagree on this.

>
>
>
>
>>
>> When you have the “type” field, you then have to specify what different
>> responses mean in the context of different types, like what XAuth does in
>> §4.2. In XYZ, the response fields have a single meaning, and the client
>> does what it can with them. I think it’s presumptuous to assume “qrcode” as
>> a scannable format, for instance.
>>
>
> As I noted in XAuth, the AS does care. While a really long URL works fine
> in a redirect or popup, it does not work in a QR code. The AS can return a
> short URL for the QR code that redirects to the long URL. The AS does not
> want to impose the redirect latency on the redirect or popup.
>
>
> That’s not really true in either the specific or the abstract. QR codes
> don’t have a lot of trouble scaling for rendering.
>

Yes they do. Speaking from building an app that used them.

> And if the AS has the capability of having enough information in the short
> URL to redirect to a URL that it can actually use, wouldn’t it just get the
> information directly at the short URL without a redirect?
>

The AS has existing code that uses a really long URL. Why make them change?

> Yes you could implement it as a redirect from short to long, but if you’re
> worried about latency, then don’t do that.
>

Latency for non-QR code use cases.

I think there are lots of reasons why the AS wants to know how the User
interaction will be transferred. Being explicit allows both the Client and
the AS know exactly what will happen.

>
>
>> Even if we were to optimize this for the client and have the AS return an
>> image instead of a URL, I think the AS should be able to return an
>> arbitrary image for the client to display to the user.
>>
>
> Again, it’s all about getting the user in front of the AS with a web page.
> I don’t agree that the AS cares much how the user gets there.
>

It might not be a web page. The AS may be an app on the User's phone.

>
>
> Additionally, since we are designing all of this to be extensible, if
> another use case comes up with a different interaction method, we can just
> add a new type.
>
>
> And in XYZ, if there’s a new interaction method, you add a new flag (or
> object) to the interaction object to signal that. If the AS supports it, it
> can give whatever the appropriate response for that is to the client. If
> the AS doesn’t, it can still pick another type.
>
> I’ll note here that in XYZ, you’ve also got the ability for the client to
> support a legacy interaction method while a new one rolls out in parallel.
> With XAuth, you’ve got to make sure that it’s supported at every possible
> AS the client can talk to before the client makes that switch.
>

The Client can query the AS.

The vast majority of Clients have the AS preconfigured, so they know if the
AS supports it or not.

>
>> Well, kind of — XAuth doesn’t allow the combination of an API-specified
>> element (a scope, a simple string value) and a more fine grained access
>> request.
>>
>
> I made that change as it was not clear when I looked at RAR (which is
> still developing) that it did not include the scope.
>
>
> I did go back to re-read. It seems that you are re-stating what my stated
> assumption was: that the RAR does not include scope internally, and that
> since XAuth makes them exclusive with each other then it’s a choice. What
> am I missing?
>

XAuth does not make them exclusive to each other.

type "oauth_scope" has a "scope" attribute

type "oauth_rar" has a "scope" attribute and a "authorization_details"
object

> https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-3
>
> https://tools.ietf.org/html/draft-hardt-xauth-protocol-00#section-8
>
>
> Yes, I did read; please stop assuming that I haven’t, which you have done
> several times in your replies on this thread. In fact, I have already
> thanked you for refactoring, and have stated that I think that’s moving in
> a good direction.
>
> I answered a specific and direct question specific and directly. You asked
> what the problem with JOSE as the default was, which is the question that I
> answered. I did not state that XAuth, as currently written, suffers from
> these deficiencies, but that they are problematic trends the I have seen in
> many JOSE-based designs in the past. JOSE isn’t the problem, over-reliance
> on JOSE as the sole container for information is.
>

I was not precise in my question, so the answer did not match, which is why
I was confused. I see we are aligned on JSON for the protocol, and JOSE
being an option for Client Authentication.

To clarify my question:

"Is there something about JOSE that you think is problematic to make it the
default *mechanism*?"

> Detached signatures work, but I have found them to be problematic in
> practice, which is why I chose "application/jws". There is no canonical
> form for JSON, so it can get modified, and still be valid JSON, but the
> signature does not match. Passing around the signature independent of the
> payload is more complex.
>
> A JWS can be easily passed between components and is self contained, with
> no worries that the JSON was modified by parsing and re-serializing it.
>
>
> I understand and agree with the limitations of detached signatures. This
> is the key brilliance of JOSE, and what I love most about it. But the
> internal payload also makes it difficult to impossible to incorporate
> additional information, such as headers and other bits of context that we
> might want to protect.
>

The message body can wrap the message so that context can be included, but
separated. See what I'm proposing for "jose+body"

In XAuth / TxAuth, the message itself can have all the context needed --
and should.

>
>
>
>>
>> In all of these cases, I do not think it is a good idea to use JWT claims
>> in the TxAuth request or response namespaces. Where we use JOSE, we should
>> avoid JWT.
>>
>
>> I still agree that they should be able to easily use TxAuth, which just a
>> stronger argument for the signature/proofing mechanism to be a pluggable
>> thing and that the request/response bodies not be JOSE objects but JSON
>> objects.
>>
>
> Yes, and this is the right way to layer it. But I also think that the
> “default" method should use “application/json” specifically, though I could
> be convinced if there’s a better approach.
>

Let's compare and contrast the approaches. I'm open to not having the
default being JOSE if another approach is generally better at meeting most
implementor needs.

>
>
>
>> I would rather see us have a general mechanism that allows us to get
>> multiple access tokens in a way that’s parallel to how you get one access
>> token.
>>
>
> A general mechanism sounds fine and dandy. Currently we don't have other
> ways to request authorization except for oauth scopes and RAR, which is a
> super set of RAR. If and when we need a more general mechanism, we could
> define a new type.
>
>
> I think instead we should define a syntactical way to say “I want multiple
> kinds of things and I want them back in different access tokens”. Maybe
> it’s as simple as a list of resource lists instead of a single list of
> resources? But I think it’s cleaner to have them be more in parallel with
> the single token request.
>

Good point. I made that adjustment in -02 of XAuth.

>> Sometimes I want to go to more than one movie. OAuth today makes me wait
>> in line to buy each ticket. Why not let me buy multiple tickets at once?
>>
>>
>> The semantics of requesting multiple access tokens in parallel is
>> something the working group might want to consider. I am not a fan of how
>> XAuth handles this, with packing things into the authorization list. I
>> think it’s a concept we should consider though.
>>
>
> So here’s a terrible straw man: taking XYZ’s “resources” component as the
> basis, what I’d like to see is a way for a client to send multiple
> “resources” requests in parallel, indicating that it wants several access
> tokens. So let’s say the client sends:
>
> resources: [
>    “foo",
>    “bar”,
>    { “name”: “batman”,
>      “knight”: “dark”
>    }
> ]
>
> There’s a lot I hate about this syntax (like the fact that it could be
> easy to smush the two together and make things really confusing), so please
> don’t tear down the specifics of the example. But the concept of being able
> to ask for one or more-than-one of the same kind of thing is what I’m
> after. We could use two different field names like XAuth does for the
> different structures, and make them mutually exclusive, but that’s got
> drawbacks too.
>
> This means that the client wants three tokens, as above, but that it wants
> them back with specific names in the output. So you’d get something like:
>
> access_tokens: {

> This has the downside of making the client pick values, but the upside of
> having a clear way to reference which token goes with which part of the
> request. This might be a complex enough use case that making the client pay
> the complexity cost might pay off here.
>

I pondered the list vs the dictionary as well. I have list in -02, but
personally would prefer the dictionary as it is clear what is being handed
back.

> The output would need to have similar parallels, regardless of how we do
x

> Agreed

> A family is going to the movies. The Father (one component of the family),
> is going to purchase tickets. Billy (age 8) can pick from the G rated
> movies. Sally (age 15) can pick from G, PG, and PG-13 movies, and Father
> can pick anything.
>
> Father does not want to buy 3 tickets that are identical and can work for
> any movie. (effectively what an access token is today) He only wants them
> to go to a movie he has approved, at the time he has selected.
>
> The metaphor breaks down here, but each child needs to be able to refresh
> their ticket independent of the other's, which is why a refresh handle is
> required. The transaction handle is not granular enough.
>
>
> I understand what you’re describing, but I question how realistic it is.
> That would require a very sophisticated client doing a very specific set of
> optimizations. Is it worth it doing that kind of optimization?
>

To clarify, I am describing that the Client can acquire more than one
access token at a time. I mention refresh, as each access token would get
refreshed independently, hence a refresh mechanism independent from the
TxAuth transaction handle.

I have heard of numerous people wanting multiple access tokens. There are
different parts of the Client that do different things, so you want each of
those to get the access token it needs. The other angle is that different
resources need different access tokens, because they were built
independently, but the Client needs to access both resources, so needs an
access token for each.

>
> And it actually makes me wonder if your use case is less of a “refresh”
> and more of an “token exchange” with some kind of augmentation. I don’t
> have a syntax for that defined in XYZ yet, but it’s in my notes as
> something we might want to consider. It’s already in charter because OAuth
> has several mechanisms for access token exchange.
>

I'm confused as to how this is a refresh or token exchange example.

> The client can’t know what I consented to, only what it got back from its
> request. And it’s certainly in no position to know what I’ve consented to
> if it’s asking me to log in, since it doesn’t know who I am.
>

To clarify -- maybe my consent is stored at the AS. Maybe it is not.

>
>
>
>> The client can't know if this is the “first” time or not because it
>> doesn’t know who I am yet, so it can’t ask if I should consent again. If
>> the client knows who I am, it doesn’t need to ask the AS to log me in in
>> the first place.
>>
>
> The Client asks the AS to authenticate the User, and send that result,
> then the Client can decide what, if anything it wants to request for that
> User. The AS no longer needs to maintain state.
>
>
>>
>> However, once I’m interacting with the AS, the AS has a chance of
>> figuring things out. The AS can determine if it’s seen the same client
>> before, if it’s seen the same user before, and if the same client is making
>> the same request for the same user, and the AS knows that it can make that
>> decision without prompting the user. We already do exactly this today with
>> OAuth 2 and OIDC systems.
>>
>
> I think you might be reading too much into “saving state” as being
> something like a database write operation. I just mean that the AS needs to
> know, somehow, that it’s made a decision. There are a lot of ways to pull
> that off, including wrapping information about the user that the client can
> present again.
>

Which instance of the Client? Client state (at the full service level)
needs to be centrally stored as there may be multiple implementations of
the Client.

> Why not just go back to the AS and ask for the data again. If consent is
> not required, the AS returns the data. If consent is required, the AS can
> interact with the User to get it.
>
> If the client is just going to go back to the AS with a separate call to
> get profile information, why conflate it with the transaction request,
> especially when doing so can lead to the privacy issues that I’ve outlined?
>

Which privacy issues?

> I’m not convinced the optimization is worth the risk, much in the way that
> the implicit flow was an optimization that’s turned out to be not worth the
> risk.
>

I'm not following your implication.

>
> I think of discovery is going to the AS and learning what it can do --
> since discovery is learning. That can be the developer going to the AS docs
> and reading, or the Client calling a discovery API.
>
> After manual discovery, the developer decides how to manually configure
> the Client, based on what was discovered when reading the documentation.
>
> I have found it useful to call out the manual discovery so that
> implementors know where the information comes from. IE it is not in the
> specification.
>
>
> I would recommend not using the term “discovery” to refer to this, as I
> believe “discovery” is well-known* to be a programmatic process.
>

Changed in -02.

> *Pun fully intended. :)

I got it. =)