Hello Ashwin,

Thank you for attempting to solve this concern.

When reading the draft, readers might believe that protecting the private key will be sufficient.

   11.11.Private Key Protection

   The security of EPOP depends entirely on the client's private key
   remaining secret.

Unfortunately, while necessary this is insufficient.

If two individuals accept to collaborate, whatever kind of cryptography will be used, *whatever kind of protocol will be used,* a software-only solution will be unable to prevent the transfer of a token from another client to the same RS.

Collaboration really makes sense if the content of the token does not contain a set of attributes that allows the RS to identify the token owner *and* when the unlinkability property for the same RS or between two RSs is supported.

It can also make sense if a token owner is willing to allow another client to impersonate him.

In order to defeat collaboration attacks, for same-device authorization flows, the RS would need to know the characteristics of the hardware device and of the applications used by the individual to perform the access (without, for privacy reasons,being able to uniquely identify the device or the application).

In practice, this mandates the use of a TEE and of TAs whichis an area that has not yet been addressed by the OAuth WG.

Collaboration can also take place for cross-device authorization flows.

The IETF draft draft-ietf-oauth-cross-device-security-16 explores the best current practices: "Cross-Device Flows: Security Best Current Practice".

Section 4.3.10 "Out of Scope“ indicates:

   “ For other attacks, where the user is willingly colludingwith the
   attacker,
   the threat model, security implications and potential mitigations
   are very different”.
      (...)
   This document only considers scenarios where a user does not collude
   with an attacker.

As currently recommended in this IETF draft, a first step would be to mandate a proximity mode of connection between the two devices. A second step would be needed to make sure that both devices are owned by the same person.

A possible solution would be to use biometric controls, but not those currently natively supported by the device which are more a “commodity feature” rather than a “security feature": e.g., it is a common practice to allow
the use of more than one biometric template for face recognition.

At the moment, it looks difficult to fully defeat collusion attacks for cross-device authorization flows, but it looks possible to mitigate them.
This is an area that has not yet been explored.

All these considerations do not appear in section 11 (Security Considerations).

Regards,

Denis

Hi Niel

>While I can see the motivation, IMO the HTTP-specificity of DPoP is an advantage from a security point of view. Otherwise, like this draft, you end up with lots of crucial checks being conditional. Are you suggesting separating drafts by protocols or suggesting that other protocols should not be supported?

>The problem I think you have is that the EPOP proof is wrapping the token ..
>EPOP seems to have the further issue that the proof itself contains ..

The trust establishment pattern you describe as "suspending disbelief" is the same two-phase model used in certificate-based authentication and codified in RFC 9883: a self-asserted public key is presented, the relying party verifies the signature with it (establishing key possession), and authorization of that key is then confirmed via a separate chain check. Nobody considers TLS client certificate authentication problematic on these grounds. EPOP follows the same principle: steps 1–3 establish that the sender holds the private key; step 8 (cnf.jkt cross-check) establishes that the AS authorized that key for the nested credential. These answer different questions and must run in sequence.

On parsing an "untrusted" token: after steps 1–3 pass, the outer token is not unexamined — its signature has been verified. This proves key possession. An attacker who wraps a stolen access token in their own EPOP envelope will pass steps 1–3 but fail step 8, because the cnf.jkt inside the AS-issued nested token does not match their self-generated JWK thumbprint. The AS bound that value at issuance; it is not under attacker control in the resource access flow.

On the cnf.jkt concern: I think there may be a conflation of two distinct flows. In authorization code exchange, cnf.jkt is client-declared (same as client_assertion in RFC 7521), and PKCE provides the complementary binding. In resource access, cnf.jkt is embedded in the AS-issued access token and is not under attacker control — this is the primary token substitution defense. In rotation flow, new cnf.jkt is attested by the previously known EPOP key, which is attested by the underlying refresh token.

On conditionality: DPoP has the same structural characteristic — nonce is optional, ath is conditional on token type. EPOP's validation algorithm in §5 is a strict sequential procedure with explicit normative requirements at each step. I am open to discussion on whether specific conditions in the draft need tighter language.

Regards
Ashwin

On Wed, May 20, 2026 at 1:04 PM Neil Madden <[email protected]> wrote:



    > On 20 May 2026, at 19:52, Ashwin Ambekar <[email protected]> wrote:
    >
    > 
    > Hi Gabriel,
    >
    > There is a broader point that I think gets missed in the ~ vs
    nesting discussion: neither SD-JWT nor DPoP address
    sender-constraining for opaque access tokens across non-HTTP
    transports. SD-JWT requires JWT structure — it has nothing to work
    with for opaque tokens. DPoP handles opaque tokens on HTTP via
    ath, but the htm/htu claims make it HTTP-only. A client holding an
    opaque AT on Kafka, MQTT, or SASL has no sender-constraining path
    under either mechanism.

    While I can see the motivation, IMO the HTTP-specificity of DPoP
    is an advantage from a security point of view. Otherwise, like
    this draft, you end up with lots of crucial checks being conditional.

    >
    > EPOP's ntk treats JWT and opaque tokens identically: the
    credential goes in ntk, the outer envelope provides the proof, and
    validation follows the same path regardless of token format or
    transport. This uniform treatment of opaque tokens across all
    transports is a primary design goal, not an incidental feature.
    > There is a convergence path where SD tokens can be the ntk claim
    inside the EPOP token, which I'll be willing to explore as a
    follow-on draft if you are interested.

    The problem I think you have is that the EPOP proof is wrapping
    the token, but the token needs to be validated in order to
    establish trust in the proof key. Sure, you can do that, but it
    means you have to suspend disbelief for a while - validating the
    EPOP proof based on a self-asserted JWK and only much later do you
    get around to checking if that key is trusted. That seems a
    problematic design to me. (I had a similar concern with DPoP, but
    this seems a step even further down that road). I shouldn’t be
    having to parse an untrusted token to find another token that’ll
    eventually let me tie off the trust knot. That way lies doom.

    EPOP seems to have the further issue that the proof itself
    contains a self-asserting cnf/jkt claim that sometimes seems to
    have to match the jwk header (both under attacker control, so
    pointless), but at other times might be a nested token where it
    matches the outer proof key.

    I think there’s just far too much complexity and conditionality in
    this as specified to make a robust security mechanism.

    — Neil





Regards
Ashwin Ambekar

_______________________________________________
OAuth mailing list [email protected]
To unsubscribe send an email [email protected]

_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to