[OAUTH-WG] OAuth PoP Implementation

Justin Richer <jricher@mit.edu> Wed, 03 February 2016 22:47 UTC

Return-Path: <jricher@mit.edu>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com []) by ietfa.amsl.com (Postfix) with ESMTP id 999A41B3617 for <oauth@ietfa.amsl.com>; Wed, 3 Feb 2016 14:47:18 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.201
X-Spam-Status: No, score=-4.201 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_MED=-2.3, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=ham
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id 28dj6h8Ai8Mb for <oauth@ietfa.amsl.com>; Wed, 3 Feb 2016 14:47:15 -0800 (PST)
Received: from dmz-mailsec-scanner-1.mit.edu (dmz-mailsec-scanner-1.mit.edu []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id C73BD1B361B for <oauth@ietf.org>; Wed, 3 Feb 2016 14:47:14 -0800 (PST)
X-AuditID: 1209190c-4f7ff70000000918-79-56b283709f23
Received: from mailhub-auth-4.mit.edu ( []) (using TLS with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by (Symantec Messaging Gateway) with SMTP id 60.18.02328.07382B65; Wed, 3 Feb 2016 17:47:12 -0500 (EST)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu []) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id u13MlCv1023979 for <oauth@ietf.org>; Wed, 3 Feb 2016 17:47:12 -0500
Received: from [] (static-96-237-195-53.bstnma.fios.verizon.net []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id u13MlAuj025537 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for <oauth@ietf.org>; Wed, 3 Feb 2016 17:47:12 -0500
From: Justin Richer <jricher@mit.edu>
Content-Type: multipart/alternative; boundary="Apple-Mail=_F6F77C8B-B271-4EE3-9BC8-3C2BE83A4BEF"
Message-Id: <467A26CD-FC42-4E96-AE30-6E4E3B013F41@mit.edu>
Date: Wed, 3 Feb 2016 17:47:10 -0500
To: "<oauth@ietf.org>" <oauth@ietf.org>
Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\))
X-Mailer: Apple Mail (2.2104)
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOIsWRmVeSWpSXmKPExsUixG6nrlvQvCnMoP+5ucXJt6/YHBg9liz5 yRTAGMVlk5Kak1mWWqRvl8CV8ebWZqaC+a4V65pWszUwPrbsYuTkkBAwkbh4dR97FyMXh5BA G5PEjc75bBDOUUaJz9fbGCGc90wSTyfOYwRpYRNQlZi+poUJxGYWSJC4fvkbG4gtLKAo8eDz bjCbV8BKomfjBnYQm0VAReJyxz6wXhEBdYk1538yQdToSby6dZkV4gxZid2/HzFNYOSZhWTs LCRlEHFtiWULXzND2JoS+7uXs2CKa0h0fpvIuoCRbRWjbEpulW5uYmZOcWqybnFyYl5eapGu oV5uZoleakrpJkZQ+HFK8uxgfHNQ6RCjAAejEg/vDe9NYUKsiWXFlbmHGCU5mJREeQtDgUJ8 SfkplRmJxRnxRaU5qcWHGCU4mJVEeHtKgHK8KYmVValF+TApaQ4WJXFeI36glEB6Yklqdmpq QWoRTFaGg0NJgre0CSgrWJSanlqRlplTgpBm4uAEGc4DNLwApIa3uCAxtzgzHSJ/ilFRSpyX GSQhAJLIKM2D6wWlh4S3h01fMYoDvSLMuwKkigeYWuC6XwENZgIaPJtvPcjgkkSElFQDY/EM pTempzXDslOsbQsLrSX8J8QtXTGtc/nGSQ4cK5w959bKbbryYdrt+xpsu6WPb3eM0WtX3GjZ MCn228TPYS9PtBY94NWUjpom26WWsHNjQ8Bl9pNZy6OW3K73yOWad+ii0S5Hy2ucF8XPhtYs nFJ+NVf1s07BhZu9N0PE/s5Ztv6HrArbTCWW4oxEQy3mouJEAAZY9QnqAgAA
Archived-At: <http://mailarchive.ietf.org/arch/msg/oauth/svZK02yGXpe7KbtEt88f1q7RXy0>
Subject: [OAUTH-WG] OAuth PoP Implementation
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 03 Feb 2016 22:47:18 -0000

Hi Everyone,

I recently decided to put together an end to end implementation of at least part of the proposed OAuth specs. I haven’t seen any other implementations of the whole system, so I wanted to see how viable this whole idea really. It’s done in Node.js (using Express.js) and it’s on GitHub here:

https://github.com/jricher/oauth-pop <https://github.com/jricher/oauth-pop>

The client requests a token from the auth server using the auth code flow, nothing special here.

The AS generates a random-value access token and a 2048-bit RSA key in JWK format. It sends the keypair to the client alongside the token. This step varies from the pop-key-distribution draft in the following ways:

 - Parameter name is “access_token_key” instead of just “key”, partially to allow us to redefine keys for other tokens like refresh tokens in the future.
 - Key is returned as a JSON object, not string-encoded. I think we should use the fact that JWK is JSON in the response from the token endpoint. This makes it difficult for the implicit flow, but we can define a separate encoding for that flow. I don’t see a good argument for crippling the token endpoint with the limitations of another part of the system.
 - The AS doesn’t return an algorithm, I should probably add that to my implementation though.
 - The AS doesn’t let the client pick its keys or algorithms on any part of the process but always issues the same key type. I understand this to be a valid (if not very friendly) interpretation of the spec.

The client takes this token and key and makes a JWS-signed object out of them. It adds a few bits about the request, but doesn’t do the normalization and hashing of query parameters and headers yet. That’s an important bit that still needs to be implemented. 

The client sends the signed object (which includes the token) to the RS over the authorization header using the “PoP” scheme name, mirroring bearer tokens.

(Note: I’ve also updated the HTTP signing draft to incorporate the necessary changes above, which were discussed in Yokohama. That should be posted to the list already. It’s a lot of rewriting, so please check the diffs. Yes, I’m aware that the chairs have stated their intent to replace me as editor for the document, but I haven’t heard any communication beyond that original announcement so I felt it prudent to publish the update anyway.)

The RS parses the signed object out of the header and extracts the token. The RS introspects the token at the AS to get the key (note that it doesn’t send the whole signed object, just the access token itself). The key is returned in the introspection response as “access_token_key”, parallel with the response from the token endpoint. It is a JSON object here, too (not encoded as a string). Whatever we decide for the token endpoint response we should stay consistent for the introspection response.

The RS uses the key to validate the JWS’s signature. The RS uses the other bits from the introspection callback (scopes, client ID, stuff like that) to determine how to respond, like with bearer tokens.

The RS responds to the client like in a more traditional OAuth request.

It’s my hope that this simple implementation can help us move the conversation forward around PoP and help us make sure that what we’re implementing is actually viable. 

 — Justin