@@ -471,13 +471,9 @@ async def verify(
471471 - 'audience': str (optional, required if persist=True) - Audience for token_set
472472 - 'scope': str (optional) - Scope for token_set
473473 store_options: Optional options passed to the State Store (e.g. request/response).
474- dpop_key: Optional EC P-256 JWK for DPoP-bound token exchange. Pass the
475- same key the login flow was bound to (e.g. the dpop_key given to
476- signin_with_passkey) so the MFA step-up preserves the sender
477- constraint. When provided, attaches a DPoP proof so Auth0 issues a
478- DPoP-bound token (token_type: DPoP); the SDK never stores this
479- Tier 0 key — the caller re-supplies it, consistent with every other
480- DPoP entry point.
474+ dpop_key: Optional EC P-256 JWK to DPoP-bind the token. Pass the same
475+ key used at login (e.g. given to signin_with_passkey) to preserve
476+ the sender constraint through step-up. Never stored by the SDK.
481477
482478 Returns:
483479 MfaVerifyResponse with access_token, token_type, etc.
@@ -530,9 +526,7 @@ async def verify(
530526 headers = headers
531527 )
532528
533- # RFC 9449 §8.2 — the authorization server signals a required
534- # nonce with HTTP 400/401 + a DPoP-Nonce header. Rebuild the proof
535- # with the nonce and retry once.
529+ # Rebuild the proof with the nonce and retry once.
536530 if (
537531 dpop_key is not None
538532 and response .status_code in (400 , 401 )
@@ -569,24 +563,14 @@ async def verify(
569563 token_response = response .json ()
570564 verify_response = MfaVerifyResponse (** token_response )
571565
572- # DPoP binding must be consistent in both directions. token_type
573- # is the documented OAuth response field; per RFC 9449 a
574- # sender-constrained token is returned as token_type "DPoP".
566+ # Reject a Bearer downgrade when a DPoP token was requested
567+ # (RFC 9449: a bound token has token_type "DPoP").
575568 token_is_dpop = verify_response .token_type .lower () == "dpop"
576569 if dpop_key is not None and not token_is_dpop :
577- # We asked for a bound token but got Bearer — cannot prove
578- # possession on later calls; reject rather than downgrade.
579570 raise MfaVerifyError (
580571 "DPoP token binding failed: expected token_type 'DPoP', "
581572 f"got '{ verify_response .token_type } '"
582573 )
583- if dpop_key is None and token_is_dpop :
584- # Server issued a DPoP-bound token but no key was supplied —
585- # we cannot prove possession, so accepting it would fail open.
586- raise MfaVerifyError (
587- "Server returned a DPoP-bound token but no dpop_key was "
588- "provided; pass dpop_key to verify to bind it"
589- )
590574
591575 # Clear the in-progress MFA state after successful verification.
592576 if self ._state_store :
0 commit comments