Friday, December 3, 2010

OAuth: More Than Just Delegation

It seems many are still looking at OAuth as simply a delegation protocol. I think it is much more. Let's take a moment and highlight some features that go beyond simple delegation, and get at some of the real value behind OAuth.

Authentication & The Password Anti-Pattern
One way to look at OAuth is that it is a "Proxy Authentication" system. It allows applications acting on a user's behalf (as a proxy) to access user-controlled or identity-centric services like your bank account, or your google docs account. Unlike most approaches today, OAuth does not use user-ids and passwords (the dreaded password anti-pattern). If you haven't heard it before, you should never share your password for one service provider with another. If you still aren't sure why this is a big deal, read the story on the recent Gawker Media Hack and how it spread to include multiple social media accounts.

In OAuth, applications have their own credentials (a 'client_id'). There are multiple ways for them to authenticate with a service provider. The client application obtains a token (with user consent) with which the client application can act on behalf of a user. Note the important distinction: the application does not become the user. The application is simply able to indicate that it is acting on behalf of a user for a particular scope of activity.

Separation of Roles/Rights/Entitlements
Consider a Financial aggregation site (there are several now) uses user-id and password to access a customer's bank account to aggregate information from multiple institutions. Because of the password-anti pattern, accessed banks have increased difficulty distinguishing the real customer from the aggregator service masquerading as the customer. Thus the bank ends up potentially giving full access to the aggregator which may not be desirable to the user. Because the aggregator needs to use the customer's user-id and password, the customer must place a lot of trust in the aggregator not to do bad things with their account.

The pattern of using a user-id/password means that service providers like banks, cannot easily distinguish customers from client applications. Because of this, the ability to set finer grained access rights is limited. I am somewhat simplifying here, but because OAuth uses both a client application credential (aka client identifier) and a token representing the user's scope of permission, service providers like banks, are able to set different access policies for client applications authorized by their customers.

OAuth creates the possibility for policy/access management servers set specific access roles/rights/entitlements for client applications acting on a user's behalf to access services. Now the bank can more easily limit the financial aggregator to only those operations authorized by their customer.

Flexible Session Lifetimes
We tend to think of a session as what happens when we log into a site using a browser. We perform some operations and then log out. In other cases we may already be logged in due to a long-lived cookie. The service provider site can also set a cookies that span multiple days or weeks. The lifetime of a login really depends on the nature of the service provider web site and the service being offered.

The typical pattern of user-in-the-browser sessions may not be optimal for client services and non-browser application (such as on a smart phone). For example, a photo printing service might only need one-time access to a set of photos. While a smart-phone photo browsing application would more typically have ongoing access since the application is in the control of the user.

OAuth uses a code/refresh token/access token system that enables 3 possible session lifetimes for a single relationship. It sounds complex, but let's boil it down...
  1. When a user initially authorizes an application to have access, a code is issued (first lifetime). Typically this code is used one-time to obtain something called a refresh token or access token.
  2. A refresh token (the second lifetime) is optional, but the intention is that it is kept for a longer term and allows the client application to obtain resource access tokens. Refresh tokens might typically last days or months.
  3. Resource access tokens (third lifetime) are then used (often as bearer tokens) to access protected services. These tokens are typically short-lived (minutes/hours).
The effect is that client applications can obtain a long term access grant from the user, but the grant is constantly re-verified by requiring the client app to both authenticate to the service with its own credential, and reissue its resource access token (lasting minutes or hours).

While this seems like a lot of overhead, it really isn't. Once the refresh token is obtained, the client app only has to use the refresh token once to request an resource access token. At this point, the pattern is not that unlike a browser login followed by an SSO cookie being set. As with the browser SSO cookie, the client app uses the resource access token for each operation until it expires.

One of the benefits of the approach of a refresh token and access token approach is it forces the client app to re-authenticate to re-verify its access fairly frequently. This is actually very important as it enables the possibility of revocation. If a user (or a web site) chooses to revoke an OAuth grant or authorization, the client application access is effectively terminated as soon as the current access token has expired. When the client application attempts to use its refresh token to obtain a new access token, the access manager will reject the request.

Revocation is a nice feature. It is probably one of the most under-estimated features of OAuth. If you use Twitter, or Facebook, check out your account applications settings page and you'll see what I mean. You'll see that you are probably already using OAuth extensively you'll be surprised at how many grants you have already given out!


Anonymous said...

Why does revocation require refresh tokens?
When I click "Revoke Access" for an app on my Twitter Settings page I hope access stops for that app immediately (at worst, say, in 30 seconds due to backend sync delays). I don't expect access to continue for minutes/hours until the app next tries to refresh its access token.

Phil Hunt said...

True. This is because there is no immediate revocation mechanism. Sites where revocation is critical can have a very low lifetime for access tokens (e.g. 60 seconds). This would force re-issuance every 60 seconds -- effectively creating a smaller window for revocation to be effective. Unfortunately it is at some performance cost!

Anonymous said...

You can check if the idendity associated with an access token is revoked. There is no need for a refresh phase to do it. (at least in most scenarios). Of course it is an optimization to not recalculate the permission of a session on each use.

Phil Hunt said...

This discussion thread on the WG list may be more enlightening...

Or more specifically...

There is some discussion of highlighting this in revision 21.

Unknown said...

That's a big problem. In fact, when I talked to my bank about this they had to refer to higher management, because no traditional customer do that.

But they ended up suggesting me something interresting. A solution can be to create a separate debit card, with only "Query" access. But when I asked for it, they said that I can only have ONE debit card. I hope this situation will change. It might be a good decision factor to check for before changing bank.

Phil Hunt said...

I think you may be confusing authentication vs authorization. With oauth you would not get a second "bank card". The point is you can authorize a client to have specific scoped rights.

Post a Comment