Skip to content

fix(auth): align mTLS discovery and enforce fail-fast transport configuration.#17470

Open
vverman wants to merge 2 commits into
googleapis:mainfrom
vverman:agentic-identity-fix-mtls-gaps-2
Open

fix(auth): align mTLS discovery and enforce fail-fast transport configuration.#17470
vverman wants to merge 2 commits into
googleapis:mainfrom
vverman:agentic-identity-fix-mtls-gaps-2

Conversation

@vverman

@vverman vverman commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

This PR resolves two mTLS issues:

(1) it synchronizes the transport and token discovery paths to check for workload certs and library support, preventing mismatched bound tokens, and

(2) it enforces fail-fast error behavior in all transports if mTLS configuration fails, avoiding silent fallback to insecure TLS. These align token and transport states securely.

@vverman vverman requested review from a team as code owners June 16, 2026 00:46
@vverman vverman requested a review from nbayati June 16, 2026 00:46

@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 auto-enablement of mTLS when workload certificates are discovered (including at a well-known SPIFFE path) and changes the library's behavior to fail fast with a MutualTLSChannelError instead of silently falling back to standard TLS when mTLS is expected but certificates cannot be loaded. The review feedback suggests several improvements: aligning the environment variable checks in _agent_identity_utils.py to treat any value other than 'true' as disabled, correcting a misleading exception message in sessions.py when a custom request handler is used, and making the SPIFFE certificate path check more robust by using path.isfile and handling potential OSError exceptions.

Comment on lines +205 to +207
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert and use_client_cert.lower() == "false":
return None

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.

medium

If GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an invalid value (e.g., 'foo'), check_use_client_cert() will treat it as False (disabled). However, the current check only returns None if it is explicitly 'false'. To ensure perfect alignment with check_use_client_cert(), we should treat any value other than 'true' as an opt-out/disabled state when the environment variable is set.

Suggested change
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert and use_client_cert.lower() == "false":
return None
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert is not None and use_client_cert.lower() != "true":
return None

Comment on lines +324 to +326
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert and use_client_cert.lower() == "false":
return 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.

medium

Similar to the check in get_and_parse_agent_identity_certificate, if GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an invalid value, it should be treated as disabled to prevent mismatched bound tokens. We should check if the variable is set and is not 'true'.

Suggested change
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert and use_client_cert.lower() == "false":
return False
use_client_cert = os.environ.get(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE)
if use_client_cert is not None and use_client_cert.lower() != "true":
return False

Comment on lines +215 to +217
raise exceptions.MutualTLSChannelError(
"mTLS was configured/enabled but client certificate or private key could not be loaded."
)

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.

medium

The exception message here is misleading. If this block is reached, it means a custom request handler (not an AiohttpRequest) was provided, which cannot be configured for mTLS. The current message states that the client certificate or private key could not be loaded, which will confuse users trying to debug their configuration.

Suggested change
raise exceptions.MutualTLSChannelError(
"mTLS was configured/enabled but client certificate or private key could not be loaded."
)
raise exceptions.MutualTLSChannelError(
"mTLS was configured/enabled but a custom request handler was provided, which is not supported for mTLS configuration."
)

Comment on lines +522 to +526
if (
path.exists(_WELL_KNOWN_SPIFFE_CERT_PATH)
and path.getsize(_WELL_KNOWN_SPIFFE_CERT_PATH) > 0
):
return True

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.

medium

Using path.exists can return True for directories, and calling path.getsize on a directory or a file without read permissions can raise an OSError (such as PermissionError). To make this auto-detection robust and prevent unexpected crashes on startup, we should use path.isfile and wrap the check in a try-except OSError block.

Suggested change
if (
path.exists(_WELL_KNOWN_SPIFFE_CERT_PATH)
and path.getsize(_WELL_KNOWN_SPIFFE_CERT_PATH) > 0
):
return True
try:
if (
path.isfile(_WELL_KNOWN_SPIFFE_CERT_PATH)
and path.getsize(_WELL_KNOWN_SPIFFE_CERT_PATH) > 0
):
return True
except OSError:
pass

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