Subject: Re: [OAUTH-WG] DPoP - Downgrades, Transitional Rollout & Mixed Token Type Deployments

From: George Fletcher <[email-masked]>
Date: Fri, 5 Jun 2020 16:17:17 -0400

The issue I see with sticking with the DPoP token_type is that from a 
roll_out perspective, ALL resource servers must be updated to support 
the new scheme and only then can the DPoP deployment start. For any wide 
ecosystem deployment that can be problematic. I don't have any great 
suggestions:(

Secondly, I do think we need a way to allow for the refresh_token to be 
bound while leaving the access_tokens as bearer tokens. This adds useful 
security without impacting existing RS deployments. It was unclear from 
our interim meeting discussion how the client knows whether the refresh 
token has been bound to the public key or not. The AS can signal that 
the access_token is NOT bound by returning a token_type of "bearer" but 
we should think about adding addition response fields for the refresh 
token binding (e.g. "rt_token_type).

Thanks,
George

On 5/29/20 5:50 PM, Brian Campbell wrote:
> Apologies for the slow reply on this. No excuses other than life  > sometimes happens. > > `token_type` is maybe not the clearest 
extension point (and one I've > arguably misused in OAuth MTLS > 
<https://www.rfc-editor.org/rfc/rfc8705.html> and the now defunct > 
Token Binding > 
<https://tools.ietf.org/html/draft-ietf-oauth-token-binding-08>and > 
admitted to being on the fence about in the issue you linked to > 
<https://github.com/danielfett/draft-dpop/issues/41>). But it is the > 
extension point that was basically left in RFC 6749 to facilitate > this 
exact kind of thing (for MAC really but it's conceptually > similar in 
that it was an application level proof mechanism of sorts) > . The text 
from RFC 6749 sec 7.1 > 
<https://tools.ietf.org/html/rfc6749?#section-7.1> is also copied > 
below. Note that a "client MUST NOT use an access token if it does > not 
understand the token type" so FWIW the client behaviours you > describe 
aren't in line with that. > > It still seems to be that using DPoP 
token_type is the appropriate > thing to do and that it can be defined 
to account and allow for mixed > token type situations. It would define 
that the DPoP authz scheme be > used as the authentication method to 
include the access token when > making a protected resource request. 
That definition can also include > falling back to using the Bearer 
authz scheme when/if so challenged > by a protected resource. > > 
<https://tools.ietf.org/html/rfc6749?#section-7.1> > > 7.1 
<https://tools.ietf.org/html/rfc6749?#section-7.1>. Access Token > Types 
 > > The access token type provides the client with the information > 
required to successfully utilize the access token to make a > protected 
resource request (along with type-specific attributes). > The client 
MUST NOT use an access token if it does not understand the > token type. 
 > > For example, the "bearer" token type defined in [RFC6750 > 
<https://tools.ietf.org/html/rfc6750>] is utilized by simply > including 
the access token string in the request: > > GET /resource/1 HTTP/1.1 
Host: example.com Authorization: Bearer > mF_9.B5f-4.1JqM > > while the 
"mac" token type defined in [OAuth-HTTP-MAC > 
<https://tools.ietf.org/html/rfc6749?#ref-OAuth-HTTP-MAC>] is > utilized 
by issuing a Message Authentication Code (MAC) key together > with the 
access token that is used to sign certain components of the > HTTP 
requests: > > GET /resource/1 HTTP/1.1 Host: example.com Authorization: 
MAC > id="h480djs93hd8", nonce="274312:dj83hs9s", > 
mac="kDZvddkndxvhGRXZhvuDjEWhGeE=" > > The above examples are provided 
for illustration purposes only. > Developers are advised to consult the 
[RFC6750 > <https://tools.ietf.org/html/rfc6750>] and [OAuth-HTTP-MAC > 
<https://tools.ietf.org/html/rfc6749?#ref-OAuth-HTTP-MAC>] > 
specifications before use. > > Each access token type definition 
specifies the additional > attributes (if any) sent to the client 
together with the > "access_token" response parameter. It also defines 
the HTTP > authentication method used to include the access token when 
making a > protected resource request. > > > > On Tue, May 19, 2020 at 
7:20 AM Filip Skokan <[email-masked]> > wrote: > >> This is a RE: to 
yesterday's interim meeting discussion, largely >> related to the first 
rollout step where we want to constrain >> refresh tokens but leave 
protected resource access intact. >> >> I'll start off with a case that 
I hope we can agree is absolutely >> necessary for DPoP to solve - that 
is constraining refresh tokens >> for browser based applications. Now, 
*do we see this as a >> secondary objective? I think it should be on par 
with access token >> constraining.* SPAs using code flow and having 
access to refresh >> tokens as means against the continuous browser 
efforts to cut down >> on storage access is a real case servers will be 
eventually forced >> to adopt. >> >> Since rollout for DPoP needs to 
begin with the AS and Client >> supporting it (regardless what order i 
guess) there are going to be >> instances where the RS will be 
supporting both Bearer and DPoP at >> the same time. >> >> As discussed 
yesterday, the client shouldn't know/care and change >> its behaviour 
when it comes to using access tokens. >> >> *But what is the client 
behaviour we take for standard?* Because I >> can see two conflicting 
implementations in the wild >> >> 1. The client echoes the token_type it 
received from the token >> endpoint as the authorization scheme - 
(optionally) throws on >> unrecognized token type values 2. The client 
uses Bearer as a fixed >> authorization scheme and ignores the 
token_type it received >> >> #2 is an implementation which I suspect has 
no idea about DPoP, but >> if extended to send DPoP headers (through 
various mechanism - >> library extensions or even manipulating the 
`XMLHttpRequest` >> prototype) will >> >> - 🎉 get the benefit of having 
its Refresh Tokens bound - 🎉 most >> likely continue to work with RSs 
that only support Bearer - ❌ will >> cease to work with RSs that will 
adopt support for DPoP because >> it'll be using the wrong scheme, that 
is unless (🎉) RSs >> supporting DPoP choose to suspend the requirement 
to use the new >> scheme and instead depend on the presence of `cnf.jkt` 
as means to >> trigger DPoP validation. *Q: is that an acceptable thing 
to do?* >> >> Arguably, client behaviour #1 is what a client should be 
using if >> it supports other schemes besides Bearer. But it may as well 
be the >> behaviour of a client that has no clue about DPoP, right? 
Again, >> such client can be made to support DPoP in a SPA through >> 
manipulation of the XMLHttpRequest prototype, in which case the >> 
developer needs to do the same for the protected resource calls. >> But 
at this point the developer has to know which RS to apply DPoP >> to and 
which not - ergo - which to send Bearer vs. DPoP scheme to? >> The 
developer will have to write a whitelist of resource servers >> anyway - 
and there we get to the point where client has >> information and 
functionality that it shouldn't /need to/ have. >> >> Its great that we 
have token_type, authorization header schemes, >> etc..., but we don't 
seem have a well defined (or at least >> followed) behaviour for our 
clients around handling the token_type >> response values and their 
usage. >> >> A developer has to resolve to navigate this monkey course 
unless >> the RS definition on the AS is aware of the fact that the RS 
does >> support DPoP, so that the issued token_type is always correct 
for >> the RS. So, *should we make that a recommended way of 
'indicating' >> when to issue Bearer vs DPoP access tokens?* >> >> What 
else could we do that doesn't give more decision making to >> the 
clients so that the very first step - *Refresh Tokens get >> 
constrained* - is achieved* but Protected Resource access is >> 
unaffected?* >> >> Note that this was not "a thing" for mTLS because it 
continues to >> use the Bearer scheme (for better or worse) and it 
completely omits >> possible continuous rollout or discussing what are 
the signals the >> RS must use to require mTLS to be used), same for the 
abandoned >> OAuth 2.0 Token Binding draft (also continued to use the 
Bearer >> scheme). >> >> I suspect we have just this opportunity to fix 
token types and >> their use and if we can't, we'll have to resolve to 
abandon that >> extension point as one that doesn't support continued 
rollout of >> real sender constraining mechanism (e.g. http signatures 
in the >> future) and just continue using Bearer because in the end, 
given >> that RSs could be relying on the presence of the cnf claim to 
 >> figure out the token's constraining mechanism, would that be such a 
 >> bad thing? >> >> Put it the other way around. By introducing Bearer 
scheme, do we >> actually gain anything of value that can't be gained 
through other >> means? >> >> Note that this message didn't start with 
the goal of questioning >> the new scheme use, it just sort of landed 
there... My pedantic >> nature would love to see the new scheme and 
token_type extension >> point used as it was meant to be but I also 
recognize the many >> issues it brings that could be sidestepped by not 
introducing it in >> the first place, all without losing capabilities. 
 >> >> Previous material on the topic >> >> - 
https://github.com/danielfett/draft-dpop/issues/41, decision to >> break 
backwards compatibility amongst the authors - ML >> 
<https://mailarchive.ietf.org/arch/browse/oauth/?q=%22DPoP%20-%20new%20authorization%20scheme%20%2F%20immediate%20usability%20concerns%22&gbt=1&index=> 
 >> thread, in my opinion inconclusive, no consensus >> >> >> S 
pozdravem, *Filip Skokan* >> 
_______________________________________________ OAuth mailing list >> 
[email-masked] https://www.ietf.org/mailman/listinfo/oauth >> > > > 
_______________________________________________ OAuth mailing list > 
[email-masked] https://www.ietf.org/mailman/listinfo/oauth

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sat, 6 Jun 2020 10:06:02 +0200

> Am 05.06.2020 um 22:17 schrieb George Fletcher <gffletch=[email-masked]>:
> 
> Secondly, I do think we need a way to allow for the refresh_token to be bound while leaving the access_tokens as bearer tokens. This adds useful security without impacting existing RS deployments.

+1 that’s a very useful feature

---

From: Francis Pouatcha <[email-masked]>
Date: Sat, 6 Jun 2020 18:57:24 -0400

>
>
> > Am 05.06.2020 um 22:17 schrieb George Fletcher <gffletch=40aol.com@dmarc.
> .ietf.org>:
> >
> security without impacting existing RS deployments.
>
> +1 that’s a very useful
> feature_______________________________________________
>
AFAIK a refresh_token is always bound. What am I missing here?
-- 
Francis Pouatcha
Co-Founder and Technical Lead at adorys
https://adorsys-platform.de/solutions/

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 12:41:48 +0900

DPoP-bound refresh token seems feature duplication with dynamic client registration.

> 2020/06/07 7:57、Francis Pouatcha <fpo=[email-masked]>のメール:
> 
> 
> > Am 05.06.2020 um 22:17 schrieb George Fletcher <gffletch=40aol.com@dmarc..ietf.org <http://ietf.org/>>:
> > 
> +1 that’s a very useful feature_______________________________________________
> https://adorsys-platform.de/solutions/ <https://adorsys-platform.de/solutions/>_______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sun, 7 Jun 2020 09:22:00 +0200

That’s correct for confidential clients.

For a public client, the refresh token is just bound to the client id. DPoP allows binding to an ephemeral key pair for this kind of clients.

> Am 07.06.2020 um 00:57 schrieb Francis Pouatcha <fpo=[email-masked]>:
> 
> 
>> 
>> > Am 05.06.2020 um 22:17 schrieb George Fletcher <gffletch=40aol.com@dmarc..ietf.org>:
>> >

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sun, 7 Jun 2020 09:24:36 +0200

There are similarities in this particular use case but I would argue DPoP is more light weight than dynamic client registration, less state management in particular.

> Am 07.06.2020 um 05:41 schrieb Nov Matake <[email-masked]>:
> 
>> _______________________________________________
>> OAuth mailing list
>> [email-masked]

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 20:04:43 +0900

Since each client instance has at least one key, those are same level of state management.

> 2020/06/07 16:24、Torsten Lodderstedt <[email-masked]>のメール:
> 
>>> 2020/06/07 7:57、Francis Pouatcha <fpo=[email-masked] <mailto:fpo=[email-masked]>>のメール:
>>> 
>>> 
>>> > Am 05.06.2020 um 22:17 schrieb George Fletcher <gffletch=40aol.com <http://40aol.com/>@dmarc..ietf.org <http://ietf.org/>>:
>>> > 
>>> [email-masked] <mailto:[email-masked]>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sun, 7 Jun 2020 13:25:54 +0200

If the client would register for every transaction.

And don’t forget, DPoP also supports sender constrained access to resource servers, which dyn registration does not.

> Am 07.06.2020 um 13:04 schrieb Nov Matake <[email-masked]>:
>

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 20:33:46 +0900

Confidential clients can also use DPoP.

> 2020/06/07 20:25、Torsten Lodderstedt <[email-masked]>のメール:
> 
>>> 2020/06/07 16:24、Torsten Lodderstedt <[email-masked] <mailto:[email-masked]>>のメール:
>>> 
>>>> Am 07.06.2020 um 05:41 schrieb Nov Matake <[email-masked] <mailto:[email-masked]>>:
>>>> 
>>>>> https://www.ietf.org/mailman/listinfo/oauth <https://www.ietf.org/mailman/listinfo/oauth>
>>>> 
>>

---

From: Neil Madden <[email-masked]>
Date: Sun, 7 Jun 2020 12:49:30 +0100

There are multiple issues with using dynamic client registration for this. If a user uninstalls and later reinstalls an app then they can end up with multiple registrations for the same client, which makes it harder for them to manage access. Additionally, client registrations typically don’t expire so the AS doesn’t know when it can remove unused clients.

Besides, this ship already sailed with mTLS cert-bound refresh tokens. 

Neil

> On 7 Jun 2020, at 12:34, Nov Matake <[email-masked]> wrote:
>

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 21:07:44 +0900

So, you mean…

If a frontend client want to use
* sender-constrained code, bearer access token and sender-constrained refresh token, use DynReg.
* sender-constrained code, sender-constrained access token and sender-constrained refresh token, use DynReg + DPoP.
* bearer code, sender-constrained access token and sender-constrained refresh token, use DPoP only.
* bearer code, bearer access token and bearer refresh token, use neither.

is my understanding correct??

> 2020/06/07 20:49、Neil Madden <[email-masked]>のメール:
> 
>>> 2020/06/07 20:25、Torsten Lodderstedt <[email-masked] <mailto:[email-masked]>>のメール:
>>> 
>>>> Am 07.06.2020 um 13:04 schrieb Nov Matake <[email-masked] <mailto:[email-masked]>>:
>>>>

---

From: Neil Madden <[email-masked]>
Date: Sun, 7 Jun 2020 13:26:41 +0100

Answers inline: 

> On 7 Jun 2020, at 13:07, Nov Matake <[email-masked]> wrote:
> 
> So, you mean…
> 

I’m not really sure what a sender-constrained code would be, but I suspect the right answer here is PKCE + DPoP. PKCE basically is PoP for auth codes. 

> * sender-constrained code, sender-constrained access token and sender-constrained refresh token, use DynReg + DPoP.

PKCE + DPoP

> * bearer code, sender-constrained access token and sender-constrained refresh token, use DPoP only.

Sure, but you should always use PKCE, so PKCE + DPoP. 

> is my understanding correct??

Just use PKCE + DPoP. (Or a different PoP mechanism, eg mTLS cert-bound tokens, or etc).

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 21:36:41 +0900

Yeah, both PKCE and Client Credential provide sender-constrained code...
lots of choices

Sent from my iPhone

> On Jun 7, 2020, at 21:26, Neil Madden <[email-masked]> wrote:
> 
> 
> Answers inline: 
>

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 21:42:05 +0900

* sender-constrained code, bearer access token and sender-constrained refresh token, use DynReg or "PKCE + DPoP allowing access token remaining bearer".
* sender-constrained code, sender-constrained access token and sender-constrained refresh token, use "DynReg + DPoP" or "PKCE + DPoP".
* bearer code, sender-constrained access token and sender-constrained refresh token, use DPoP only.
* sender-constrained code, bearer access token and bearer refresh token, use PKCE only.
* bearer code, bearer access token and bearer refresh token, use none of them.

> 2020/06/07 21:36、Nov Matake <[email-masked]>のメール:
> 
>>>> 2020/06/07 20:49、Neil Madden <[email-masked] <mailto:[email-masked]>>のメール:
>>>> 
>>>>> On 7 Jun 2020, at 12:34, Nov Matake <[email-masked] <mailto:[email-masked]>> wrote:
>>>>>

---

From: Francis Pouatcha <[email-masked]>
Date: Sun, 7 Jun 2020 10:00:06 -0400

I am a little bit confused. Let me  break it down:

code :
  -> sender : Client
  -> consumer : AS
  -> sender PoP :
       --> confidential client: code_verifier (PKCE)
       --> public client:  code_verifier (PKCE)?

refresh_token :
  -> sender : Client
  -> consumer : AS
  -> sender PoP :
       --> confidential client: private_key_jwt, mTLS
       --> public client:  DPoP?

access_token :
  -> presenter : Client
  -> consumer : RS
  -> sender PoP :
       --> confidential client: private_key_jwt, mTLS
       --> public client:  DPoP?

Is this correct?

On Sun, Jun 7, 2020 at 8:42 AM Nov Matake <[email-masked]> wrote:

> * sender-constrained code, bearer access token and sender-constrained
> refresh token, use DynReg or "PKCE + DPoP allowing access token remaining
> bearer".
> * sender-constrained code, sender-constrained access token and
> sender-constrained refresh token, use "DynReg + DPoP" or "PKCE + DPoP".
> I’m not really sure what a sender-constrained code would be, but I suspect
> the right answer here is PKCE + DPoP. PKCE basically is PoP for auth codes.
>
> * sender-constrained code, sender-constrained access token and
> sender-constrained refresh token, use DynReg + DPoP.
>
>
> PKCE + DPoP
>
> There are multiple issues with using dynamic client registration for this.
> If a user uninstalls and later reinstalls an app then they can end up with
> multiple registrations for the same client, which makes it harder for them
> to manage access. Additionally, client registrations typically don’t expire
> so the AS doesn’t know when it can remove unused clients.
>

---

From: Nov Matake <[email-masked]>
Date: Sun, 7 Jun 2020 23:18:33 +0900

private_key_jwt and mTLS can be sender PoP method for code too.

> 2020/06/07 23:00、Francis Pouatcha <[email-masked]>のメール:
> 
> On Sun, Jun 7, 2020 at 8:42 AM Nov Matake <[email-masked] <mailto:[email-masked]>> wrote:
>> 2020/06/07 21:36、Nov Matake <[email-masked] <mailto:[email-masked]>>のメール:
>> 
>>> On Jun 7, 2020, at 21:26, Neil Madden <[email-masked] <mailto:[email-masked]>> wrote:
>>> 
>>> 
>>> Answers inline: 
>>> 
>>>> On 7 Jun 2020, at 13:07, Nov Matake <[email-masked] <mailto:[email-masked]>> wrote:
>>>> 
>>>> So, you mean…
>>>> 
> https://adorsys-platform.de/solutions/ <https://adorsys-platform.de/solutions/>

---

From: Francis Pouatcha <[email-masked]>
Date: Sun, 7 Jun 2020 11:02:38 -0400

> private_key_jwt and mTLS can be sender PoP method for code too.
Yes,correct thanks for pointing this out: So we have
code :
  -> sender : Client
  -> consumer : AS
  -> sender PoP :
       --> confidential client: [code_verifier (PKCE)  AND [
private_key_jwt XOR mTLS ] ]
       --> public client:  code_verifier (PKCE) AND ?

refresh_token :
  -> sender : Client
  -> consumer : AS
  -> sender PoP :
       --> confidential client: private_key_jwt, mTLS
       --> public client:  DPoP AND ?

access_token :
  -> presenter : Client
  -> consumer : RS
  -> sender PoP :
       --> confidential client: private_key_jwt, mTLS
       --> public client:  DPoP AND ?

@Daniel Fett <[email-masked]>  I still have some question marks in
here. Am I missing anything?
-- 
Francis Pouatcha
Co-Founder and Technical Lead at adorys
https://adorsys-platform.de/solutions/

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sun, 7 Jun 2020 19:11:18 +0200

> On 7. Jun 2020, at 16:18, Nov Matake <[email-masked]> wrote:
> 

Seems we need to distinguish certain “kinds” of PoP for code. 

1) private_key_jwt, mTLS and other client secrets can be used to authenticate the client and thus check the binding of the code to a particular client_id.

2) PKCE is different in that it allows to tie the code to a certain transaction running on a certain device. 

(2) detects code replay at the same client_id on a different device, (1) does not. 

Regarding PoP for access tokens: private_key_jwt does not provide this capability. mTLS and DPoP provide it for both confidential and public clients.

---

From: Brian Campbell <[email-masked]>
Date: Tue, 9 Jun 2020 15:33:49 -0600

I don't follow the reasoning about all resource servers needing to be
updated to support the new scheme before deployment could start.  Given how
6750, JWT and Introspection define things (basically as extensible with
unrecognized stuff to be ignored) , I would expect that a existing regular
RFC 6750 protected resource with no knowledge of DPoP would almost
certainly accept a dpop/jkt bound access token as though it was a bearer
token. The definition of the DPoP token_type would prescribe sending the
access token with the DPoP authorization scheme in conjunction with the
DPoP header but also say that, if that was met with a 401 WWW-Authenticate:
Bearer challenge (or the client had prior such knowledge about the RS),
that the access token could be sent using the Bearer authorization scheme.
And would work as such. There may well be some existing protected resources
that wouldn't accept a dpop/jkt bound access token but I'd say they'd be
operating erroneously and I would think it'd be a pretty small minority -
DPoP not defining a new token_type wouldn't change that situation at all
anyway. In fact, from the perspective of interoperability on roll out, I
don't see how DPoP defining a new token_type or not changes anything.
Things look a little more intentional with a new token type and auth scheme
and there might be an additional 401 challenge at first with a Bearer only
RS but I don't see how the actual inerop is any different.

The suggestion/proposal during the interim to signal to the client that the
RT had been bound was indeed to introduce a new token endpoint response
parameter[1]. Although I had an intentionally ridiculous name there to
serve as a placeholder and hopefully avoid bikeshedding the name. I will
say that doing something general (like an rt_token_type) in a specific
extension like DPoP can be pretty problematic so I think it should  need to
be something DPoP specific even if that's a little ugly.

[1] slide #23
https://datatracker.ietf.org/meeting/interim-2020-oauth-09/materials/slides-interim-2020-oauth-09-sessa-dpop.pdf

On Fri, Jun 5, 2020 at 2:17 PM George Fletcher <gffletch=
[email-masked]> wrote:

> roll_out perspective, ALL resource
>
servers must be updated to support the new scheme and only then can the
> DPoP deployment start.
For any wide ecosystem deployment that can be problematic. I don't have any
> great suggestions:(
> bound while leaving the
access_tokens as bearer tokens. This adds useful security without impacting
> existing RS deployments.
It was unclear from our interim meeting discussion how the client knows
> whether the refresh token has
>
been bound to the public key or not. The AS can signal that the
> access_token is NOT bound by
>
returning a token_type of "bearer" but we should think about adding
> addition response fields for
>
the refresh token binding (e.g. "rt_token_type).
> > Apologies for the slow reply on this. No excuses other than life >
> sometimes happens. > > `token_type` is maybe not the clearest extension
> point (and one I've > arguably misused in OAuth MTLS >
> <https://www.rfc-editor.org/rfc/rfc8705.html>
> <https://www.rfc-editor.org/rfc/rfc8705.html> and the now defunct > Token
> Binding > <https://tools.ietf.org/html/draft-ietf-oauth-token-binding-08>
> <https://github.com/danielfett/draft-dpop/issues/41>
> exact kind of thing (for MAC really but it's conceptually > similar in that
> it was an application level proof mechanism of sorts) > . The text from RFC
> 6749 sec 7.1 > <https://tools.ietf.org/html/rfc6749?#section-7.1>
> token_type is the appropriate > thing to do and that it can be defined to
> account and allow for mixed > token type situations. It would define that
> the DPoP authz scheme be > used as the authentication method to include the
> access token when > making a protected resource request. That definition
> can also include > falling back to using the Bearer authz scheme when/if so
> challenged > by a protected resource. > >
> <https://tools.ietf.org/html/rfc6749?#section-7.1>
> <https://tools.ietf.org/html/rfc6749?#section-7.1>
> resource request (along with type-specific attributes). > The client MUST
> NOT use an access token if it does not understand the > token type. > > For
> example, the "bearer" token type defined in [RFC6750 >
> <https://tools.ietf.org/html/rfc6750>
> the access token string in the request: > > GET /resource/1 HTTP/1.1 Host:
> example.com Authorization: Bearer > mF_9.B5f-4.1JqM > > while the "mac"
> token type defined in [OAuth-HTTP-MAC >
> <https://tools.ietf.org/html/rfc6749?#ref-OAuth-HTTP-MAC>
> mac="kDZvddkndxvhGRXZhvuDjEWhGeE=" > > The above examples are provided for
> illustration purposes only. > Developers are advised to consult the
> [RFC6750 > <https://tools.ietf.org/html/rfc6750>
> <https://tools.ietf.org/html/rfc6750>] and [OAuth-HTTP-MAC >
> <https://tools.ietf.org/html/rfc6749?#ref-OAuth-HTTP-MAC>
> specifications before use. > > Each access token type definition specifies
> the additional > attributes (if any) sent to the client together with the >
> "access_token" response parameter. It also defines the HTTP >
> authentication method used to include the access token when making a >
> protected resource request. > > > > On Tue, May 19, 2020 at 7:20 AM Filip
> Skokan <[email-masked]> <[email-masked]> > wrote: > >> This is a
> RE: to yesterday's interim meeting discussion, largely >> related to the
> first rollout step where we want to constrain >> refresh tokens but leave
> protected resource access intact. >> >> I'll start off with a case that I
> hope we can agree is absolutely >> necessary for DPoP to solve - that is
> constraining refresh tokens >> for browser based applications. Now, *do we
> see this as a >> secondary objective? I think it should be on par with
> access token >> constraining.* SPAs using code flow and having access to
> refresh >> tokens as means against the continuous browser efforts to cut
> down >> on storage access is a real case servers will be eventually forced
> >> to adopt. >> >> Since rollout for DPoP needs to begin with the AS and
> Client >> supporting it (regardless what order i guess) there are going to
> be >> instances where the RS will be supporting both Bearer and DPoP at >>
> the same time. >> >> As discussed yesterday, the client shouldn't know/care
> and change >> its behaviour when it comes to using access tokens. >> >>
> *But what is the client behaviour we take for standard?* Because I >> can
> see two conflicting implementations in the wild >> >> 1. The client echoes
> the token_type it received from the token >> endpoint as the authorization
> scheme - (optionally) throws on >> unrecognized token type values 2. The
> client uses Bearer as a fixed >> authorization scheme and ignores the
> token_type it received >> >> #2 is an implementation which I suspect has no
> idea about DPoP, but >> if extended to send DPoP headers (through various
> mechanism - >> library extensions or even manipulating the `XMLHttpRequest`
> >> prototype) will >> >> - 🎉 get the benefit of having its Refresh Tokens
> bound - 🎉 most >> likely continue to work with RSs that only support
> Bearer - ❌ will >> cease to work with RSs that will adopt support for DPoP
> because >> it'll be using the wrong scheme, that is unless (🎉) RSs >>
> supporting DPoP choose to suspend the requirement to use the new >> scheme
> and instead depend on the presence of `cnf.jkt` as means to >> trigger DPoP
> validation. *Q: is that an acceptable thing to do?* >> >> Arguably, client
> behaviour #1 is what a client should be using if >> it supports other
> schemes besides Bearer. But it may as well be the >> behaviour of a client
> that has no clue about DPoP, right? Again, >> such client can be made to
> support DPoP in a SPA through >> manipulation of the XMLHttpRequest
> prototype, in which case the >> developer needs to do the same for the
> protected resource calls. >> But at this point the developer has to know
> which RS to apply DPoP >> to and which not - ergo - which to send Bearer
> vs. DPoP scheme to? >> The developer will have to write a whitelist of
> resource servers >> anyway - and there we get to the point where client has
> >> information and functionality that it shouldn't /need to/ have. >> >>
> Its great that we have token_type, authorization header schemes, >> etc...,
> but we don't seem have a well defined (or at least >> followed) behaviour
> for our clients around handling the token_type >> response values and their
> unless >> the RS definition on the AS is aware of the fact that the RS does
> >> support DPoP, so that the issued token_type is always correct for >> the
> RS. So, *should we make that a recommended way of 'indicating' >> when to
> issue Bearer vs DPoP access tokens?* >> >> What else could we do that
> doesn't give more decision making to >> the clients so that the very first
> step - *Refresh Tokens get >> constrained* - is achieved* but Protected
> Resource access is >> unaffected?* >> >> Note that this was not "a thing"
> for mTLS because it continues to >> use the Bearer scheme (for better or
> worse) and it completely omits >> possible continuous rollout or discussing
> what are the signals the >> RS must use to require mTLS to be used), same
> for the abandoned >> OAuth 2.0 Token Binding draft (also continued to use
> the Bearer >> scheme). >> >> I suspect we have just this opportunity to fix
> rollout of >> real sender constraining mechanism (e.g. http signatures in
> the >> future) and just continue using Bearer because in the end, given >>
> that RSs could be relying on the presence of the cnf claim to >> figure out
> the token's constraining mechanism, would that be such a >> bad thing? >>
> >> Put it the other way around. By introducing Bearer scheme, do we >>
> actually gain anything of value that can't be gained through other >>
> means? >> >> Note that this message didn't start with the goal of
> questioning >> the new scheme use, it just sort of landed there... My
> pedantic >> nature would love to see the new scheme and token_type
> extension >> point used as it was meant to be but I also recognize the many
> >> issues it brings that could be sidestepped by not introducing it in >>
> the first place, all without losing capabilities. >> >> Previous material
> on the topic >> >> - https://github.com/danielfett/draft-dpop/issues/41,
> decision to >> break backwards compatibility amongst the authors - ML >>
> >> thread, in my opinion inconclusive, no consensus >> >> >> S pozdravem,
> *Filip Skokan* >> _______________________________________________ OAuth
> mailing list >> [email-masked] https://www.ietf.org/mailman/listinfo/oauth
> >> > > > _______________________________________________ OAuth mailing list

-- 
_CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
material for the sole use of the intended recipient(s). Any review, use, 
distribution or disclosure by others is strictly prohibited.  If you have 
received this communication in error, please notify the sender immediately 
by e-mail and delete the message and any file attachments from your 
computer. Thank you._

---

From: Justin Richer <[email-masked]>
Date: Wed, 10 Jun 2020 16:32:48 -0400

What if we simply declare that refresh tokens are always bound to the DPoP key used to request them? Is there value in NOT binding the refresh token?

As for access tokens, the way I read it, all of this is true:

- The AS could still decide to issue a Bearer token, using the token_type field, for whatever policy reason.
- A client getting back a Bearer token from a DPoP request would do Bearer headers. 
- A client getting a DPoP token from a DPoP request would do DPoP headers.
- An client should never send a DPoP token as a Bearer header.
- An RS should ALWAYS look for a DPoP binding signature from a DPoP scheme token. Missing that is an error.

So if we just declare that a refresh token must always be DPoP bound when DPoP is used to request it and a refresh token is issued, then we’re in the clear here, as best as I can tell, and it allows the AS some flexibility.

Some problems with this:

1) Pretty much every single OAuth client in the world ignores the “token_type” field. But clients being updated to support DPoP wouldn’t ignore it, so that’s probably ok.
2) If we wanted to make refresh token binding switchable we’d need a “refresh_token_type” field or similar, and the client would need to know how to understand it and deal with its absence (since most servers won’t send it).
3) This presumes the client will not rotate its key before using the refresh token. If it does it’ll have to do a whole new grant.
4) None of this prevents an RS from ignoring the DPoP signature, but I think that’s a separate problem.
5) It’s arguable that we’d want a client to be able to bind a NEW DPoP key during a refresh, using the old key as proof for the refresh token and the new key going forward. Is this a case we want to enable?

 — Justin

> On Jun 7, 2020, at 3:22 AM, Torsten Lodderstedt <torsten=[email-masked]> wrote:
>

---

From: Francis Pouatcha <[email-masked]>
Date: Wed, 10 Jun 2020 19:35:38 -0400

On Wed, Jun 10, 2020 at 4:32 PM Justin Richer <[email-masked]> wrote:

> What if we simply declare that *refresh tokens are always bound to the
> DPoP key* used to request them? Is there value in NOT binding the refresh
> token?
>
> Fully agree. I will add a *refresh_token shall always be PoP bound*.
Independent of the type of PoP.

> So if we just declare that a refresh token must always be DPoP bound when
> DPoP is used to request it and a refresh token is issued, then we’re in the
> clear here, as best as I can tell, and it allows the AS some flexibility.
>
> Some problems with this:
>
> 1) Pretty much every single OAuth client in the world ignores the
> “token_type” field. But clients being updated to support DPoP wouldn’t
> ignore it, so that’s probably ok.
> 2) If we wanted to make refresh token binding switchable we’d need a
> “refresh_token_type” field or similar, and the client would need to know
> how to understand it and deal with its absence (since most servers won’t
> send it).
> 3) This presumes the client will not rotate its key before using the
> refresh token. If it does it’ll have to do a whole new grant.
> 5) It’s arguable that we’d want a client to be able to bind a NEW DPoP key
> during a refresh, using the old key as proof for the refresh token and the
> new key going forward. Is this a case we want to enable?
>
Key rotation shall be handled separately from the refresh_token process. If
a refresh_token is bound to a key, the client shall keep that key till the
refresh_token is consumed. A key rotation process shall be designed such as
to allow the key holder to keep obsolete keys for the completion of pending
processes.

>
>  — Justin
>
> On Jun 7, 2020, at 3:22 AM, Torsten Lodderstedt <
> torsten=[email-masked]> wrote:
>
> For a public client, the refresh token is just bound to the client id.
> DPoP allows binding to an ephemeral key pair for this kind of clients.
>
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Thu, 11 Jun 2020 08:36:16 +0200

I generally agree with the proposal, but I would suggest to limit it to public clients. 

In case of confidential clients, the refresh token is (via the client_id) already bound to the client’s secret(s) and those can be rotated. Additionally binding the refresh token to a DPoP key would limit it’s applicability w/o a benefit. 

> On 11. Jun 2020, at 01:35, Francis Pouatcha <[email-masked]> wrote:
> 
> 
> Fully agree. I will add a refresh_token shall always be PoP bound. Independent of the type of PoP.
>  
> Key rotation shall be handled separately from the refresh_token process. If a refresh_token is bound to a key, the client shall keep that key till the refresh_token is consumed. A key rotation process shall be designed such as to allow the key holder to keep obsolete keys for the completion of pending processes.
> 
>  — Justin
>

---

From: Neil Madden <[email-masked]>
Date: Thu, 11 Jun 2020 08:26:20 +0100

+1

> On 11 Jun 2020, at 07:36, Torsten Lodderstedt <torsten=[email-masked]> wrote:
>

---

From: Francis Pouatcha <[email-masked]>
Date: Thu, 11 Jun 2020 13:24:34 -0400

> >
> > In case of confidential clients, the refresh token is (via the
> client_id) already bound to the client’s secret(s) and those can be
> rotated. Additionally binding the refresh token to a DPoP key would limit
> it’s applicability w/o a benefit.
>
I meant *PoP* and not *DPoP*. The client secret is also a variant of PoP.
This does not change the value of this sentence: "*refresh_token shall
always be bound to a PoP*".

---

From: Torsten Lodderstedt <[email-masked]>
Date: Thu, 11 Jun 2020 19:51:16 +0200

> On 11. Jun 2020, at 19:24, Francis Pouatcha <fpo=[email-masked]> wrote:
> 
> 
> 
> On Thu, Jun 11, 2020 at 3:26 AM Neil Madden <[email-masked]> wrote:
> +1
> 
> I meant PoP and not DPoP. The client secret is also a variant of PoP. This does not change the value of this sentence: "refresh_token shall always be bound to a PoP".

This means you agree DPoP shall be used for refresh tokens issued to public clients only? As you said, client authentication is a kind of PoP as well, so confidential clients don’t need DPoP protection for refresh tokens.

---

From: Brian Campbell <[email-masked]>
Date: Thu, 11 Jun 2020 15:17:10 -0600

The current draft (draft-ietf-oauth-dpop-01) does say that when a valid
DPoP proof is presented and refresh token is issued to a public client, the
refresh token must be bound to the DPoP key. So that part is already
covered in the document. And, for whatever it's worth, that pretty closely
mirrors how it works with MTLS, public clients, and RTs. If there are
specific suggestions as to how to make it more clear, they'd of course be
welcome.

The text in draft does need to be updated to better account/allow for, as
Justin said, the "AS could still decide to issue a Bearer token, using the
token_type field, for whatever policy reason." I'd sort of thought it
already did and it was the intent but, on reading again, there's definitely
some text that needs to be fixed. That should help better facilitate mixed
or rollout deployments by letting the AS decide to bind ATs or not based on
resource or scope requested or other policy.

Also to help facilitate mixed or rollout deployments, I'm not sure about
"An client should never send a DPoP [bound access] token as a Bearer
header."  Such a constraint could be put on the client but it seems
unhelpful. A bad acting client could easily ignore it and I'm not sure what
it accomplishes if/when followed. Following from
https://github.com/danielfett/draft-dpop/issues/58 the draft needs to be
updated to say explicitly that an RS supporting both Bearer and DPoP
schemes simultaneously needs to update its Bearer token evaluation
functionality so as to reject tokens that are dpop bound. But the draft
can't really impose anything on existing RSs supporting only Bearer (and
unaware of DPoP). And such RSs will most likely accept a DPoP bound AT when
send via the Bearer scheme (JWT says to ignore unrecognized claims,
introspection says other parameters might be present, and 6750 is basically
silent on the content of the AT, which is where the binding is carried).
This admittedly doesn't seem quite right. But there's nothing this draft
can realistically do about it. And I think it can help with mixed or
rollout deployments. Especially those where sufficient information about
what RS(s) the requested token is for are not available in the token
request for whatever reason. Currently the draft is silent about it and
maybe that's as it should be. But I'm suggesting in a few messages on this
thread that the definition of the DPoP token_type would prescribe sending
the access token with the DPoP authorization scheme in conjunction with the
DPoP header but also say that, if that was met with a 401 WWW-Authenticate:
Bearer challenge by a particular RS (or the client had prior such knowledge
about the RS), that the access token could be sent using the Bearer
authorization scheme.

It is correct that, as currently written in the draft, a public client with
a DPoP bound refresh token will have to use the same key for the lifetime
of the grant. That seemed like a good tradeoff vs. defining a mechanism for
key rotation for the public client refresh token case where two proofs (one
to verify the binding for the RT being sent and one to newly bind the RT
to) would be presented on refresh grant type request. I tend to think where
it is now hits the right balance in functionality and complexity. But if
there are strong beliefs otherwise, let's discuss the need and cost/benefit
and all that.

On Thu, Jun 11, 2020 at 1:26 AM Neil Madden <[email-masked]>
wrote:

> >> What if we simply declare that refresh tokens are always bound to the
> DPoP key used to request them? Is there value in NOT binding the refresh
> token?
> >>
> >> - The AS could still decide to issue a Bearer token, using the
> token_type field, for whatever policy reason.
> >> So if we just declare that a refresh token must always be DPoP bound
> when DPoP is used to request it and a refresh token is issued, then we’re
> in the clear here, as best as I can tell, and it allows the AS some
> flexibility.
> >>
> >> Some problems with this:
> >>
> >> 5) It’s arguable that we’d want a client to be able to bind a NEW DPoP
> key during a refresh, using the old key as proof for the refresh token and
> the new key going forward. Is this a case we want to enable?
> >> Key rotation shall be handled separately from the refresh_token
> process. If a refresh_token is bound to a key, the client shall keep that
> key till the refresh_token is consumed. A key rotation process shall be
> designed such as to allow the key holder to keep obsolete keys for the
> completion of pending processes.
> >>
> >> — Justin
> >>

---

From: Daniel Fett <[email-masked]>
Date: Fri, 12 Jun 2020 17:10:39 +0200

Am 11.06.20 um 23:17 schrieb Brian Campbell:
>
> Also to help facilitate mixed or rollout deployments, I'm not sure
> about "An client should never send a DPoP [bound access] token as a
> Bearer header."  Such a constraint could be put on the client but it
> seems unhelpful. A bad acting client could easily ignore it and I'm
> not sure what it accomplishes if/when followed. Following from
> https://github.com/danielfett/draft-dpop/issues/58 the draft needs to
> be updated to say explicitly that an RS supporting both Bearer and
> DPoP schemes simultaneously needs to update its Bearer token
> evaluation functionality so as to reject tokens that are dpop bound.
> But the draft can't really impose anything on existing RSs supporting
> only Bearer (and unaware of DPoP). And such RSs will most likely
> accept a DPoP bound AT when send via the Bearer scheme (JWT says to
> ignore unrecognized claims, introspection says other parameters might
> be present, and 6750 is basically silent on the content of the AT,
> which is where the binding is carried). This admittedly doesn't seem
> quite right. But there's nothing this draft can realistically do about
> it. And I think it can help with mixed or rollout deployments.
> Especially those where sufficient information about what RS(s) the
> requested token is for are not available in the token request for
> whatever reason. Currently the draft is silent about it and maybe
> that's as it should be. But I'm suggesting in a few messages on this
> thread that the definition of the DPoP token_type would prescribe
> sending the access token with the DPoP authorization scheme in
> conjunction with the DPoP header but also say that, if that was met
> with a 401 WWW-Authenticate: Bearer challenge by a particular RS (or
> the client had prior such knowledge about the RS), that the access
> token could be sent using the Bearer authorization scheme.
I would support that.
>
> It is correct that, as currently written in the draft, a public client
> with a DPoP bound refresh token will have to use the same key for the
> lifetime of the grant. That seemed like a good tradeoff vs. defining a
> mechanism for key rotation for the public client refresh token case
> where two proofs (one to verify the binding for the RT being sent and
> one to newly bind the RT to) would be presented on refresh grant type
> request. I tend to think where it is now hits the right balance in
> functionality and complexity. But if there are strong beliefs
> otherwise, let's discuss the need and cost/benefit and all that.

Absolutely agree. We would create a lot of complexity for very little gain.

-Daniel

-- 
https://danielfett.de