Hi Joe, Thank you for this -- you're correct that cnonce does not prevent pre-generation attacks. cnonce is entirely deterministic from public inputs (SPKI + published epop_cnonce_seed + time-step).
The motivation behind cnonce is distinct from DPoP's server nonce. The server publishes the time-step parameters (epop_cnonce_step_seconds, epop_cnonce_seed), and validation runs against the server's clock — the client is bound to the server's time-step grid and cannot escape it. This gives the server control over the expiration window without issuing per-client nonce values, allowing any verifier to check cnonce statelessly from the client's public key and the published parameters. cnonce alone does not address pre-generation attacks. The draft addresses this through atomic key rotation as part of the refresh token flow — the client rotates to a new key pair, the server validates the rotation chain and re-binds the new key, and any tokens pre-generated with the old key are invalidated from that point. Regular key rotation, validated by the server at each refresh, bounds the window during which a compromised key remains useful. The specific goals are: (1) eliminate per-client nonce state on the server, which matters for horizontally-scaled deployments; (2) support non-HTTP protocols like Kafka where a server nonce round-trip is not possible; and (3) address the practical reality that DPoP's server nonce is optional and frequently skipped precisely because of the per-client state management burden — against that realistic baseline, cnonce provides an independent server-governed time-bound with no added server state. I can consider revising section 7/7.1.. If there are more inputs please share. This was very helpful. Regards Ashwin On Tue, May 19, 2026 at 10:08 AM Joe DeCock <[email protected]> wrote: > I would also appreciate if you could talk more about the design of the > cnonce. It seems like it is meant to replace the server nonce in DPoP, but > I don't understand how it can accomplish that. As I understand it, the > purpose of DPoP's server nonce is to prevent pre-generation attacks. It can > do that because the value of the server nonce is unpredictable. In > contrast, EPOP's cnonce is entirely deterministic. It seems like cnonce > isn't really meant to prevent pre-generation attacks. But if that's the > case, could you simplify the protocol by removing it entirely, since you > already have iat for time-bounding the token, and jti for replay detection? > > Thanks, > Joe > > On Mon, May 18, 2026 at 6:02 PM Joe DeCock <[email protected]> wrote: > >> Hi Ashwin, >> >> I think this is an interesting idea. Applying sender constraints without >> being tied to http is clearly a real problem. >> >> I'd be curious to hear more from you about the tradeoffs you considered >> when designing EPOP and why you made the decisions you did. For example, my >> intuition is that the enveloped approach results in larger data structures >> compared to a detached signature. Did you consider a design that keeps the >> detached signatures of DPoP? >> >> Thanks for your work on this draft. >> >> Joe DeCock >> >> >> On Sat, May 16, 2026 at 9:14 PM Ashwin Ambekar <[email protected]> wrote: >> >>> Hi all, >>> >>> I've submitted an initial Internet-Draft for a new OAuth 2.0 token >>> profile called Enveloped Proof of Possession (EPOP): >>> >>> https://datatracker.ietf.org/doc/draft-ambekar-oauth-epop/ >>> >>> ## What EPOP introduces >>> >>> EPOP defines a single unified token type that carries both the >>> credential (authorization code, access token, or refresh token) and its >>> cryptographic proof of possession as an inseparable envelope. This >>> eliminates the split between token issuance and proof construction that >>> exists in current mechanisms, and brings the following properties: >>> >>> 1. **Unified credential + proof token** — The credential and its PoP >>> proof are bound together at issuance into a single JWT envelope, >>> cryptographically tied to the client's key pair. Possession of the token >>> alone is insufficient to use it. >>> >>> 2. **Transport-agnostic proof of possession** — EPOP proof validation >>> does not depend on HTTP request parameters, making it applicable uniformly >>> across HTTP and non-HTTP transports: MQTT, Kafka, gRPC, SASL, and emerging >>> agentic protocols such as MCP. >>> >>> 3. **Extended PoP support for RFC 7628 (SASL/OAuth)** — EPOP provides a >>> concrete proof-of-possession mechanism for SASL-based OAuth flows defined >>> in RFC 7628, which currently lacks a sender-constraining profile. >>> >>> 4. **Client-derived nonce (cnonce)** — EPOP introduces an >>> offline-derived client nonce computed deterministically from the client's >>> private key and token material. This eliminates the server-issued nonce >>> round-trip required by existing mechanisms, enabling stateless proof >>> validation at the resource server — critical for high-throughput and >>> constrained deployments. >>> >>> The draft also covers atomic key rotation, discovery metadata >>> extensions, and security considerations for replay prevention and token >>> substitution across all supported transports. >>> >>> ## Seeking feedback on >>> >>> - Whether the unified envelope model introduces any token substitution >>> or cross-credential attack surface not addressed in Section 10. >>> - Soundness of the cnonce derivation and replay window model. >>> - Operator and implementer perspectives, particularly for non-HTTP >>> deployments. >>> - Any overlap with active WG drafts I should reference or reconcile >>> against. >>> >>> Source and issue tracker: https://github.com/asambeka/epop >>> >>> All review, critique, and collaboration interest welcome. >>> >>> Thanks, >>> Ashwin Ambekar >>> eBay >>> _______________________________________________ >>> OAuth mailing list -- [email protected] >>> To unsubscribe send an email to [email protected] >>> >> -- Regards Ashwin Ambekar
_______________________________________________ OAuth mailing list -- [email protected] To unsubscribe send an email to [email protected]
