fix: Make credential key generation stable and prevent cross-user credential leaks

This change updates the credential key generation to use a stable hash (SHA256) instead of Python's built-in hash, which can vary based on PYTHONHASHSEED. It also makes sure that temporary or exchanged OAuth2 fields are excluded from the key calculation. I also added when saving credentials, a copy of the AuthConfig is used to avoid modifying the original shared AuthConfig instance with user-specific exchanged credentials.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 864599326
This commit is contained in:
George Weale
2026-02-02 17:51:19 -08:00
committed by Copybara-Service
parent 666cebe369
commit 33012e6dda
11 changed files with 448 additions and 43 deletions
+27
View File
@@ -348,10 +348,12 @@ class TestGenerateAuthRequest:
exchanged_auth_credential=oauth2_credentials_with_auth_uri.model_copy(
deep=True
),
credential_key="my_tool_tokens",
)
handler = AuthHandler(config)
result = handler.generate_auth_request()
assert result.credential_key == "my_tool_tokens"
assert (
result.exchanged_auth_credential.oauth2.auth_uri
== oauth2_credentials_with_auth_uri.oauth2.auth_uri
@@ -400,6 +402,31 @@ class TestGenerateAuthRequest:
assert mock_generate_auth_uri.called
assert result.exchanged_auth_credential == mock_credential
@patch("google.adk.auth.auth_handler.AuthHandler.generate_auth_uri")
def test_preserves_credential_key_on_generated_request(
self, mock_generate_auth_uri, oauth2_auth_scheme, oauth2_credentials
):
"""Test that AuthHandler preserves an explicit credential_key."""
mock_generate_auth_uri.return_value = AuthCredential(
auth_type=AuthCredentialTypes.OAUTH2,
oauth2=OAuth2Auth(
client_id="mock_client_id",
client_secret="mock_client_secret",
auth_uri="https://example.com/generated",
state="generated_state",
),
)
config = AuthConfig(
auth_scheme=oauth2_auth_scheme,
raw_auth_credential=oauth2_credentials,
credential_key="my_tool_tokens",
)
handler = AuthHandler(config)
result = handler.generate_auth_request()
assert result.credential_key == "my_tool_tokens"
class TestGetAuthResponse:
"""Tests for the get_auth_response method."""