Friday, October 26, 2012

Thousand of Providers and Apps for ABBI

The vision for ABBI is to enable thousands of providers to allow patients to automatically download data, possibly using thousands of various health applications.  The challenge this creates is that for the eco-system to work, we need to ensure that 1000 apps X 1000 providers doesn't equal 1,000,000 application registrations for every app to work with every provider.  I was reminded of this by a comment made by Josh Mandel yesterday on another of my ABBI posts.

I've been prototyping my efforts using OAuth 1.0, and have been following Twitter's pattern.  With Twitter, you have to register your app, and get a client key and secret that your app will use later in the Authorization Workflow.  But providers don't want to be in the credentialing business at all, and many would love to off-load that responsibility even for patients to others, so why would they now want to credential applications as well.

In the case of Twitter, it is the singular provider of the Twitter API, yet what we want for ABBI is to have numerous providers of the ABBI API.   We don't want to have each of those applications to have to register with all of the possible data holders, because then the applications would have to have foreknowledge of all data holders.  In fact, based on the consent model, there should not need to be any sort of business relationship between the application developers and the data holders.  But we do want to make sure (from the patient's perspective) that these applications aren't just some rogue actor trying to obtain access to patient information.

I looked to see what the Rhex Project had done, considering they were implementing OAuth 2.0, but no luck.  Page 11 of the Rhex OAuth 2.0 Profile (.doc) states:
Confidential Clients register a JSON Web Key (JWK) with a trusted Authorization Server prior to conducting health exchange transactions.  
So even they require a registration step.

There are a couple of ways to avoid registration.

Don't Use oauth_consumer_key

OAuth 1.0 doesn't require the oauth_consumer_key to be present in the Authorization workflow or in API calls, nor is it required to have a value.  The whole idea that the client application has to register could be ignored.  But, one advantage that oauth_consumer_key and oauth_consumer_secret support is the idea that activities performed by applications on behalf of a user can be traced back to a specific application.  This is rather beneficial.  If my data was downloaded, I'd really like to know which app did it when I check the logs.

I'd like to avoid dropping the oauth_consumer_key if possible.  There's simply no way to convey the client application identity if you do that.

Negotiate oauth_consumer_key without a Registration

OAuth 1.0 leaves completely unspecified the means by which the consumer_key and consumer_secret values are exchanged with the client application. This is by design.  With Twitter, there's a developer's API page you use, and you request keys via the web.  But there could be any number of other mechanisms by which client keys and secrets are exchanged, some of which could be done without a registration step.

Key features of the client key and secret that need to be preserved:

  1. The key needs to uniquely identify the client application, and be distinct from any other client application.
  2. The secret needs to be something that that only the server (data holder) and the client application could have knowledge of.
I have a solution in mind that involves consumer key and secret exchanges with the client application's web-site.  There are several challenges that have to be surmounted in order for this to work, but I'm going to spend some time thinking on this.


  1. Hi Keith,

    Great post and thanks for drawing attention to this topic. In general there are solutions to this problem that have been profiled in detail.

    One comment on your post, and then a couple of known approaches:

    Comment: I think you may be misinterpreting the spec when you say that "oauth_consumer_key" is optional in OAuth 1.0a [1]. On my read (see section 3.1) this is a required parameter for all requests. ("oauth_token", however, is optional for two-legged API calls.)

    Approach 1 (not recommended): "Anonymous clients"
    Google's OAuth 1.0 implementation actually included a provision for anonymous apps that simply use a consumer token/secret of anonymous/anonymous [2]! And then in the user-authorization step they showed a yellow warning box to the effect that the app could be rogue.

    Approach 2 (complex): "Dynamic client registration"
    OpenID Connect, for example, provides a profile for "dynamic client registration" [3]. To register, the client posts a message with its name, logo, URL, client ID, client secret, etc. And as long as it's an https URL and the server *only* redirects authorization requests to that URL, this may be good enough. (There is also a JSON Web Key approach described.)

    Note that even for Approach #1 above: if showing the user an HTTPs redirect URI is "good enough," then anonymous clients may not be inherently bad.

    Finally I'd point you to an extensive discussion I had with the RHEx group on this topic (unfortunately only available with Google sign-in) [4]. Effectively RHEx kept this functionality out of scope, but agreed that it would be important for a "real" ecosystem.

    So... these the approaches I've seen. What are some others that we may be missing?





  2. Rereading RFC 5849, I see that you are correct (I was in section 2, you in 3). You need to have consumer_key, but clearly you could have any (even an empty) value. That gets to your Approach 1. I agree, that's bogus.

    Approach 2 sounds similar what I'm thinking, but slightly different. I'll have to check out the OpenID profile.