Hi Neil,

thanks for the detailed review. Here are my thoughts:

*1.* DPoP exists because TLS alone was judged insufficient to protect access tokens in real deployments. We're applying the same reasoning to the request the token authorizes. TLS termination at DDoS protection or corporate proxies is a deployment reality. The difference from HttpSig is that a terminating proxy gets full read/write access under TLS, but cannot forge a signature. Stripping it doesn't help either, because the AS/Credential Issuer requires it. The motivating payloads (holder keys and key attestations in OpenID4VCI proofs) aren't secret, so confidentiality isn't my concern. The attack is substituting them so the credential is bound to an attacker-controlled key, so integrity is the property at stake. Where additional confidentiality is needed, OpenID4VCI provides options for application-level encryption, but that's debatable. The signature is verified where the request is semantically consumed, i.e. the Credential Issuer endpoint. The issuer's internal decomposition is its own trust domain, which is the same scoping as DPoP.

*2.* One of the ideas here is that you may want to bind an RT to a different key (e.g. HSM) than an AT.

*3/4.* I'm working in regulated industries, where usage of HSM is mandatory, loading private keys in memory is simply not allowed. RFC 9449 doesn't require a server to return |DPoP-Nonce| on a proof-less request, and doesn't mandate error precedence, so clients can't rely on this interoperably. The AS may simply return an |invalid_request|, and not return a nonce. It also only covers the first request: on nonce rotation, the client discovers expiry only through a failed signed request.

Best regards,

Paul

On 9/23/26 2:53 PM, Neil Madden wrote:
Hi Paul,

Thanks for sharing this slide deck. I think it would be useful if some of this rationale was summarised into the draft introduction, so that it is clear to readers what problems the new proposal is intended to solve.

I summarise your arguments as follows:

 1. DPoP doesn't protect the contents of HTTP messages, such as public
    keys in OpenID4VCI proofs.
 2. DPoP doesn't protect refresh tokens for confidential clients, and,
    when it is used for (public client) RTs it uses the same key as
    for ATs.
 3. Nonce negotiation requires an additional roundtrip with a "wasted
    signature" to retrieve an initial/updated nonce. This is
    potentially expensive in time and money especially for HSM-backed
    signing keys.
 4. The HTTP 400 status code when requiring a nonce is confusing and
    leads to broken client logic.


My responses to these issues are as follows:

1. The need to protect message bodies:

The cited need for this is to protect against active attackers "after TLS termination". I would firstly question why OAuth needs to address what clearly appears to be architectural defict. If the payload needs protection "after TLS termination" then why has TLS been terminated prematurely? (And what would prevent HttpSig also being terminated similarly prematurely at some middlebox?).

Why only protect integrity? TLS also protects confidentiality, and that protection is also being lost by this early termination. I fear that if we approve this approach, then it's only a matter of time before somebody then claims that confidentiality also needs to be protected downstream of TLS termination. Signatures are no help at all with that.

There is also the question of what happens even further downstream. TLS termination is presumably being done at a gateway which is then forwarding the request un-altered. But what happens when it then hits eg a frontend service and results in N new requests to backend microservices, each request slightly different (but perhaps including sensitive details from the original)? All those requests would also need protection under your rationale, but neither DPoP nor HttpSig can address that, being point-to-point solutions rather than end-to-end. Either you need to go back to properly configuring TLS where it is needed (perhaps via a service mesh), or else design a solution that does work end-to-end.

Finally, as already noted, using a non-repudiable signature over the entire HTTP body is using a sledgehammer to crack a nut, and will have unintended consequences (see my other messages in this thread).

2.
i. No DPoP for Confidential Client RTs

I don't really understand this problem. As the DPoP RFC notes, RTs for confidential clients are already sender-constrained, so what is the problem?

ii. Using the same key for RTs and ATs

Again, what is the problem here? There's nothing inherently bad about using the same key to sign DPoP proofs for ATs and RTs. What threat model are you trying to address?

3. Nonce negotiation is expensive.
4. Nonce negotiation using 400 status is annoying.

I don't disagree with this. I don't particularly love the DPoP nonce negotiation. (A long time ago I proposed an alternative based on ECDH key agreement and then the use of a short-term HMAC key instead, but it was rejected by the WG).

IMO the HSM issue is also an architectural problem. After much real-world experience with HSMs and KMSes I have formed the conclusion that you want them out of the hot path of your systems as much as possible: they are a reliability and performance bottleneck. Instead, I always recommend that people follow the approach of Google's Tink cryptography library: use the HSM to decrypt a set of keys on startup/periodically and then use those keys locally rather than calling out the HSM every time. Rotate them regularly mitigate to reduce the risk of compromise. I appreciate this is not always possible, but I've never seen anything but pain from having a direct dependency on a HSM at runtime.

But aren't these issues solved anyway by the client simply not sending a DPoP proof at all in its first request? The server should then respond with a 401 and WWW-Authenticate: DPoP header, and could simply include a DPoP-Nonce header too at that time. No extra overhead for the client, normal 401 return code, and all done in a single roundtrip. This already seems permitted by the spec.

On contrast, the draft being proposed here doesn't support server-generated responses at all, only client-supplied ones. This doesn't address the precomputation attack discussed section 11.2 of RFC 9449, which was the reason for adding nonces in the first place. So this argument doesn't appear to be addressed in any case by the proposed draft.

-- Neil


On 22 Sep 2026, at 20:41, Paul Bastian <[email protected]> wrote:

Hi Warren,

Here is the slide deck from OSW:
https://docs.google.com/presentation/d/1M54dFlaJP0UXeuIpYS3iPDDW3ulmySYP4yStO14SrbE/edit?usp=drivesdk

We asked people at the end of the presentation which direction to go. Nobody supported extending DPoP. 5 people supported the direction of this draft.

Best regards,
Paul
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to