Re: [OAUTH-WG] OAuth PoP Implementation

Justin Richer <> Thu, 04 February 2016 14:22 UTC

Return-Path: <>
Received: from localhost ( []) by (Postfix) with ESMTP id DD55F1B300F for <>; Thu, 4 Feb 2016 06:22:07 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -3.901
X-Spam-Status: No, score=-3.901 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, MIME_8BIT_HEADER=0.3, RCVD_IN_DNSWL_MED=-2.3, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=ham
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id a6kJa1ZgjGxH for <>; Thu, 4 Feb 2016 06:22:04 -0800 (PST)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 721E41B2FD2 for <>; Thu, 4 Feb 2016 06:22:04 -0800 (PST)
X-AuditID: 1209190e-c6fff70000001ee4-b7-56b35e8be95e
Received: from ( []) (using TLS with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by (Symantec Messaging Gateway) with SMTP id A8.19.07908.B8E53B65; Thu, 4 Feb 2016 09:22:03 -0500 (EST)
Received: from ( []) by (8.13.8/8.9.2) with ESMTP id u14EM2jM016975; Thu, 4 Feb 2016 09:22:02 -0500
Received: from [] ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.13.8/8.12.4) with ESMTP id u14EM0kp016290 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT); Thu, 4 Feb 2016 09:22:01 -0500
To: Erik Wahlström <>
References: <> <>
From: Justin Richer <>
Message-ID: <>
Date: Thu, 04 Feb 2016 09:21:53 -0500
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1
MIME-Version: 1.0
In-Reply-To: <>
Content-Type: multipart/alternative; boundary="------------050707040402030008010003"
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42IRYrdT0e2O2xxm8P0/t8XXCU2sFiffvmJz YPJYsuQnk8eaaTNYApiiuGxSUnMyy1KL9O0SuDIWXZnJWvB+PmNFy5cXjA2MUwq6GDk5JARM JLY/bmLrYuTiEBJoY5K4t3UJK0hCSGADo8SiacwQiVtMEj8X7mDsYuTgEBYwkHi2UB2kRkTA QeLm+tVMEPWVEp93TGUBKWEWUJdoP+kCEmYTUJWYvqYFrIRXQE2i7/4NFhCbRUBFYsO2Ocwg tqhAjMTFziNQNYISJ2c+AavhFPCUWLzvHxuIzSwQJvH61zOWCYz8s5CUzUKSgrDNJOZtfsgM YctLNG+dDWSDXKQmsaxVCVl4ASPbKkbZlNwq3dzEzJzi1GTd4uTEvLzUIl1jvdzMEr3UlNJN jKCg5pTk28H49aDSIUYBDkYlHt4Gz01hQqyJZcWVuYcYJTmYlER5m202hwnxJeWnVGYkFmfE F5XmpBYfYpTgYFYS4V0WAZTjTUmsrEotyodJSXOwKInzGvEDTRJITyxJzU5NLUgtgsnKcHAo SfByAqNXSLAoNT21Ii0zpwQhzcTBCTKcB2i4L0gNb3FBYm5xZjpE/hSjopQ4775YoIQASCKj NA+uF5R0Et4eNn3FKA70ijCvO0gVDzBhwXW/AhrMBDT4NCPY4JJEhJRUA2NXtdyZf7fdVoqr uCTUOW8qDi/bpHCCraiSQ/n2+VmLahgvnm4VLri+p9jxJV/ya60QlR3noh7dsV6pLFr72bNh xo3S01rSd2usnn1Z5L100antU+IulS1n4DbaOd31v8r27pNclrM/zhdL3GU5/9fMdPOvD95y nD72dQ9bpXlLntwCq7hvPO+VWIozEg21mIuKEwE/x5beFQMAAA==
Archived-At: <>
Cc: "<>" <>
Subject: Re: [OAUTH-WG] OAuth PoP Implementation
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 04 Feb 2016 14:22:08 -0000

Hi Erik, responses inline.

On 2/4/2016 4:20 AM, Erik Wahlström wrote:
> Hi,
> Good work Justin.
> I’ve also implemented (parts) of PoP tokens for the ACE WG oauth2 
> draft and made a lot of the same assumptions.
> See below.
>> On 03 Feb 2016, at 23:47, Justin Richer <jricher@MIT.EDU 
>> <mailto:jricher@MIT.EDU>> wrote:
>> 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:
>> The client requests a token from the auth server using the auth code 
>> flow, nothing special here.
> I use client creds but nothing special there either.

Should be generally identical to bearer tokens, so that's good to hear. :)

>> 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.
> My implementation uses “key” but it would be a quick change.

Yeah, it's a little bikeshedding but I think "access_token_key" is 
clearer and the WG should go in that direction. It'd be a trivial change 
for my code to change to "key" too if we went that way, it's syntax.

> I’ve actually have a problem naming a PoP based access token. Is it a 
> PoP token or an access token?

PoP tokens really have two parts: the access token itself, which is 
analogous to the bearer token, and the key associated with it. That's 
part of why I went with "access_token" and "access_token_key" above. I 
would still consider a PoP token a kind of access token.

>>  - 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.
> Looking through my code I use a string in the token response, but 
> actually use a object in the request if it’s a asymmetric key that 
> should be bound to the token and the client generates the keys. Will 
> change to object in the response.

I think we should be consistent about this, and I think we should use 
objects where possible (IE, where we're already speaking JSON) and 
strings were not (IE, where we're speaking www-form-encoded).

>>  - 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.
> I have that as a config on the AS for the RS.

Makes sense, and I want to explore the implications of client-supplied 
keys on my implementation too. Just haven't gotten there.

>> 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.)
> Will read through changes asap.
>> 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).
> Same here.
>> 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.
> Just so that I follow correctly, do you return something like this 
> (but with access_token_key).
> {
> "active" : true,
> "key" : {"kty”:”…
> / Erik

Yes, exactly like that.

>> 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
>> _______________________________________________
>> OAuth mailing list
>> <>