Subject: [OAUTH-WG] Use cases for XYZ

From: Justin Richer <[email-masked]>
Date: Mon, 19 Aug 2019 20:03:49 +0000

As promised in Montreal, I have started to pull together use cases that fit XYZ’s model better than they fit traditional OAuth. While I’ve been able to work out how XYZ works for the most common OAuth deployments and extensions, I think the real interest is in the new spaces where OAuth doesn’t work out as well. The list here is far from comprehensive, of course, and I’d like to keep building this out. I plan on putting things into a more formal structure and getting them onto the https://oauth.xyz/ website in the near future alongside any others that I gather.

Ephemeral Clients. The OAuth model puts the notion of a “client” application front and center, and this makes sense from OAuth’s roots as a way to connect two web servers together. We’ve seen that this breaks down in different ways when we have SPA’s, mobile app instances, etc. Dynamic Registration helps, but with truly ephemeral clients you end up with having a lot of orphaned applications registered into the AS. In the last few years, OAuth has been trending away from pre-registration of all trust material into enabling more runtime keys and secrets. Extensions like PKCE, DPoP, OAuth-MTLS, and Token Binding are all based on this notion. In XYZ, the “transaction” is the core component of the model, and everything hangs off from that. As such, a client application that identifies itself to a new AS, gets a token, then disappears with its tokens is a reasonable model that leaves no trace behind.

Distributed RS’s. In highly distributed spaces with common APIs, such as a distributed social network, the RS’s all need to recognize not only the token but also who the token represents. OAuth has some pieces that let you tie something like this together, such as a JWT with key discovery based on the issuer of the token, but this doesn’t lend itself to use with ephemeral clients and bound tokens where the RS would need a way to figure out how to get to the keys. This kind of thinking extends to APIs deployed as micro services behind gateways, or lambda functions on an elastic cloud. What serves an “API” endpoint isn’t what it used to be, and I think we’ve got a better starting place with XYZ to make the lives of RS developers easier by having clearer mechanisms to bind tokens to both the rights they represent and the presentation mechanisms they need.

Bound Access Tokens. Everything is bearer tokens in OAuth2. Yes, we’re getting better about this with DPoP and OAuth-MTLS, and I support this work extending OAuth 2. But that’s far from complete or widely used. And what’s really weird, when you look at these, is that we’re not even using some of the half-baked extension points that we :do: have in OAuth 2, such as token types. We really shouldn’t be calling things “Bearer” tokens anymore when they require you to do other things on top of presenting the token, like using MTLS with a specific cert. Plus we’ve got a lot of conflation between people who want to pack keys into the tokens themselves vs. having the keys referenced by the token, which leads to confusion around what things like RFC7800 actually provide and define. XYZ gives us an opportunity to have a much clearer model for what an access token is, and how it gets bound to a key and presentation mechanism of various types. Bearer tokens still work here, too, but they become one among many citizens, like we always intended OAuth2 to have.

Multiple Parties. OAuth assumes that the Resource Owner is the person operating the client application. UMA extends this to allowing the Requesting Party to be the one using the client, but it generally doesn’t collapse cleanly into the cases where the RO :is: the party using the client since the claims gathering endpoint and the authorization endpoint aren’t quite the same in concept. UMA’s also arguably pretty complex, but I think it :had: to be in order to fit into the OAuth2 world. And then we have extensions in the identity space like CIBA which have multiple channels of interaction with potentially multiple users. We’ve also got the Device Flow which allows multiple channels connected by a real-world artifact (the user code), and I know of at least one deployment where the interactive page where the code is entered is under the control of someone other than the resource owner, since it’s a transitive trust model at play. This is an off-label use, which XYZ can make much more explicitly built-in. By separating the notion of the nature of the software from the nature of the user’s interaction, we can address a wider array of multi-party configurations without OAuth’s same core assumptions. Nat’s already talked about this kind of thing here on the list, and I think flexibility around who does what is going to be a key difference.

Known User. When the client knows something about the user, it should be able to express that to the AS as part of the transaction request. OAuth doesn’t have any place for this to happen, since most interactive flows start from the front channel. The one core flow that does allow this is the resource-owner password grant, which of course exposes the client software to a user’s memorized shared secret (their password). It can’t be used with any kind of challenge-response or assertion-based system. We don’t have any way to pass assertions or claims about the user, unless we wanted to use the token exchange grant — and I would argue that this is abusing the definition of “token” in this space and getting us into WS-* territory. One stop gap that I know of in the wild is to use token exchange to present a user-token to the AS, and then branch behavior: if the exchange works, use the resulting token. If the exchange fails (due to the user needing to interact or the trust not being high enough for the request), then you bail out of the exchange grant and into one of the interactive grants instead to get the user to the front channel. Since you start in the back channel in XYZ, the client can send along any information that it has about the user right from the start, and the AS can determine what else it needs to do. This could include interacting with the user directly, or even building up a challenge-response for a user’s credential to be presented via the client and returned through a transaction continue message. On top of this, since we’re doing JSON in the back channel, we’ve got a lot more expressiveness for the data we’re sending back and forth beyond form-encoded strings.

Non-authorization Interaction. This is one that Annabelle brought up in Montreal, and I’ll admit that it’s a bit further out than the others because it’s not even an authorization case. In this, an application tries to do something at an API but finds out that the user needs to interact with the service. This might be to consent, like in OAuth, but it also might be to enter an updated credit card. Basically, a backend system needs to say “Oh I thought things were fine but I need to talk to someone with a webpage right now”, much like the token-exchange-failure model in the last paragraph. This fits XYZ’s model of pinging the AS to try and do something, but having the AS optionally come back and say “hey get the user to this webpage, I need to talk to them”, with the main difference that it’s not inside a transaction request, per se. I think there’s something interesting happening here though that we should consider.

Key Distribution. This is another one that lands us outside of what OAuth is used for, but not that far from its intent. If we have bound access tokens, that means the tokens themselves are bound to keys. Well, those keys could also be used in other non-access-token-based presentation mechanisms and protocols. Maybe the client needs to sign an assertion about itself, or a document, or a SET for audit purposes. In all of these cases, I think it can be argued that the access token represents here what the key can be used for, which might be in addition to its presentation at an API itself. I’ve been involved with plenty of systems that boil down to a key exchange or distribution problem, and when the trust is user-driven, it’s not that different from what we’re doing with tokens in XYZ.

Structured Resources. Or in other words, “structured scopes” like Torsten is proposing. Again, I support this work for extending OAuth, but it’s got a lot of hurdles to overcome. For one, encoding the structures as form parameters is awkward, at best. Second, the combination of “plain” scopes with structured scopes would need to be carefully defined, since a “plain” scope can represent so many different aspects of the request. And finally, what goes into the structure is going to be a big issue of possible contention since not only are all APIs very different, so far APIs have used “scope” in very different ways. With XYZ, resource requests have a much more well-defined setup: they exist as objects describing the request, they’re combined with “AND” semantics, and they can be represented by strings that decode explicitly to the representational objects.

I’d like to hear from others about what other use cases you’ve run into at the edges of OAuth (or related space) that don’t quite fit.

I have reached out to the chairs and the AD to help determine next steps for XYZ within the IETF. I hope to be able to attend the Singapore meeting and continue the conversation in person there as well.

— Justin