From many conversations that I've had with people over the past few years, it's been clear to me that there's a significant amount of confusion about the state of interoperability in OAuth. All notions of profiles and deployments aside, I believe that many people have different ideas about *what* exactly is meant to be interoperable within OAuth, and these expectations lead to premature declarations of OAuth being non-interoperable. The truth is that there are a lot of moving parts in OAuth and different parts of the protocol family deal with interoperability between different pieces. I'm going to attempt, here, to lay out what I see as the fundamental interop concerns that each component deals with, and hopefully this can help drive the conversation forward in a constructive manner:

RFC6749: client <-> AS

The core spec deals with interop between the client and the authorization server, in four different flows that tell the client what it needs to do to get a token. (Five if you count refresh tokens.) The resource owner/user agent are used as mechanisms to facilitate the interaction between these parts, but they are by and large passive carriers of the information being passed along the front channel. It's important to realize that RFC6749 doesn't say anything about interoperating with the protected resource. It's also important to realize that RFC6749 doesn't say anything about interop between the resource owner/user agent and the client, or between the resource owner/user agent and the AS. The core is, by design, silent on these matters.


RFC6750: client <-> PR

The bearer token spec deals with interop between the client and the protected resource by defining one kind of token and telling the client how to use it at the PR. In defining the token type, it does define what would is returned from the AS. This, however, I think is an unfortunate artifact of the core not defining an abstract object structure representing the token, and instead defining only the JSON serialization coming from the token endpoint's output (which is then serialized in parameters in the implicit flow, and maybe we can fix this all in OAuth 2.1, but I digress). However, the core of this spec is to tell the client what to do once it gets a token. Ultimately, RFC6750 doesn't care how you get a bearer token, and we've seen many instances of issuance of bearer tokens that don't use any RFC6749 constructs. But once you get that token, and it is a bearer token, then a client can use RFC6750 to hand that to a protected resource. RFC6750 is also silent about what the protected resource does to figure out what the token's good for, or if it's any good at all.


JWT, Introspection: PR <-> AS

Since everything to this point has been completely hand-wavy about how the heck a PR and an AS can agree on what to do with a token, these two specs (and their associated ecosystems) solve it in different ways. Of course, the most common approach, and the one assumed in OAuth 1.0, was that the AS and PR were actually the same thing. But since we can theoretically split these two in OAuth 2.0, we need some means to get them talking. JWTs pack information into the token itself, building directly on top of RFC6750's bearer token (for the most part), and use JOSE to provide different flavors of protection and assurance. A common pattern with JWT that I've seen is to have something that can facilitate service discovery in the "iss" field (like a URL), and then asymmetrically sign it with the AS's key so that the PR can check the signature. Then everything in the token can be used to figure out important things like who the token's for and what it should be used for. Introspection uses a web-API approach to solving the same problem, where the PR makes an HTTP GET and passes the token along back to the AS to get this information. Both have their benefits and drawbacks and can even be used together (ie: parse the JWT to find the issuer, then call introspection on that issuer).



Then you have things like Revocation which deal with token-holder <-> AS, where token-holder can be either the client or the PR depending on what's trying to be accomplished. Registration deals with client <-> AS, resource provisioning deals with PR <-> AS, and of course there's UMA which connects everybody to everybody else by using most of these components in a single, comprehensive application of awesomeness.



Where have we gone awry on this? For starters, current revision of the signed token spec attempts to solve both client <-> PR and PR <-> AS interoperability simultaneously, and I think that's a mistake. There are also those who assume client <-> AS and client <-> PR interoperability as indivisible from each other, which is also a mistake. And then there are those that see that one spec or another doesn't specify interop between all points on its own, so they conclude OAuth is fundamentally non-interoperable. This is a grave mistake but it's a very real problem of perception that OAuth has in the real world.

I think that as we go forward with OAuth interop testing and continued profiling, we need to keep in mind *what* is interoperating with *what* for each piece that we care about.

 -- Justin
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to