More Thoughts on OAuth Access Sharing

(Or, About Secondary Tokens)

OAuth Legs In response to my previous post on taking OAuth beyond the 3rd leg, Mike Malone reiterated the point that while these ideas are still better than sharing passwords, they take away much of the security offered by OAuth in the first place. I agree. But the trick is to find a solution that is consistent with the simplicity of the OAuth protocol design. If it is not easy to implement, it is not likely to be used.

Mike suggested to allow applications to request a much more limited token for sharing, with limitations on scope, number of requests, or lifetime. I like this idea, a lot, but the difficulty is to find the right balance of restrictions and usability.

For example, limiting scope might not work with access sharing among applications that need a high degree of access. Lifetime limiting will not allow access sharing with background applications. However, here are some ways to implement this without getting too complicated. Again, these are just ideas and need to be further developed.

The main principal in all these suggestions is to build on top of the previous proposals for access sharing, but instead of giving the other application the token credentials received for the primary application, a different set of token credentials is obtained and shared.

After obtaining a set of token credentials (access token) with the right to share access, the application makes another API call requesting a secondary set of token credentials. It is this secondary set that is shared with the other application.

Secondary Client Binding

Secondary tokens can be issued themselves with a strict application identifier binding. This means that a secondary token can only work for a specific (other) application. It ensures that a secondary token is not further shared by the other application (uncontrolled).

Of course, that might actually be needed as applications get more complex and outsource functionality around. The primary application might want to share access with another application that in turn will want to share access as well.

When requesting a secondary token, the application can use a similar method as the Dynamic Access Sharing Scope proposal from the previous post to specify which other applications are allow to use this secondary token. But this requires that applications know in advance what the other applications will need.

Discovery can help here to avoid complicated handshaking. The application can simply perform LRDD discovery on the other application and in its XRD, find what kind of access sharing it would require.

By binding secondary tokens to specific applications, the server can relay that information to the user in the OAuth access control panel, and allow more transparency as to what each application is doing, as well as a way to revoke secondary tokens by the user if needed.

Limitations All Around

The simplest approach is to place certain restrictions on the secondary token, like limited scope, read / write access, or lifetime. Of course, whatever the limitations are, they must allow the other application to perform its activities, otherwise there is little point in this whole feature. Again, discovery can help here determine what the other application needs.

What needs to happen is for the application to be able to request specific types of secondary tokens. Just like in the previous post, this can be done during registration or dynamically during the request. During the registration means that when selecting which applications to grant access to, the application developer will also manually select the restrictions placed on the secondary token.

Dynamic means adding a parameter to the OAuth protocol to indicate such restrictions. This is in line with an old proposal for an OAuth Token Attributes extension that will standardize such request mechanism. However, it has not evolved much beyond the original idea due to lack of implementation experience. Dynamic requests can happen either for each secondary token request, or when asking for authorization.

The advantage of putting this information at the registration point, or dynamically during the authorization step, is that it allows the server to relay this information to the user and fully communicate the properties of the shared access grant. The trick is to balance the overload of information with the security requirements of the user, so that the user isn’t completely lost with too much details.

Request, Share, Revoke

A different approach, but one that can be combined with the previous suggestions, is to add another API call to revoke secondary tokens. This way, the primary application can simply revoke the secondary token when no longer needed. In many cases, this will be enough because activities are performed in a synchronized fashion.

The way this will work is that the application will request a secondary token, share that token with the other application requesting it to perform some useful activities, and when done, simply revoke the secondary token. It doesn’t prevent the other application from abusing the secondary token, but it is limited by the duration of the shared activity.

Degrees of Secondary

Even with discovery, at some point the relationships between applications gets very complex and while each application can describe itself and the kind of access it needs, the primary application might find itself performing multiple levels of discovery (on the other application and its dependencies, recursively).

While perfectly doable, this seems to get more complicated than this entire design and what it is trying to avoid. When designing access sharing solutions, it is vital to focus on actual use cases. Don’t invent crazy scenarios in which access is shared in complex situations. Find out what works today with good bad old password sharing, and adapt.