Pages

Saturday, February 2, 2013

OAuth 2.0 Headaches for ABBI

Now I understand why Eran Hammer wrote OAuth 2.0 and the Road to Hell.  I've been playing around with how to address client registration issues.  Right now, I have the following open in my browser:

  1. JSON Web Signature (JWS) [IETF Draft 4]
  2. JSON Web Token (JWT) [IETF Draft 6]
  3. JSON Web Token (JWT) Bearer Token Profiles for OAuth 2.0 [IETF Draft 4]
  4. JSON Web Algorithms (JWA) [IETF Draft 8]
  5. Assertion Framework for OAuth 2.0 [IETF Draft 8]
  6. The OAuth 2.0 Authorization Framework [RFC 6749]

Does this sound vaguely familiar?  Recall these seven: MU Stage 1, HITSP C32, C80, C83, IHE XPHR, HL7 CCD, HL7 CDA

Here's the break down:
OAuth 2.0 is being used to support capturing the authorization of the patient [or authorized representative] to allow a client application instance to access PHI on the patient's behalf.   The Assertion Framework for OAuth 2.0 specifies the parameters that tell how the client assertion of its identity is being exchanged in the OAuth 2.0 protocol.  JWT Bearer token profiles describes how a JWT bearer token is constructed for OAuth 2.0 for client identity and other uses.  JWS explains how a signed JWT is exchanged.  JWA indicates the algorithms that are used in JWS. And two of these don't yet agree on whether the key for who the principal is "prn" or "sub", or perhaps I don't understand the distinctions being made.


You'll note that NOT listed above is the OAuth Dynamic Client Registration Protocol [IETF Draft 04].  That's because I traded one problem [Dynamic Registration], for five others [to support a signed assertion of client identity] .  I'm not sure it was a good trade, but I'm going to plug away at this anyway.


I think we need to develop the Joined JSON Profile for OAuth 2.0 Web Authorization, which I'm going to call J-JWA, as a pun on C-CDA.  The biggest challenge for me in all of this is that with the exception of the OAuth 2.0 Framework, the rest of these are in draft form.  However, maybe we can address it in J-JWA, and we'll never have to go down that path we've been through before.

-- Keith

6 comments:

  1. I think assertion-based authorization grants solve a different problem than dynamic client registration:

    * dynamic client registration informs the server that your client exists (and gives it a name, redirect uri, etc.)
    * assertion-based authorization grants avoid sending a shared secret over the wire when requesting tokens

    Where I see JWT assertions being used in practice is to let apps request access tokens (the "/token" endpoint, so to speak) when two important constraints are met:

    Constraint 1. the app has already been registered with the service provider, and

    Constraint 2. a user has already granted authorization, or the app is getting tokens that aren't scoped to user-level data

    Two examples (Salesforce + Google):

    http://help.salesforce.com/help/doc/en/remoteaccess_oauth_jwt_flow.htm
    Constraint 1. "The developer creates a new or uses an existing remote access application"
    Constraint 2. JWT is used "when a client wishes to utilize a previous authorization"

    https://developers.google.com/accounts/docs/OAuth2ServiceAccount#libraries
    Constraint 1. "After obtaining the client_id and private key from the API Console, create a JWT..."
    Constraint 2. "Permission to perform this type of impersonation must be granted before..."

    So overall, while there is certainly a role for JWT assertions in OAuth, I don't see how it gets us automated registration.

    And as you point out:

    * draft status all around
    * many specs to read
    * limited implementation in existing client and server libraries

    I could see a role for JWT assertions in making the dynamic client registration process more secure. Especially as an optional enhancement...

    But I'm continuing to recommend that we stick with the base OAuth2 profiles (authorization_grant and implicit grants for getting tokens; bearer tokens for authenticating API requests) -- and adding in dynamic client registration -- to give ABBI Pull the best shot at getting off the ground.

    ReplyDelete
    Replies
    1. Assertions can be used to assert the client identifier as well, which addresses the need for dynamic registration: According to OAuth 2.0:

      Client registration does not require a direct interaction between the client and the authorization server. When supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties (e.g., redirection URI, client type). For example, registration can be accomplished using a self-issued or third-party-issued assertion, or by the authorization server performing client discovery using a trusted channel.

      So, the authorization_grant and implicit grant flows with bearer tokens would still be used for authorizing API requests. These might use assertion based bearer tokens, but that's a separate story.

      Delete
  2. Ah, you're talking about using assertions as part of an automated client registration process. (I was confused because your references above focused on using assertions for authorization grants and client authentication, rather than client registration.)

    So yes: assertions can be used as part of an automated (dynamic) registration process. Effectively this looks a lot like the dynamic client registration draft protocol we've been discussing (http://tools.ietf.org/html/draft-ietf-oauth-dyn-reg-04).

    In fact, that draft lists as a requirement:

    ```
    1.3.3. The authorization server should have the option of strongly
    authenticating the client and its metadata

    ... This might be solved using message signature verification.
    ```

    -- a requirement that doesn't appear to be met today. So maybe that's an opportunity to flesh out an existing spec (i.e. adding to draft-ietf-oauth-dyn-reg), rather than creating a de novo specification.

    And then I keep coming back to the question of apps that can't keep secrets. Public clients like a pure HTML5/JavaScript statically-hosted app; an app implemented as a browser extension; an iPad app, etc., can't really generate assertions. (Well, perhaps a hosted web app can -- not at runtime, but at install-time it could generate and statically host an assertion.)

    And if public client's can't use assertion-based registration, ABBI should make this a security-enhancing option in a more general dynamic registration process.

    I may well be missing an idea you have about how to accomplish this; or we might just have different opinions about how important it is to support public clients.

    (It's also worth noting that a little bit of centralized infrastucture could ease the actual implementation process -- especially if participation is optional. E.g. a centralized repository of certificates/assertions for each ABBI data holder would allow apps to regularly register themselves with any newcomers. Or vice versa...)

    ReplyDelete
  3. On re-reading, I take back my claim about public clients not being able to generate assertions :-)

    Sure the apps themselves can't generate new assertions at runtime, but their authors can always generate signed "here's my metadata" assertions at install-time and package these with the app.

    So I get where you're coming from: apps can package (and include with dynamic registration requests) assertions signed with their own certificate to express (say):

    {
    "redirect_uris": "https://blood-pressure-grapher.org bloodpressure://go",
    "client_name": "Blood Pressure Centiles",
    "client_url": "https://blood-pressure-grapher.org",
    "logo_url": "https://blood-pressure-grapher.org/logo.png"
    "contacts": "support@blood-pressure.grapher.org",
    "token_endpoint_auth_type": "none",
    "grant_type": "implicit"
    }

    ... sign the whole thing with the app's private key and keep it around for subsequent dynamic registration invocations. (And/or submit it to a registry where it can be discovered. Etc.)

    Overall this requires developers to understand/implement JWT *once* to sign their "who am I" assertion. But they don't need to use JWT at all during the authorization grant process, or to get tokens, or to execute API calls.

    Is that the idea? I do like it as an option.

    ReplyDelete
    Replies
    1. That's the general idea, but taking it one step further. If you are supplying the authorization endpoint with a signed identity, why does it even need to be "registered". It can eliminate the dynamic registration step altogether.

      Delete
    2. If you omit registration, you don't get to assign an app a client_secret.

      While this isn't strictly necessary, I'd be more comfortable using the common authorization workflows described in the base OAuth2 spec. In particular, we should support the simple workflow where confidential clients include a client_secret when exchanging an authorization code for an access token (and public clients don't).

      * This flow involves no "invention" on ABBI's part

      * This flow is used by large, successful OAuth2 deployments (Google, Facebook, Salesforce)

      * This flow has the broadest client library support

      Delete