Re: [OAUTH-WG] New Version Notification for draft-fett-oauth-dpop-03.txt

Brian Campbell <> Thu, 21 November 2019 06:23 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id A61D61200FB for <>; Wed, 20 Nov 2019 22:23:35 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.988
X-Spam-Status: No, score=-1.988 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_KAM_HTML_FONT_INVALID=0.01, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id WTYFQ4rAVDPC for <>; Wed, 20 Nov 2019 22:23:31 -0800 (PST)
Received: from ( [IPv6:2a00:1450:4864:20::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id DEA5D12009C for <>; Wed, 20 Nov 2019 22:23:30 -0800 (PST)
Received: by with SMTP id p18so1850475ljc.6 for <>; Wed, 20 Nov 2019 22:23:30 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=/KlDYCv1RyIw1ZsZcBGvCK47jA3tGQ/rEOOnhkBiGNw=; b=P5Z55k4KNV+5NrsFG9T5RIsa65h6K5vfH21BTmVtUmo+hhW4VjSCRoNqJOQeKBhBg7 /CsdoD4N9KJ+lN6y6mxmPEt6Gw9wrDQ9JRbrIZGy8IJ3Xa78ZYm5MnyejAKukYeqFNUD sSYTtI/DNLJUUlSHsOJBu62+RPBKLLtoTgz7yXjMmyT4P/aunVzs3iIYY8urXLV4lxeW tN780k/zjo9CC+vmv+KDxMpvLjQUgVfBltJ+3Dnz2ML4XijBjmuHCXW0rnqRipnCmEct YM597TxUSewXXv2c/H70tNhu3akyXB+5/g650W3fPfxPXhoOoliTRnKhjx+SEf8TNYpT jqow==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=/KlDYCv1RyIw1ZsZcBGvCK47jA3tGQ/rEOOnhkBiGNw=; b=UBe4ZhiYyc4s7P5zPf7Uog+sxvMwL+qhY8yWwjf6weUEFRw0yXNwN3GvWUE+sIZu/E JOh+JytxRbmF4ink5XtgTYikVYzfXEkpHkEfXqXitpnZsmsatppIQuVv5nCZQQ4HdX/6 vaij2XdMzeeOeFFbP4mTYHtofmY6J19NyjozCYl1cMjFiSEwCKSdbyG9nd0699Ygmt34 Vgc/al2Lj5PTqYm1LtCLvRAs3rTedjl6/wvomjO3J/JzKiF10RV69AWJ3obpMOu2SjhJ JcDmnnnyTlMKIrWFmHVWK9/S2+aO96VtL2X7hcM81vop8JSpGg/atglf1naEo6HaEmaP tJUw==
X-Gm-Message-State: APjAAAXHeI3IXqHmuw4aJGtPJBxT/4uY3e/wCYbsJo+nmxoAl2foy8pM wHXbSLxJUu+BR/RvwG80HjCs6/YCdXxjNeeHE6+JpuYTxBokHO8SobH9U/jJlYG3bxCK6VMO5dz DZUrZGcxn6q+eFNASk8g=
X-Google-Smtp-Source: APXvYqyAIt8DD70Smd63MHIEnTgQsJqqzTg4TeASPE6jTy7ud5jLKtwhqQgyJ2O51SfSMUYmK0mMNcoI4X9kuN3ylOY=
X-Received: by 2002:a2e:5451:: with SMTP id y17mr5722772ljd.98.1574317408840; Wed, 20 Nov 2019 22:23:28 -0800 (PST)
MIME-Version: 1.0
References: <> <> <> <> <>
In-Reply-To: <>
From: Brian Campbell <>
Date: Thu, 21 Nov 2019 14:23:01 +0800
Message-ID: <>
To: Neil Madden <>
Cc: oauth <>
Content-Type: multipart/alternative; boundary="000000000000eb1c270597d5555f"
Archived-At: <>
Subject: Re: [OAUTH-WG] New Version Notification for draft-fett-oauth-dpop-03.txt
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 21 Nov 2019 06:23:36 -0000

Yeah, suggestions and/or an MTI about algorithm support would probably be
worthwhile. Perhaps also some defined means of signaling when an
unsupported algorithm is used along with any other reason a DPoP is invalid
or rejected.

There are a lot of tradeoffs in what claims are required and what
protections are provided etc. The aim of what was chosen was to do just
enough to provide some reasonable protections against reuse or use in a
different context while being simple to implement and deploy.

On Wed, Nov 20, 2019 at 6:34 AM Neil Madden <>

> Thanks for the reply, Brian.
> Collecting my thoughts up here rather than responding blow by blow.
> Public key signatures are simpler in some respects, more complex in
> others. There are currently 10 public key JWS signature schemes defined
> (ES256/384/512, RS256/384/512, PS256/384/512, EdDSA) - does an RS
> potentially have to support them all? If not, how do they negotiate
> algorithm support with the client?
> On the other hand, the ECDH scheme I proposed can be implemented by
> adapting an existing ECDH-ES encryption support in a JWT library. For
> example, I discovered while playing with this that our own internal library
> can implement the full flow I described entirely via the existing public
> API [1], so it's not necessarily as complex as it first looks. I even
> knocked up a from-scratch implementation in WebCrypto (JavaScript) without
> too much code [2].
> But I admit that using an existing JWT library to sign a JWT with an
> existing algorithm is even easier, and that counts for a lot. Perhaps we
> can make concrete suggestions/requirements about algorithm support? e.g.
> "The RS MUST support RS256 and SHOULD support EdDSA. Other algorithms MAY
> be supported."
> With regards to replay protection, I think there are at least two
> reasonable positions:
> 1. We assume that TLS is secure and don't try to defend against any
> compromise at that level. (Clearly none of the TLS-based PoP mechanisms
> survive if TLS is compromised, by definition). In this case the main attack
> to defend against is a malicious RS replaying the access token elsewhere.
> Simply signing the origin of the RS would be enough to prevent this attack,
> while letting the client reuse the same JWT for many requests (and the RS
> to cache the JWT validation). None of "jti", "htu", or "htm" seem relevant
> to this model.
> 2. We don't assume that TLS is secure (or it's not fully end-to-end) and
> try to provide some defense in depth against a MitM attacker replaying a
> token against the same RS. There is a graduated series of steps you can
> take here, depending on how much you want to prevent this:
>    a. The DPoP token can be replayed for arbitrary requests to the same RS
> but has a short time limit (e.g., exp claim or RS-enforced max lifetime
> from iat)
>    b. The DPoP token can be replayed for the same request (htu/htm claims)
>    c. The DPoP token can't be replayed at all - either because of jti
> blacklisting on the RS or a challenge-response protocol on each request.
> (There are also variants such as including a hash of the request
> body/headers, or encoding an ETag into the JWT).
> I think either are reasonable design goals, but aiming for 2 adds more
> value. I think aiming for 2a is a reasonable default baseline that allows
> the client to reuse a DPoP token for a few requests, reducing the cost of
> the signature (and the RS can cache the validated JWT). Support for 2b or
> 2c can then be listed as optional additions.
> PS - 2a/2b can be achieved without PoP. I'll save that for another email
> in the next few days though.
> [1]:
> [2]:
> -- Neil
> On 19 Nov 2019, at 07:43, Brian Campbell <>
> wrote:
> On Thu, Nov 14, 2019 at 7:20 PM Neil Madden <>
> wrote:
>> I can't attend Singapore either in person or remotely due to other
>> commitments. I broadly support adoption of this draft, but I have some
>> comments/suggestions about it.
> Thanks Neil. And sorry to hear that you won't be in Singapore. This kind
> of stuff is definitely more easily discussed in person (for me anyway). But
> I'll try and comment on your comments here as best I can. I also plan to
> also mention them in the Wednesday and/or Thursday presentation.
>> Section 2 lists the main objective as being to harden against
>> compromised/malicious AS or RS, which may attempt to replay captured tokens
>> elsewhere. While this is a good idea, a casual reader might wonder why a
>> simple audience claim in the access token/introspection response is not
>> sufficient to prevent this. Because interactions between the client and RS
>> are supposed to be over TLS, is the intended threat model one in which
>> these protections have broken down? ("counterfeit" in the description
>> suggests this). Or is the motivation that clients want to get a single
>> broad-scoped access token (for usability/performance reasons) and use it to
>> access multiple resource servers without giving each of them the ability to
>> replay the token to the other servers? Or are we thinking of a
>> phishing-type vulnerability were a general-purpose client might
>> accidentally visit a malicious site which prompts for an access token that
>> the client then blindly goes off and gets? (UMA?) It's not clear to me
>> which of these scenarios is being considered, so it would be good to
>> tighten up this section.
> It is admittedly a bit loose and I agree it'd be good to tighten it up.
> But part of why it's loose is that it tries to offer some protections for
> all those scenarios and more such as a general lost/stolen token. It's
> effectively trying to provide as many of the same types of
> protections/assurances that you'd get with TLS based PoP mechanisms (like
> OAuth MTLS or Token binding) to the extent that can be done at the HTTP
> application layer. Which can't realistically be exactly the same but can
> maybe be kinda close while actually being accessible and implementable
> because it's all done at the application layer. There are trade-offs, of
> course, and the document writers have endeavored to find a good balance in
> the trade-off decisions we've made. But that doesn't mean they are
> necessarily the right decisions or are closed to discussion. To the casual
> reader I would say that it turns out that getting an appropriate simple
> audience claim into an access token isn't nearly as simple as it might
> seem. And while it will prevent RS to RS replay (as long as both RSs aren't
> legit audiences) it doesn't help with preventing the use of tokens stolen
> or leaked by other means (including for refresh tokens issued to public
> clients).
>> Another potential motivation is for mobile apps. Some customers of ours
>> would like to tie access/refresh tokens to private key material generated
>> on a secure element in the device, that can only be accessed after local
>> biometric authentication (e.g. TouchID/FaceID on iOS). I have suggested
>> using mTLS cert-bound tokens for this, but have heard some pushback due to
>> the difficulty of configuring support for client certs across diverse
>> infrastructure. A simple JWT-based solution like DPoP could fill this need.
> It's maybe not stated in the draft but this kind of thing is among the
> objectives (in my mind anyway).
>> My main concerns with the draft though are about efficiency and
>> scalability of the proposed approach:
>> 1. The requirement to use public key signatures, along with the
>> anti-replay nonce, means that the RS is required to perform an expensive
>> signature verification check on every request. That is not going to scale
>> up well. While there are more efficient schemes like Ed25519 now, these are
>> still typically an order of magnitude slower than HMAC and the latency and
>> CPU overhead is likely to be a non-starter for many APIs (especially when
>> you're billed by CPU usage). Public key signatures are also notoriously
>> fragile (see e.g. the history of nonce reuse/leakage vulnerabilities in
>> ECDSA or
> Yes, asymmetric is more processing intensive than symmetric. But if you
> take away the distributed replay check (see next response), it will scale
> out just fine. I'm not so sure latency is a real issue here - while these
> operations are an order of magnitude slower we're still talking about times
> that are not perceptible to a human. CPU usage/cost is a part of a
> trade-off for the simplicity afforded by public/private keys.  And it is
> significantly simpler. The design you sketched out is admittedly quite
> clever but it's not even in the same ballpark with respect to complexity.
> And, as you pointed out, the other suggestion around symmetric keys has
> rather different security properties while still adding complexity. Adding
> symmetric key support isn't something that can just be added on easily.
>> 2. The advice for the RS to store a set of previously used nonces to
>> prevent replay will also hamper scalability, especially in large
>> deployments where such state would need to be replicated to all servers (or
>> use sticky load balancing, which comes with its own problems). This
>> violates the statelessness of HTTP, and it also potentially breaks
>> idempotency of operations: Think of the case where the JWT validation and
>> replay protection is done at an API gateway but then the call to the
>> backend API server fails for a transient reason. The client (or a
>> proxy/library) cannot simply replay the (idempotent) request in this case
>> because it will be rejected by the gateway. It must instead recreate the
>> DPoP JWT, incurring additional overheads.
> The actual value of replay checking on jti is somewhat questionable. The
> DPoP JWT only transits between client and server so a TLS MITM is likely
> needed to steal a DPoP JWT. But we are assuming TLS works here. And an
> active MITM could thwart this check by just being first to present DPoP
> JWT. I think the jti check made its way into the draft mostly because it
> seemed like something was needed to try and bring it closer to the TLS PoP
> models. Being aware of the scalability concerns, I did endeavor to write
> the text in such a way so as to leave some wiggle room in
> implementations/deployments with text like '"jti" SHOULD be used by the
> server for replay detection and prevention` and [ensure that] 'within a
> reasonable consideration of accuracy and resource utilization, a JWT with
> the same "jti" value has not been received previously'. The idea being that
> using something eventually consistent or even local only to the runtime
> instance would be permissible. Perhaps that allowance and the rational
> could be made more clear? Or would you suggest to do away with the jti
> replay stuff al? Or something else?
>> 3. Minor: The use of a custom header for communicating the DPoP proof
>> will require additional CORS configuration on top of that already done for
>> the Authorization header, and so adds a small amount of additional friction
>> for adoption. Given that CORS configuration changes often require approval
>> by a security team, this may make more of an impact than you'd expect.
> Feels really minor. I mean, we could try to roll everything up under one
> header. But it does seem unwarranted and would complicate things - at least
> in the model we've got now where the proof is sent the same way ono all
> types of requests.
> It's also not clear to me exactly what threat the anti-replay nonce is
>> protecting against. It does nothing against the replay scenario discussed
>> in section 2, as I understand it - which really seems to be more of a MitM
>> scenario. Given that the connection between the client and the RS is
>> supposed to be over TLS, and TLS is already protected against replay
>> attacks, I think this part needs to be better motivated given the obvious
>> costs of implementing it.
>> I have a tentative suggestion for an alternative design which avoids
>> these problems, but at a cost of potentially more complexity elsewhere.
>> I'll summarise it here for consideration:
>> 1. The client obtains an access token in the normal way. When calling the
>> token endpoint it provides an EC/okp public key as the confirmation key to
>> be associated with the access/refresh tokens.
>> 2. The first time the client calls an RS it passes its access token in
>> the Authorization: Bearer header as normal. (If the RS doesn't support DPoP
>> then this would just succeed and no further action is required by the
>> client - allowing clients to opportunistically ask for DPoP without needing
>> a priori knowledge of RS capabilities).
>> 3. The RS introspects the access token and learns the EC public key
>> associated with the access token. As there is no DPoP proof with the access
>> token, the RS will generate a challenge in the following way:
>>     o The RS generates an ephemeral EC key pair for the same curve as
>> the confirmation key (e.g. P-256 or X25519).
>>     o The RS stores the ephemeral private key somewhere, associated with
>> this access token (see below for a scalable implementation choice)
>>     o The RS encodes the ephemeral public key into a JWK (epk) and
>> base64url-encodes it. It uses this as a challenge to the client by sending
>> back a 401 response with WWW-Authenticate: DPoP <encoded-epk>
>> 4. The client decodes the epk challenge and performs an ECDH key
>> agreement between its private key and the challenge epk as per the method
>> described for the existing JWA ECDH-ES encryption algorithm. Rather than
>> deriving an AES key however, it derives a HMAC key for HS256. The "apu"
>> value is set to the access token (string value as ASCII bytes) and the
>> "apv" value is set to the hostname of the RS (e.g. "").
>> This ensures that the derived key is cryptographically bound to the context
>> in which it is used.
>> 5. The client uses the HMAC key to create a DPoP proof JWT much like the
>> one in the current draft, but signed using the HS256 key. If a "kid" field
>> was present in the challenge JWK sent by the RS then the same value MUST be
>> used in the "kid" header of this discharge JWT. It retries its original
>> request sending Authorization: DPoP <hmac-jwt> at=<access_token>.
>> 6. The RS uses its stored ephemeral private key to derive the same HMAC
>> key and verify the DPoP discharge JWT. If it validates and all fields are
>> correct then the request is allowed.
>> Efficient implementation trick:
>> Because the client is required to copy and "kid" value from the challenge
>> JWK, the RS can preemptively carry out the ECDH key agreement immediately
>> and generate the derived HMAC key. The RS can then encrypt this derived key
>> using a local authenticated encryption key (e.g. AES-GCM) and use that
>> encrypted value as the "kid" value in the challenge (perhaps along with
>> some context or an expiry time). That way the RS only needs to decrypt this
>> kid value rather than performing the ECDH key agreement on every request.
>> This also avoids the need for the RS to store any per-client state locally.
>> The challenge-response nature of the scheme prevents traditional replay
>> attacks in the case where a DPoP discharge JWT is accidentally leaked
>> through server logs or some other flaw, without needing to store nonces on
>> the server. Using the RS's hostname in the key derivation process prevents
>> mitm attacks in a similar way to how FIDO/WebAuthn prevents this. Most
>> importantly, once a HS256 key has been derived between a client and RS they
>> can reuse that key for multiple requests, reducing the overhead of the ECDH
>> key agreement step. Either side can decide as a matter of policy how long
>> to let this occur and when to trigger a fresh challenge-response.
>> Because this fits within the standard HTTP authentication framework, it
>> also requires no additional CORS configuration and is relatively easy to
>> plug in to existing HTTP client libraries.
>> The main downside of this approach to me is the fact that you can't
>> simply reuse an existing JWT library to implement it, and so it will take
>> time for client libs to develop. (Although I think this might be achievable
>> now with existing *COSE* libraries). This would increase the risk of people
>> hand-rolling solutions, rather than using well-tested libraries. On the
>> other hand, it uses fairly widely supported primitives so e.g. an
>> implementation using WebCrypto is probably only a few dozen lines of code.
>> -- Neil
>> On 31 Oct 2019, at 19:20, Brian Campbell <
>>> wrote:
>> Hello WG,
>> Just a quick note to let folks know that -03 of the DPoP draft was
>> published earlier today. The usual various document links are in the
>> forwarded message below and the relevant snippet from the doc history with
>> a summary of the changes is included here for convenience.
>> Hopefully folks will have time to read the (relativity) short document
>> before the meeting(s) in Singapore where (spoiler alert) I plan to ask that
>> the WG consider adoption of the draft.
>> Thanks,
>>  -03
>>    o  rework the text around uniqueness requirements on the jti claim in
>>       the DPoP proof JWT
>>    o  make tokens a bit smaller by using "htm", "htu", and "jkt" rather
>>       than "http_method", "http_uri", and "jkt#S256" respectively
>>    o  more explicit recommendation to use mTLS if that is available
>>    o  added David Waite as co-author
>>    o  editorial updates
>> ---------- Forwarded message ---------
>> From: <>
>> Date: Thu, Oct 31, 2019 at 11:53 AM
>> Subject: New Version Notification for draft-fett-oauth-dpop-03.txt
>> To: Torsten Lodderstedt <>et>, Michael Jones <
>>>gt;, John Bradley < <>>,
>> Brian Campbell <>om>, David Waite <
>>>gt;, Daniel Fett <>
>> A new version of I-D, draft-fett-oauth-dpop-03.txt
>> has been successfully submitted by Brian Campbell and posted to the
>> IETF repository.
>> Name:           draft-fett-oauth-dpop
>> Revision:       03
>> Title:          OAuth 2.0 Demonstration of Proof-of-Possession at the
>> Application Layer (DPoP)
>> Document date:  2019-10-30
>> Group:          Individual Submission
>> Pages:          15
>> URL:
>> Status:
>> Htmlized:
>> Htmlized:
>> Diff:
>> Abstract:
>>    This document describes a mechanism for sender-constraining OAuth 2.0
>>    tokens via a proof-of-possession mechanism on the application level.
>>    This mechanism allows for the detection of replay attacks with access
>>    and refresh tokens.
>> Please note that it may take a couple of minutes from the time of
>> submission
>> until the htmlized version and diff are available at
>> The IETF Secretariat
>> *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.*_______________________________________________
>> 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.*

_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._