Skip to content

fix(google-auth): fail loudly when dynamically disabling mTLS on active sessions - #18005

Draft
gorthitk wants to merge 3 commits into
googleapis:mainfrom
gorthitk:fix/mtls-prevent-disable-on-active-session
Draft

fix(google-auth): fail loudly when dynamically disabling mTLS on active sessions#18005
gorthitk wants to merge 3 commits into
googleapis:mainfrom
gorthitk:fix/mtls-prevent-disable-on-active-session

Conversation

@gorthitk

@gorthitk gorthitk commented Aug 5, 2026

Copy link
Copy Markdown

When mTLS is previously enabled on an active transport session (requests, urllib3, or aiohttp), attempting to disable mTLS mid-lifecycle in configure_mtls_channel() now raises a MutualTLSChannelError instead of exiting early or replacing adapters.

This prevents thread-safety violations from connection pool mutation and eliminates zombie state mismatches where active sessions continue sending client certificates while auth checks treat mTLS as disabled.

Fixes #17761

…ve sessions (googleapis#17761)

When mTLS is previously enabled on an active transport session (requests,
urllib3, or aiohttp), attempting to disable mTLS mid-lifecycle in
configure_mtls_channel() now raises a MutualTLSChannelError instead of
exiting early or replacing adapters.

This prevents thread-safety violations from connection pool mutation and
eliminates zombie state mismatches where active sessions continue sending
client certificates while auth checks treat mTLS as disabled.
@gorthitk
gorthitk requested review from a team as code owners August 5, 2026 19:08
@gorthitk gorthitk changed the title fix(google-auth): fail loudly when dynamically disabling mTLS on acti… fix(google-auth): fail loudly when dynamically disabling mTLS on active sessions Aug 5, 2026

@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 prevents mid-lifecycle transitions from mTLS-enabled to mTLS-disabled states on active sessions across the aio, requests, and urllib3 transports by raising a MutualTLSChannelError. However, the review feedback highlights that raising this exception replaces historical graceful fallback behaviors (such as falling back to standard TLS or returning False), which introduces breaking changes for downstream users and violates backwards compatibility.

Comment thread packages/google-auth/google/auth/aio/transport/sessions.py Outdated
Comment thread packages/google-auth/google/auth/aio/transport/sessions.py Outdated
Comment thread packages/google-auth/google/auth/transport/requests.py Outdated
Comment thread packages/google-auth/google/auth/transport/requests.py Outdated
Comment thread packages/google-auth/google/auth/transport/urllib3.py Outdated
Comment thread packages/google-auth/google/auth/transport/urllib3.py Outdated
Comment thread packages/google-auth/google/auth/aio/transport/sessions.py Outdated
# Dynamically disabling mTLS on an active session is unsafe in concurrent
# environments and can cause a zombie state mismatch where mTLS contexts
# remain attached while auth checks believe mTLS is disabled.
if getattr(self, "_is_mtls", False):

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.

self._is_mtls is explicitly initialized to False in init across AsyncAuthorizedSession, AuthorizedSession, and AuthorizedHttp. Using getattr(self, "_is_mtls", False) is unnecessary, we can access self._is_mtls directly.

# remain attached while auth checks believe mTLS is disabled.
if getattr(self, "_is_mtls", False):
raise exceptions.MutualTLSChannelError(
"Cannot disable mTLS on an active session. A new AuthorizedSession must be created."

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.

Please update this to reference AsyncAuthorizedSession instead of AuthorizedSession so async users aren't directed to the synchronous requests transport class.

Suggested change
"Cannot disable mTLS on an active session. A new AuthorizedSession must be created."
"Cannot disable mTLS on an active session. A new AsyncAuthorizedSession must be created."

# Prevent mid-lifecycle transition from mTLS-enabled to mTLS-disabled state.
if getattr(self, "_is_mtls", False) and not is_mtls:
raise exceptions.MutualTLSChannelError(
"Cannot disable mTLS on an active session. A new AuthorizedSession must be created."

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.

Same here

Suggested change
"Cannot disable mTLS on an active session. A new AuthorizedSession must be created."
"Cannot disable mTLS on an active session. A new AsyncAuthorizedSession must be created."

use_client_cert = google.auth.transport._mtls_helper.check_use_client_cert()
if not use_client_cert:
# Dynamically disabling mTLS on an active session is unsafe in concurrent
# environments and can cause a zombie state mismatch where mTLS adapters

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.

nit

Suggested change
# environments and can cause a zombie state mismatch where mTLS adapters
# environments and can cause a state mismatch where mTLS adapters

use_client_cert = transport._mtls_helper.check_use_client_cert()
if not use_client_cert:
# Dynamically disabling mTLS on an active session is unsafe in concurrent
# environments and can cause a zombie state mismatch where mTLS connection

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.

nit:

Suggested change
# environments and can cause a zombie state mismatch where mTLS connection
# environments and can cause a state mismatch where mTLS connection

Comment thread packages/google-auth/google/auth/aio/transport/sessions.py Outdated
Comment thread packages/google-auth/google/auth/aio/transport/sessions.py
@parthea
parthea marked this pull request as draft August 10, 2026 19:17
@parthea

parthea commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Hi @gorthitk, I'm going to mark this as draft since presubmits are failing but please feel free to mark it ready for review once checks are green

gorthitk added 2 commits August 11, 2026 08:52
…tly in mTLS checks

- Add _is_mtls_configured() helper across AuthorizedSession, AuthorizedHttp,
  and AsyncAuthorizedSession.
- Inspect adapter types (_MutualTlsAdapter, _MutualTlsOffloadAdapter),
  PoolManager connection_pool_kw ssl_context, connector SSL context,
  and cached certificates directly.
- Add unit tests verifying desynchronized state detection across all transports.
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.

google-auth: configure_mtls_channel() creates zombie state when dynamically disabled and should fail loudly

3 participants