Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fa24e36
feat: Add passphrase handling to client cert callback
agrawalradhika-cell Aug 6, 2026
49a1412
feat: Add cert rotation handling support
agrawalradhika-cell Aug 6, 2026
c502006
chore: Add passphrase in _mtls_helper for requests
agrawalradhika-cell Aug 6, 2026
12169ff
chore: Modify _mtls_helper call to include additional variable passph…
agrawalradhika-cell Aug 6, 2026
c90c0b1
chore: Modify mock return values in test_urllib3.py
agrawalradhika-cell Aug 6, 2026
3cde59e
chore: Modify mock callback return value in tests all
agrawalradhika-cell Aug 6, 2026
96b4161
chore: Modify mock return value in test_requests.py
agrawalradhika-cell Aug 6, 2026
ba1c85a
chore: Add unit tests for cert rotation handling for grpc
agrawalradhika-cell Aug 6, 2026
b427128
chore: Update unit tests for grpc cert rotation handling compatibility
agrawalradhika-cell Aug 6, 2026
70a587a
Merge pull request #1 from agrawalradhika-cell/main
agrawalradhika-cell Aug 6, 2026
a9e45af
fix: Refactor gRPC call handling and state management
agrawalradhika-cell Aug 6, 2026
565f6fb
Merge branch 'googleapis:main' into grpc-cert-rotation
agrawalradhika-cell Aug 10, 2026
524247b
chore: format files with black
agrawalradhika-cell Aug 10, 2026
ea7082b
chore: add coverage and fix lint errors
agrawalradhika-cell Aug 11, 2026
60a606a
chore: add coverage for grpc.py
agrawalradhika-cell Aug 11, 2026
90555fc
test: Updating tests for file coverage
agrawalradhika-cell Aug 11, 2026
df68343
Merge branch 'main' into grpc-cert-rotation
agrawalradhika-cell Aug 12, 2026
732f545
Merge branch 'googleapis:main' into grpc-cert-rotation
agrawalradhika-cell Aug 12, 2026
3139e83
fix: fix lint errors post resolving merge conflicts
agrawalradhika-cell Aug 12, 2026
f344dcf
chore: Update Refactor mTLS gRPC client interceptor logic based on co…
agrawalradhika-cell Aug 20, 2026
b7db29e
chore: Refactor error handling for certificate retrieval and update t…
agrawalradhika-cell Aug 20, 2026
91570a3
fix: Refactor deadline error handling in grpc.py
agrawalradhika-cell Aug 20, 2026
d8050ed
fix: Fix lint and unit tests
agrawalradhika-cell Aug 20, 2026
02fa5ea
chore: Refactor gRPC call handling with base wrapper class
agrawalradhika-cell Aug 25, 2026
9b01e85
chore: Include Wrapper in CertRotationInterceptor initialization
agrawalradhika-cell Aug 25, 2026
07ab346
chore: Refactor MTLS channel creation to use a partial function for c…
agrawalradhika-cell Aug 26, 2026
4a00631
chore: Add mTLS Interceptor and Wrapper in separate file for certific…
agrawalradhika-cell Aug 26, 2026
9091ec3
chore: Refactor gRPC transport to use mtls_interceptor
agrawalradhika-cell Aug 26, 2026
4305ab7
chore: Rename _mtls_interceptor.py to mtls_interceptor.py to make public
agrawalradhika-cell Aug 26, 2026
f7a2ca3
fix: Fix import statement for mtls_interceptor
agrawalradhika-cell Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions packages/google-auth/google/auth/transport/_mtls_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,10 +817,11 @@ def check_parameters_for_unauthorized_response(cached_cert):
Returns:
bytes: The client callback cert bytes.
bytes: The client callback key bytes.
Optional[Union[bytes, str]]: The passphrase for the key.
str: The base64-encoded SHA256 cached fingerprint.
str: The base64-encoded SHA256 current cert fingerprint.
"""
call_cert_bytes, call_key_bytes = call_client_cert_callback()
call_cert_bytes, call_key_bytes, passphrase = call_client_cert_callback()
cert_obj = _agent_identity_utils.parse_certificate(call_cert_bytes)
current_cert_fingerprint = _agent_identity_utils.calculate_certificate_fingerprint(
cert_obj
Expand All @@ -831,12 +832,18 @@ def check_parameters_for_unauthorized_response(cached_cert):
)
else:
cached_fingerprint = current_cert_fingerprint
return call_cert_bytes, call_key_bytes, cached_fingerprint, current_cert_fingerprint
return (
call_cert_bytes,
call_key_bytes,
passphrase,
cached_fingerprint,
current_cert_fingerprint,
)


def call_client_cert_callback():
"""Calls the client cert callback and returns the certificate and key."""
"""Calls the client cert callback and returns the certificate, key, and passphrase."""
_, cert_bytes, key_bytes, passphrase = get_client_ssl_credentials(
generate_encrypted_key=True
)
return cert_bytes, key_bytes
return cert_bytes, key_bytes, passphrase
35 changes: 31 additions & 4 deletions packages/google-auth/google/auth/transport/grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@

from __future__ import absolute_import

import functools
import logging
import warnings


from google.auth import exceptions
from google.auth import transport
from google.auth.transport import _mtls_helper
from google.auth.transport import mtls_interceptor‎
from google.auth.transport import mtls
from google.oauth2 import service_account

from typing import Optional


try:
import grpc # type: ignore
except ImportError as caught_exc: # pragma: NO COVER
Expand Down Expand Up @@ -283,6 +290,7 @@ def my_client_cert_callback():
)

# If SSL credentials are not explicitly set, try client_cert_callback and ADC.
cached_cert: Optional[bytes] = None
if not ssl_credentials:
use_client_cert = _mtls_helper.check_use_client_cert()
if use_client_cert and client_cert_callback:
Expand All @@ -291,19 +299,36 @@ def my_client_cert_callback():
ssl_credentials = grpc.ssl_channel_credentials(
certificate_chain=cert, private_key=key
)
cached_cert = cert
elif use_client_cert:
# Use application default SSL credentials.
adc_ssl_credentils = SslCredentials()
ssl_credentials = adc_ssl_credentils.ssl_credentials
adc_ssl_credentials = SslCredentials()
ssl_credentials = adc_ssl_credentials.ssl_credentials
cached_cert = adc_ssl_credentials._cached_cert
else:
ssl_credentials = grpc.ssl_channel_credentials()

# Combine the ssl credentials and the authorization credentials.
composite_credentials = grpc.composite_channel_credentials(
ssl_credentials, google_auth_credentials
)

return grpc.secure_channel(target, composite_credentials, **kwargs)
is_recreation = kwargs.pop("_is_recreation", False)
channel = grpc.secure_channel(target, composite_credentials, **kwargs)
# Avoid wrapping if mTLS is disabled or if this is a channel recreation call
if cached_cert and not is_recreation:
# Package arguments so the channel can be recreated later
create_channel_fn = functools.partial(
secure_authorized_channel,
credentials=credentials,
request=request,
target=target,
_is_recreation=True, # Hidden flag to stop recursion
**kwargs
)
wrapper = mtls_interceptor.MTLSRefreshingChannel(target, create_channel_fn, channel, cached_cert)
interceptor = mtls_interceptor.CertRotationInterceptor(wrapper=wrapper)
return grpc.intercept_channel(wrapper, interceptor)
return channel


class SslCredentials:
Expand All @@ -327,6 +352,7 @@ class SslCredentials:

def __init__(self):
use_client_cert = _mtls_helper.check_use_client_cert()
self._cached_cert = None
if not use_client_cert:
self._is_mtls = False
else:
Expand Down Expand Up @@ -355,6 +381,7 @@ def ssl_credentials(self):
self._ssl_credentials = grpc.ssl_channel_credentials(
certificate_chain=cert, private_key=key
)
self._cached_cert = cert
else:
self._ssl_credentials = grpc.ssl_channel_credentials()
self._is_mtls = False
Expand Down
Loading
Loading