Skip to content

feature: auth and auth-oauthlib support for OAuth Demonstrable Proof-of-Presence (DPoP) #18800 - #18808

Open
jay0lee wants to merge 1 commit into
googleapis:mainfrom
jay0lee:main
Open

jay0lee wants to merge 1 commit into
googleapis:mainfrom
jay0lee:main

Conversation

@jay0lee

@jay0lee jay0lee commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

This PR implements OAuth DPoP (RFC, Google launch).

Because DPoP touches on and changes many parts of the traditional OAuth dance and, to avoid changing the behavior of our existing Credentials class when DPoP is not in use, this implementation is it's own subclass, DPoPCredentials.

See #18800 for more details.

Add Demonstrating Proof-of-Possession (DPoP) support per RFC 9449,
binding OAuth 2.0 tokens to a cryptographic key so that stolen
refresh tokens cannot be used without the corresponding private key.

New modules:
- google.auth.dpop: DPoPSigner ABC, SoftwareDPoPSigner for
  software-held keys (ES256, ES384, RS256), JWK thumbprint
  computation, DPoP proof creation, and helper utilities.
- google.oauth2.dpop_credentials: DPoPCredentials subclass of
  Credentials that attaches DPoP proofs to token refresh requests,
  handles use_dpop_nonce challenges, and supports RAPT/reauth.

Modifications to existing modules:
- google.oauth2.credentials: extract _call_refresh_grant() hook so
  DPoPCredentials can override the refresh grant without duplicating
  the full refresh flow.
- google.oauth2._client: add return_response_headers parameter to
  _token_endpoint_request_no_throw() so DPoP can capture DPoP-Nonce
  response headers.

Google's authorization server validates DPoP proofs during token
refresh and code exchange. Google resource servers currently accept
only the Bearer authorization scheme; the DPoP proof header is
included for RFC 9449 compliance and forward compatibility.

Tests: 64 in test_dpop.py, 40 in test_dpop_credentials.py.
@jay0lee
jay0lee requested review from a team as code owners October 22, 2026 17:41

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Demonstrating Proof-of-Possession (DPoP) support per RFC 9449 across both google-auth and google-auth-oauthlib. It adds the DPoPSigner interface and SoftwareDPoPSigner implementation, a new DPoPCredentials class for binding tokens to cryptographic keys, and updates the OAuth flow and helper functions to handle DPoP parameters, proofs, and nonce challenges. Feedback on the changes highlights a bug in flow.py where the DPoP nonce is retrieved from the wrong object, a potential side-effect from modifying headers in-place, and a docstring mismatch in _client.py that could lead to a runtime unpacking error.

Comment thread packages/google-auth-oauthlib/google_auth_oauthlib/flow.py Outdated
Comment thread packages/google-auth-oauthlib/google_auth_oauthlib/flow.py Outdated
Comment thread packages/google-auth/google/oauth2/_client.py
@jay0lee
jay0lee force-pushed the main branch 6 times, most recently from 84a86e5 to 333b6f6 Compare October 23, 2026 17:49
@jay0lee

jay0lee commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Tests failed because I was attempting one PR for both the google-auth and google-auth-oauthlib packages which in retrospect was a foolish dream :-)

I've rewritten the PR to focus on google-auth only for now. Once that's committed and released it I can follow up with a PR for gogole-auth-oauthlib with it's changes and a minimum version bump for it's google-auth dependency.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant