My inbox ran hot today with both IBM employees and external contacts asking me for my opinion on a rather scathing article about OAuth 2.0 from former editor Eran Hammer-Lahav.
First my disclaimers. I am an architect and senior developer for a product in IBM (Tivoli Federated Identity Manager – aka TFIM) which implements OAuth (both 1.0 and 2.0). IBM sell’s this product and my opinions are therefore not completely unbiased but I do believe in the comments I make in this post. I also contributed some of the content to the OAuth 2.0 threat model so have spent some time on understanding OAuth 2.0 security considerations. These comments are my own and may not necessarily reflect IBM’s long term position so take them as just another input for your consideration.
I also have great respect for the work Eran put into OAuth over the past several years on both 1.0 and 2.0 and he should be recognized for that.
I don’t think OAuth 2.0 is as doom and gloom as portrayed in Eran’s comments, and I think it is unfair to compare the complexity of using OAuth (1.0 or 2.0) to WS-* as a security mechanism for Web API’s. Those technologies are light years apart in terms of complexity, ability to implement, interoperability and market acceptance. I’ve worked on and have implemented both so am reasonably well qualified to express an opinion.
I think OAuth 2.0 is very useful and some of the things criticised in the article I would argue could be considered features. Maybe that’s my “enterprise” perspective.
It is true that OAuth 2.0 on it’s own is not really a protocol which provides a prescriptive definition of interoperability boundaries however I contest this is not as big a deal as Eran makes out. In my opinion the incredibly simplified client development model in OAuth 2.0 obviates the need for strict interoperability contracts between OAuth 2.0 clients and servers. The popularity of the Facebook graph API is a working example of this. The reason I believe Facebook haven’t moved from draft 12 of the spec is that there is no need to. Eran argues that “an updated 2.0 client written to work with Facebook’s implementation is unlikely to be useful with any other provider and vice-versa”. I would argue that there is actually very little need to implement a client library at all for OAuth 2.0. That is one reason why TFIM doesn’t ship one. Other emerging protocols such as OpenID Connect are more prescriptive in their use of OAuth 2.0 as they introduce interfaces which do require interoperability of web API’s between partners which are protected with OAuth 2.0 tokens.
A good example of something Eran criticises which I view as a feature is bearer tokens and the fact that a client does not have to present [a signature derived from] the client’s own credentials along with an access token when accessing a protected resource. Sure – there is an absolute need to protect bearer tokens at rest and in transit, just like there is with a password, key, or any other form of credential maintained by a client or end-user today. Every user of a website requiring authentication and every business API needs this – we need to accept that and get used to it. I understand the argument about the use of signatures not exposing the actual credentials on the wire vs the perceived lower security of sending real credentials over protected transport however I just don’t think that consumers of our solutions believe the risk is worth the complexity. If you get a few things right like protected-transport, securing credentials and tokens at the client, token and grant entropy, etc then OAuth 2.0 is good. Eran argues that the list of things you have to know about and “get right” is too long and the specification is not prescriptive enough. As a security professional I provide guidance to clients on this very matter for not just OAuth 2.0 but SSL/TLS, SAML, OpenID and all sorts of other web security technologies on a daily basis. Prescriptive repeatable patterns will emerge.
Beyond the simpler client development model, the use of bearer tokens means that we can also easily implement things like brokered requests as well once you are operating within a trusted server environment. An OAuth service provider absolutely CAN decide to require a client to present both their own credentials and the access token in requests for a protected resource if they wish however this is not a requirement of the protocol. What is a requirement is correct and secure use of a protected transport with server authentication and I can understand that Eran sees this as a risk. The market has clearly decided it’s a more acceptable risk than requiring a client library to do signatures.
The “Under the Hood” section of the article indicates that expiry of access tokens was introduced because of self-encoded access tokens. This is not the only reason, and at least for me is not the most significant reason although it’s closely related. TFIM uses opaque (non-self-describing) access tokens that need to be evaluated back at the authorization server. TFIM also supports “remote” enforcement points for resource servers particularly IBM Web access enforcement points like WebSEAL, Datapower, and WebSphere which can be remote from the TFIM authorization server. To make access token validation perform in high-volume transactions with the same token presented on more than one occasion, TFIM allows enforcement points to optionally cache successful validation results from the TFIM authorization server for the lifetime of that token. When this is done, revocation is not possible until the access token expires (or you have some bespoke method to purge all caches). Essentially this is the same behaviour after first validation as allowing the enforcement point to validate self-encoded tokens. Eran argues that “whatever is gained from the removal of the signature is lost twice in the introduction of the state management requirement”. This is simply an opinion and one that I do not agree with. Refreshing of tokens can be done with a simple POST from the client to the token endpoint requiring no client-side library crypto or hashing algorithms (beyond protected-transport with server authentication) and therefore allows for much simpler client programming models. Yes, the client does have to understand when an access token expires and perform the refresh step, but it’s not a difficult step. Further, if you decide to not do caching at enforcement points with opaque tokens, you don’t need refresh tokens – but you will need a highly available and performant data store for tokens.
In the “Reality” section Eran describes OAuth 2.0 as a blueprint for authorization and “the enterprise way”. I tend to agree, but don’t think of that as a bad thing. He then says “The WS-* way”. As I said at the beginning of this post, OAuth 2.0 is nowhere near as complicated as WS-* and that is an unfair comparison. <controversial>It’s fairly apparent to me that the market has decided that WS-* is too complicated, definitely in the web API world but increasingly also for enterprises.</controversial> Ultimately the market will decide.
My experience has been that our customers want something simple to consume but also demand flexibility in their enterprise software. I believe OAuth 2.0 provides good balance between simplicity, flexibility and capability. It still requires you to have a brain and think about security – I don’t think that will ever change.
In the “To Upgrade or Not to Upgrade” Eran supports customers using OAuth 2.0 with the caveat “and consider yourself a security expert”. I would argue you need to be security conscious for OAuth 1.0 anyway. OAuth 2.0 (with the right patterns) provides distinct advantages over OAuth 1.0 in the area of support for public clients, descriptive new grant-type flows, token scope and refresh tokens. It is a very good base and a prescriptive set of popular patterns will emerge. I’ve even started doing some of this with the mobile security demo documented elsewhere on my blog:
I do find the graphic at the end of Eran’s article quite humorous – good to end on a light note!