google-auth 2.56.0__tar.gz → 2.56.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. {google_auth-2.56.0/google_auth.egg-info → google_auth-2.56.2}/PKG-INFO +1 -1
  2. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_agent_identity_utils.py +90 -62
  3. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/compute_engine/_metadata.py +3 -1
  4. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/impersonated_credentials.py +5 -1
  5. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/jwt.py +11 -1
  6. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/_mtls_helper.py +31 -59
  7. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/mtls.py +9 -15
  8. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/requests.py +70 -4
  9. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/urllib3.py +12 -1
  10. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/version.py +1 -1
  11. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/service_account.py +5 -1
  12. {google_auth-2.56.0 → google_auth-2.56.2/google_auth.egg-info}/PKG-INFO +1 -1
  13. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/test__metadata.py +5 -1
  14. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/test_credentials.py +117 -51
  15. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_service_account.py +4 -0
  16. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_agent_identity_utils.py +203 -108
  17. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_impersonated_credentials.py +4 -0
  18. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_jwt.py +25 -2
  19. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test__mtls_helper.py +94 -101
  20. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test_grpc.py +12 -7
  21. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test_mtls.py +41 -40
  22. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test_requests.py +135 -0
  23. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test_urllib3.py +57 -0
  24. {google_auth-2.56.0 → google_auth-2.56.2}/LICENSE +0 -0
  25. {google_auth-2.56.0 → google_auth-2.56.2}/MANIFEST.in +0 -0
  26. {google_auth-2.56.0 → google_auth-2.56.2}/README.rst +0 -0
  27. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/__init__.py +0 -0
  28. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_cache.py +0 -0
  29. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_cloud_sdk.py +0 -0
  30. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_credentials_async.py +0 -0
  31. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_credentials_base.py +0 -0
  32. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_default.py +0 -0
  33. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_default_async.py +0 -0
  34. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_exponential_backoff.py +0 -0
  35. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_helpers.py +0 -0
  36. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_jwt_async.py +0 -0
  37. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_oauth2client.py +0 -0
  38. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_refresh_worker.py +0 -0
  39. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_regional_access_boundary_utils.py +0 -0
  40. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/_service_account_info.py +0 -0
  41. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/__init__.py +0 -0
  42. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/_helpers.py +0 -0
  43. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/credentials.py +0 -0
  44. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/transport/__init__.py +0 -0
  45. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/transport/aiohttp.py +0 -0
  46. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/transport/mtls.py +0 -0
  47. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aio/transport/sessions.py +0 -0
  48. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/api_key.py +0 -0
  49. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/app_engine.py +0 -0
  50. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/aws.py +0 -0
  51. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/compute_engine/__init__.py +0 -0
  52. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/compute_engine/_mtls.py +0 -0
  53. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/compute_engine/credentials.py +0 -0
  54. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/credentials.py +0 -0
  55. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/__init__.py +0 -0
  56. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/_cryptography_rsa.py +0 -0
  57. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/_helpers.py +0 -0
  58. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/_python_rsa.py +0 -0
  59. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/base.py +0 -0
  60. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/es.py +0 -0
  61. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/es256.py +0 -0
  62. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/crypt/rsa.py +0 -0
  63. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/downscoped.py +0 -0
  64. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/environment_vars.py +0 -0
  65. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/exceptions.py +0 -0
  66. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/external_account.py +0 -0
  67. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/external_account_authorized_user.py +0 -0
  68. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/iam.py +0 -0
  69. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/identity_pool.py +0 -0
  70. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/metrics.py +0 -0
  71. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/pluggable.py +0 -0
  72. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/py.typed +0 -0
  73. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/__init__.py +0 -0
  74. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/_aiohttp_requests.py +0 -0
  75. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/_custom_tls_signer.py +0 -0
  76. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/_http_client.py +0 -0
  77. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/_requests_base.py +0 -0
  78. {google_auth-2.56.0 → google_auth-2.56.2}/google/auth/transport/grpc.py +0 -0
  79. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/__init__.py +0 -0
  80. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_client.py +0 -0
  81. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_client_async.py +0 -0
  82. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_credentials_async.py +0 -0
  83. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_id_token_async.py +0 -0
  84. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_reauth_async.py +0 -0
  85. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/_service_account_async.py +0 -0
  86. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/challenges.py +0 -0
  87. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/credentials.py +0 -0
  88. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/gdch_credentials.py +0 -0
  89. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/id_token.py +0 -0
  90. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/py.typed +0 -0
  91. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/reauth.py +0 -0
  92. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/sts.py +0 -0
  93. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/utils.py +0 -0
  94. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/webauthn_handler.py +0 -0
  95. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/webauthn_handler_factory.py +0 -0
  96. {google_auth-2.56.0 → google_auth-2.56.2}/google/oauth2/webauthn_types.py +0 -0
  97. {google_auth-2.56.0 → google_auth-2.56.2}/google_auth.egg-info/SOURCES.txt +0 -0
  98. {google_auth-2.56.0 → google_auth-2.56.2}/google_auth.egg-info/dependency_links.txt +0 -0
  99. {google_auth-2.56.0 → google_auth-2.56.2}/google_auth.egg-info/requires.txt +0 -0
  100. {google_auth-2.56.0 → google_auth-2.56.2}/google_auth.egg-info/top_level.txt +0 -0
  101. {google_auth-2.56.0 → google_auth-2.56.2}/setup.cfg +0 -0
  102. {google_auth-2.56.0 → google_auth-2.56.2}/setup.py +0 -0
  103. {google_auth-2.56.0 → google_auth-2.56.2}/tests/__init__.py +0 -0
  104. {google_auth-2.56.0 → google_auth-2.56.2}/tests/aio/test__helpers.py +0 -0
  105. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/__init__.py +0 -0
  106. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/data/smbios_product_name +0 -0
  107. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/data/smbios_product_name_non_google +0 -0
  108. {google_auth-2.56.0 → google_auth-2.56.2}/tests/compute_engine/test__mtls.py +0 -0
  109. {google_auth-2.56.0 → google_auth-2.56.2}/tests/conftest.py +0 -0
  110. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/__init__.py +0 -0
  111. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test__cryptography_rsa.py +0 -0
  112. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test__python_rsa.py +0 -0
  113. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test_crypt.py +0 -0
  114. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test_es.py +0 -0
  115. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test_es256.py +0 -0
  116. {google_auth-2.56.0 → google_auth-2.56.2}/tests/crypt/test_rsa.py +0 -0
  117. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/authorized_user.json +0 -0
  118. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/authorized_user_cloud_sdk.json +0 -0
  119. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/authorized_user_cloud_sdk_with_quota_project_id.json +0 -0
  120. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/authorized_user_with_rapt_token.json +0 -0
  121. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/client_secrets.json +0 -0
  122. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/context_aware_metadata.json +0 -0
  123. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/enterprise_cert_invalid.json +0 -0
  124. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/enterprise_cert_valid.json +0 -0
  125. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/enterprise_cert_valid_provider.json +0 -0
  126. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es256_privatekey.pem +0 -0
  127. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es256_public_cert.pem +0 -0
  128. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es256_publickey.pem +0 -0
  129. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es256_service_account.json +0 -0
  130. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es384_privatekey.pem +0 -0
  131. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es384_public_cert.pem +0 -0
  132. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es384_publickey.pem +0 -0
  133. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/es384_service_account.json +0 -0
  134. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/external_account_authorized_user.json +0 -0
  135. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/external_account_authorized_user_non_gdu.json +0 -0
  136. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/external_subject_token.json +0 -0
  137. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/external_subject_token.txt +0 -0
  138. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/gdch_service_account.json +0 -0
  139. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/impersonated_service_account_authorized_user_source.json +0 -0
  140. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/impersonated_service_account_external_account_authorized_user_source.json +0 -0
  141. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/impersonated_service_account_service_account_source.json +0 -0
  142. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/impersonated_service_account_with_quota_project.json +0 -0
  143. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/old_oauth_credentials_py3.pickle +0 -0
  144. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/other_cert.pem +0 -0
  145. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/pem_from_pkcs12.pem +0 -0
  146. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/privatekey.p12 +0 -0
  147. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/privatekey.pem +0 -0
  148. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/privatekey.pub +0 -0
  149. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/public_cert.pem +0 -0
  150. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/service_account.json +0 -0
  151. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/service_account_non_gdu.json +0 -0
  152. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/trust_chain_with_leaf.pem +0 -0
  153. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/trust_chain_without_leaf.pem +0 -0
  154. {google_auth-2.56.0 → google_auth-2.56.2}/tests/data/trust_chain_wrong_order.pem +0 -0
  155. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/__init__.py +0 -0
  156. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test__client.py +0 -0
  157. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_challenges.py +0 -0
  158. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_credentials.py +0 -0
  159. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_gdch_credentials.py +0 -0
  160. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_id_token.py +0 -0
  161. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_reauth.py +0 -0
  162. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_sts.py +0 -0
  163. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_utils.py +0 -0
  164. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_webauthn_handler.py +0 -0
  165. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_webauthn_handler_factory.py +0 -0
  166. {google_auth-2.56.0 → google_auth-2.56.2}/tests/oauth2/test_webauthn_types.py +0 -0
  167. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__cache.py +0 -0
  168. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__cloud_sdk.py +0 -0
  169. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__default.py +0 -0
  170. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__exponential_backoff.py +0 -0
  171. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__helpers.py +0 -0
  172. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__oauth2client.py +0 -0
  173. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__refresh_worker.py +0 -0
  174. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__regional_access_boundary_utils.py +0 -0
  175. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test__service_account_info.py +0 -0
  176. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_api_key.py +0 -0
  177. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_app_engine.py +0 -0
  178. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_aws.py +0 -0
  179. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_credentials.py +0 -0
  180. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_credentials_async.py +0 -0
  181. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_downscoped.py +0 -0
  182. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_exceptions.py +0 -0
  183. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_external_account.py +0 -0
  184. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_external_account_authorized_user.py +0 -0
  185. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_iam.py +0 -0
  186. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_identity_pool.py +0 -0
  187. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_metrics.py +0 -0
  188. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_packaging.py +0 -0
  189. {google_auth-2.56.0 → google_auth-2.56.2}/tests/test_pluggable.py +0 -0
  190. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/__init__.py +0 -0
  191. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/aio/conftest.py +0 -0
  192. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/aio/test_aiohttp.py +0 -0
  193. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/aio/test_sessions.py +0 -0
  194. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/aio/test_sessions_mtls.py +0 -0
  195. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/aioresponses_compat.py +0 -0
  196. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/compliance.py +0 -0
  197. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test__custom_tls_signer.py +0 -0
  198. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test__http_client.py +0 -0
  199. {google_auth-2.56.0 → google_auth-2.56.2}/tests/transport/test_aio_mtls_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-auth
3
- Version: 2.56.0
3
+ Version: 2.56.2
4
4
  Summary: Google Authentication Library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth
6
6
  Author: Google Cloud Platform
@@ -67,93 +67,88 @@ def _is_certificate_file_ready(path):
67
67
  st = os.stat(path)
68
68
  return stat.S_ISREG(st.st_mode) and st.st_size > 0
69
69
  except PermissionError:
70
- # Propagate PermissionError to let caller handle it (fail-fast or fallback)
70
+ # Propagate PermissionError to let caller handle it (e.g., return early or fallback)
71
71
  raise
72
72
  except OSError:
73
73
  return False
74
74
 
75
75
 
76
76
  def get_agent_identity_certificate_path():
77
- """Gets the certificate path from the certificate config file.
77
+ """Gets the agent certificate path from the certificate config file.
78
78
 
79
79
  The path to the certificate config file is read from the
80
80
  GOOGLE_API_CERTIFICATE_CONFIG environment variable. This function
81
- implements a retry mechanism to handle cases where the environment
81
+ can optionally trigger polling to handle cases where the environment
82
82
  variable is set before the files are available on the filesystem.
83
83
 
84
84
  Returns:
85
- str: The path to the leaf certificate file.
85
+ Optional[str]: The path to the agent's certificate file, or None if unavailable.
86
86
 
87
87
  Raises:
88
88
  google.auth.exceptions.RefreshError: If the certificate config file
89
89
  or the certificate file cannot be found after retries.
90
90
  """
91
- import json
92
-
93
91
  cert_config_path = os.environ.get(environment_vars.GOOGLE_API_CERTIFICATE_CONFIG)
94
92
 
95
- # Check if the well-known workload directory is mounted.
93
+ if not cert_config_path:
94
+ return None
95
+
96
+ # We trigger polling only if the config path points to the well-known directory.
97
+ # Cloud Run dynamically generates these files in this directory, and both the
98
+ # config file and the certificate file may experience a brief startup latency.
99
+ # For all other paths, we return early to avoid introducing unnecessary startup
100
+ # delays.
96
101
  well_known_dir = os.path.dirname(_WELL_KNOWN_CERT_PATH)
97
- has_well_known_dir = os.path.exists(well_known_dir)
102
+ try:
103
+ abs_cert_path = os.path.abspath(cert_config_path)
104
+ abs_well_known_dir = os.path.abspath(well_known_dir)
105
+ should_poll = (
106
+ os.path.commonpath([abs_well_known_dir, abs_cert_path])
107
+ == abs_well_known_dir
108
+ )
109
+ except ValueError:
110
+ should_poll = False
98
111
 
99
- # If we have neither a config path nor a well-known mount directory, exit immediately.
100
- if not cert_config_path and not has_well_known_dir:
101
- return None
112
+ return _get_cert_path_with_optional_polling(cert_config_path, should_poll)
102
113
 
103
- # If ECP config path is specified but does not exist, and we are on a workstation, fail-fast immediately.
104
- if (
105
- cert_config_path
106
- and not has_well_known_dir
107
- and not os.path.exists(cert_config_path)
108
- ):
109
- return None
110
114
 
115
+ def _get_cert_path_with_optional_polling(cert_config_path, should_poll):
116
+ """Gets the certificate path, optionally polling until it is ready.
117
+
118
+ Args:
119
+ cert_config_path (str): The path to the certificate configuration file.
120
+ should_poll (bool): If True, the function will poll for the file and
121
+ certificate to be ready. If False, it will check only once and
122
+ return early if they are not immediately available.
123
+
124
+ Returns:
125
+ str: The path to the certificate file, or None if unavailable.
126
+
127
+ Raises:
128
+ google.auth.exceptions.RefreshError: If the certificate config file
129
+ or the certificate file cannot be found after retries.
130
+ """
111
131
  has_logged_config_warning = False
112
132
  has_logged_cert_warning = False
113
133
 
114
134
  for interval in _POLLING_INTERVALS:
115
135
  try:
116
- # Path A: Config file is explicitly set
117
- if cert_config_path:
118
- with open(cert_config_path, "r") as f:
119
- cert_config = json.load(f)
120
-
121
- cert_configs = (
122
- cert_config.get("cert_configs")
123
- if isinstance(cert_config, dict)
124
- else None
125
- )
126
- workload_config = (
127
- cert_configs.get("workload")
128
- if isinstance(cert_configs, dict)
129
- else None
130
- )
131
-
132
- if (
133
- not isinstance(workload_config, dict)
134
- or "cert_path" not in workload_config
135
- ):
136
- return None
137
-
138
- cert_path = workload_config["cert_path"]
139
- if _is_certificate_file_ready(cert_path):
140
- return cert_path
136
+ cert_path = _parse_cert_path_from_config(cert_config_path)
141
137
 
142
- # The config was parsed, but the cert file is not ready yet
143
- target_path = cert_path
138
+ if cert_path is None:
139
+ return None
144
140
 
145
- # Path B: Config is NOT set, fallback to the well-known path
146
- else:
147
- if _is_certificate_file_ready(_WELL_KNOWN_CERT_PATH):
148
- return _WELL_KNOWN_CERT_PATH
141
+ if _is_certificate_file_ready(cert_path):
142
+ return cert_path
149
143
 
150
- # The well-known cert file is not ready yet
151
- target_path = _WELL_KNOWN_CERT_PATH
144
+ # The config was parsed, but the cert file is not ready yet
145
+ if not should_poll:
146
+ # If polling is disabled, return early.
147
+ return None
152
148
 
153
- # Log a warning on the first failed attempt to load the certificate file
154
149
  if not has_logged_cert_warning:
155
150
  warnings.warn(
156
- f"Certificate file not ready at {target_path}. Retrying until startup timeout (up to {_TOTAL_TIMEOUT} seconds total)..."
151
+ f"Certificate file not ready at {cert_path}. Retrying until startup timeout (up to {_TOTAL_TIMEOUT} seconds total)..."
157
152
  )
158
153
  has_logged_cert_warning = True
159
154
 
@@ -164,25 +159,24 @@ def get_agent_identity_certificate_path():
164
159
  )
165
160
  return None
166
161
  except (IOError, ValueError, KeyError) as e:
167
- if cert_config_path and os.path.exists(cert_config_path):
162
+ if os.path.exists(cert_config_path):
168
163
  # If the file exists but has invalid JSON or is unreadable,
169
- # we assume it is in its final format and fail-fast by returning None.
164
+ # we assume it is in its final format and return early (returning None).
165
+ return None
166
+
167
+ if not should_poll:
168
+ # If polling is disabled, return early if the file doesn't exist.
170
169
  return None
171
170
 
172
- if not has_logged_config_warning and cert_config_path:
171
+ if not has_logged_config_warning:
173
172
  warnings.warn(
174
173
  f"Certificate config file not found or incomplete: {e} (from "
175
174
  f"{environment_vars.GOOGLE_API_CERTIFICATE_CONFIG} environment variable). "
176
175
  f"Retrying until startup timeout (up to {_TOTAL_TIMEOUT} seconds total)..."
177
176
  )
178
177
  has_logged_config_warning = True
179
- pass
180
178
 
181
- # A sleep is required in two cases:
182
- # 1. The config file is not found (the except block).
183
- # 2. The config file/well-known path is found, but the certificate is not yet available.
184
- # In both cases, we need to poll, so we sleep on every iteration
185
- # that doesn't return a certificate.
179
+ # Sleep before the next polling attempt.
186
180
  time.sleep(interval)
187
181
 
188
182
  raise exceptions.RefreshError(
@@ -193,6 +187,40 @@ def get_agent_identity_certificate_path():
193
187
  )
194
188
 
195
189
 
190
+ def _parse_cert_path_from_config(cert_config_path):
191
+ """Reads the cert config file and returns the cert_path.
192
+
193
+ Args:
194
+ cert_config_path (str): The path to the certificate configuration file.
195
+
196
+ Returns:
197
+ Optional[str]: The path to the certificate file, or None if not found
198
+ in the config.
199
+
200
+ Raises:
201
+ IOError: If the certificate config file cannot be read.
202
+ ValueError: If the certificate config file contains invalid JSON.
203
+ KeyError: If the certificate config file does not contain the
204
+ expected structure.
205
+ """
206
+ import json
207
+
208
+ with open(cert_config_path, "r", encoding="utf-8") as f:
209
+ cert_config = json.load(f)
210
+
211
+ cert_configs = (
212
+ cert_config.get("cert_configs") if isinstance(cert_config, dict) else None
213
+ )
214
+ workload_config = (
215
+ cert_configs.get("workload") if isinstance(cert_configs, dict) else None
216
+ )
217
+
218
+ if not isinstance(workload_config, dict) or "cert_path" not in workload_config:
219
+ return None
220
+
221
+ return workload_config["cert_path"]
222
+
223
+
196
224
  def get_and_parse_agent_identity_certificate():
197
225
  """Gets and parses the agent identity certificate if not opted out.
198
226
 
@@ -38,7 +38,9 @@ from google.auth.compute_engine import _mtls
38
38
 
39
39
  _LOGGER = logging.getLogger(__name__)
40
40
 
41
- _SERVICE_ACCOUNT_EMAIL_PATTERN = re.compile(r"^[^@]+@[^@]+\.[^@]+$")
41
+ _SERVICE_ACCOUNT_EMAIL_PATTERN = re.compile(
42
+ r"^[^@]+@[^@]+\.gserviceaccount\.com$", re.IGNORECASE
43
+ )
42
44
 
43
45
  _GCE_DEFAULT_MDS_IP = "169.254.169.254"
44
46
  _GCE_DEFAULT_HOST = "metadata.google.internal"
@@ -362,8 +362,12 @@ class Credentials(
362
362
 
363
363
  Returns:
364
364
  Optional[str]: The URL for the Regional Access Boundary lookup endpoint, or None
365
- if the service account email is missing.
365
+ if the service account email is missing. Returns None if the subject is populated.
366
366
  """
367
+ if self._subject:
368
+ # RAB does not apply to Workspace User Accounts via Domain-wide Delegation.
369
+ return None
370
+
367
371
  if not self.service_account_email:
368
372
  _LOGGER.error(
369
373
  "Service account email is required to build the Regional Access Boundary lookup URL for impersonated credentials."
@@ -585,7 +585,17 @@ class Credentials(
585
585
  self.token, self.expiry = self._make_jwt()
586
586
 
587
587
  def _build_regional_access_boundary_lookup_url(self, request=None):
588
- """Builds the lookup URL using the service account's email address."""
588
+ """Builds the lookup URL using the service account's email address.
589
+
590
+ Returns None if the subject is populated.
591
+ """
592
+ # In jwt.Credentials, subject defaults to client_email (which is the issuer).
593
+ # We must check self._subject != self._issuer to correctly determine if
594
+ # Domain-Wide Delegation is active.
595
+ if self._subject and self._subject != self._issuer:
596
+ # RAB does not apply to Workspace User Accounts via Domain-wide Delegation.
597
+ return None
598
+
589
599
  if not self.signer_email:
590
600
  return None
591
601
 
@@ -26,6 +26,7 @@ import tempfile
26
26
  from typing import cast, Generator, List, Optional, Tuple, Union
27
27
 
28
28
  from google.auth import _agent_identity_utils
29
+ from google.auth import _cloud_sdk
29
30
  from google.auth import environment_vars
30
31
  from google.auth import exceptions
31
32
 
@@ -51,30 +52,10 @@ _KEY_REGEX = re.compile(
51
52
  _LOGGER = logging.getLogger(__name__)
52
53
 
53
54
 
54
- # A flag to track if we have already logged a warning about mTLS auto-enablement failures.
55
- # This prevents log spam when client libraries create transports or session instances
56
- # frequently within a single process.
57
- _has_logged_mtls_warning = False
58
-
59
-
60
55
  _PASSPHRASE_REGEX = re.compile(
61
56
  b"-----BEGIN PASSPHRASE-----(.+)-----END PASSPHRASE-----", re.DOTALL
62
57
  )
63
58
 
64
- # Temporary patch to accomodate incorrect cert config in Cloud Run prod environment.
65
- _WELL_KNOWN_CLOUD_RUN_CERT_PATH = (
66
- "/var/run/secrets/workload-spiffe-credentials/certificates.pem"
67
- )
68
- _WELL_KNOWN_CLOUD_RUN_KEY_PATH = (
69
- "/var/run/secrets/workload-spiffe-credentials/private_key.pem"
70
- )
71
- _INCORRECT_CLOUD_RUN_CERT_PATH = (
72
- "/var/lib/volumes/certificate/workload-certificates/certificates.pem"
73
- )
74
- _INCORRECT_CLOUD_RUN_KEY_PATH = (
75
- "/var/lib/volumes/certificate/workload-certificates/private_key.pem"
76
- )
77
-
78
59
 
79
60
  class _MemfdCreationError(OSError):
80
61
  """Raised when Linux in-memory virtual file creation (memfd) fails."""
@@ -436,10 +417,15 @@ def _get_cert_config_path(certificate_config_path=None, include_context_aware=Tr
436
417
  The absolute path of the certificate config file, and None if the file does not exist.
437
418
  """
438
419
 
420
+ source = "function argument"
421
+ is_explicit = True
439
422
  if certificate_config_path is None:
440
423
  env_path = environ.get(environment_vars.GOOGLE_API_CERTIFICATE_CONFIG, None)
441
424
  if env_path is not None and env_path != "":
442
425
  certificate_config_path = env_path
426
+ source = (
427
+ f"environment variable {environment_vars.GOOGLE_API_CERTIFICATE_CONFIG}"
428
+ )
443
429
  else:
444
430
  env_path = environ.get(
445
431
  environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH,
@@ -447,11 +433,21 @@ def _get_cert_config_path(certificate_config_path=None, include_context_aware=Tr
447
433
  )
448
434
  if include_context_aware and env_path is not None and env_path != "":
449
435
  certificate_config_path = env_path
436
+ source = f"environment variable {environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH}"
450
437
  else:
451
- certificate_config_path = CERTIFICATE_CONFIGURATION_DEFAULT_PATH
438
+ certificate_config_path = os.path.join(
439
+ _cloud_sdk.get_config_path(), "certificate_config.json"
440
+ )
441
+ is_explicit = False
452
442
 
453
443
  certificate_config_path = path.expanduser(certificate_config_path)
454
444
  if not path.exists(certificate_config_path):
445
+ if is_explicit:
446
+ _LOGGER.debug(
447
+ "Certificate configuration file explicitly specified via %s at %s does not exist",
448
+ source,
449
+ certificate_config_path,
450
+ )
455
451
  return None
456
452
  return certificate_config_path
457
453
 
@@ -489,25 +485,6 @@ def _get_workload_cert_and_key_paths(config_path, include_context_aware=True):
489
485
  cert_path = workload["cert_path"]
490
486
  key_path = workload["key_path"]
491
487
 
492
- # == BEGIN Temporary Cloud Run PATCH ==
493
- # See https://github.com/googleapis/google-auth-library-python/issues/1881
494
- if (cert_path == _INCORRECT_CLOUD_RUN_CERT_PATH) and (
495
- key_path == _INCORRECT_CLOUD_RUN_KEY_PATH
496
- ):
497
- if not path.exists(cert_path) and not path.exists(key_path):
498
- _LOGGER.debug(
499
- "Applying Cloud Run certificate path patch. "
500
- "Configured paths not found: %s, %s. "
501
- "Using well-known paths: %s, %s",
502
- cert_path,
503
- key_path,
504
- _WELL_KNOWN_CLOUD_RUN_CERT_PATH,
505
- _WELL_KNOWN_CLOUD_RUN_KEY_PATH,
506
- )
507
- cert_path = _WELL_KNOWN_CLOUD_RUN_CERT_PATH
508
- key_path = _WELL_KNOWN_CLOUD_RUN_KEY_PATH
509
- # == END Temporary Cloud Run PATCH ==
510
-
511
488
  return cert_path, key_path
512
489
 
513
490
 
@@ -755,36 +732,33 @@ def check_use_client_cert():
755
732
  will default to False.
756
733
  If GOOGLE_API_USE_CLIENT_CERTIFICATE is unset, the value will be inferred
757
734
  as True (auto-enabled) if a workload config file exists (pointed at by
758
- GOOGLE_API_CERTIFICATE_CONFIG) containing a "workload" section.
735
+ GOOGLE_API_CERTIFICATE_CONFIG or CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH,
736
+ or the default path like ~/.config/gcloud/certificate_config.json)
737
+ containing a "workload" section.
759
738
  Otherwise, it returns False.
760
739
 
761
740
  Returns:
762
741
  bool: Whether the client certificate should be used for mTLS connection.
763
742
  """
764
- global _has_logged_mtls_warning
765
743
  env_override = _check_use_client_cert_env()
766
744
  if env_override is not None:
767
745
  return env_override
768
746
 
769
747
  # Auto-enablement checks (when GOOGLE_API_USE_CLIENT_CERTIFICATE is not set)
770
748
 
771
- # Check if the value of GOOGLE_API_CERTIFICATE_CONFIG is set.
772
- cert_path = getenv(environment_vars.GOOGLE_API_CERTIFICATE_CONFIG) or getenv(
773
- environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH
774
- )
749
+ # Check if a workload config file exists.
750
+ cert_path = _get_cert_config_path(include_context_aware=True)
775
751
 
776
752
  if cert_path:
777
753
  try:
778
754
  with open(cert_path, "r") as f:
779
755
  content = json.load(f)
780
756
  except (FileNotFoundError, OSError, json.JSONDecodeError) as e:
781
- if not _has_logged_mtls_warning:
782
- _LOGGER.warning(
783
- "mTLS auto-enablement failed: Could not read/parse certificate file at %s. Error: %s",
784
- cert_path,
785
- e,
786
- )
787
- _has_logged_mtls_warning = True
757
+ _LOGGER.debug(
758
+ "mTLS auto-enablement failed: Could not read/parse certificate file at %s. Error: %s",
759
+ cert_path,
760
+ e,
761
+ )
788
762
  return False
789
763
 
790
764
  # Structural validation
@@ -794,12 +768,10 @@ def check_use_client_cert():
794
768
  return True
795
769
 
796
770
  # If we got here, the file exists but the expected structure is missing
797
- if not _has_logged_mtls_warning:
798
- _LOGGER.warning(
799
- "mTLS auto-enablement failed: Certificate configuration file at %s is missing the required ['cert_configs']['workload'] section.",
800
- cert_path,
801
- )
802
- _has_logged_mtls_warning = True
771
+ _LOGGER.debug(
772
+ "mTLS auto-enablement failed: Certificate configuration file at %s is missing the required ['cert_configs']['workload'] section.",
773
+ cert_path,
774
+ )
803
775
  return False
804
776
 
805
777
 
@@ -24,7 +24,6 @@ from google.auth import environment_vars
24
24
  from google.auth import exceptions
25
25
  from google.auth.transport import _mtls_helper
26
26
 
27
-
28
27
  _LOGGER = logging.getLogger(__name__)
29
28
 
30
29
 
@@ -44,25 +43,18 @@ def has_default_client_cert_source(include_context_aware=True):
44
43
  Returns:
45
44
  bool: indicating if the default client cert source exists.
46
45
  """
46
+ cert_path = _mtls_helper._get_cert_config_path(
47
+ include_context_aware=include_context_aware
48
+ )
49
+ if cert_path is not None:
50
+ return True
47
51
  if (
48
52
  include_context_aware
49
53
  and _mtls_helper._check_config_path(_mtls_helper.CONTEXT_AWARE_METADATA_PATH)
50
54
  is not None
51
55
  ):
52
56
  return True
53
- if (
54
- _mtls_helper._check_config_path(
55
- _mtls_helper.CERTIFICATE_CONFIGURATION_DEFAULT_PATH
56
- )
57
- is not None
58
- ):
59
- return True
60
- cert_config_path = getenv("GOOGLE_API_CERTIFICATE_CONFIG")
61
- if (
62
- cert_config_path
63
- and _mtls_helper._check_config_path(cert_config_path) is not None
64
- ):
65
- return True
57
+
66
58
  return False
67
59
 
68
60
 
@@ -146,7 +138,9 @@ def should_use_client_cert():
146
138
  If GOOGLE_API_USE_CLIENT_CERTIFICATE is set to true or false, a corresponding
147
139
  bool value will be returned
148
140
  If GOOGLE_API_USE_CLIENT_CERTIFICATE is unset, the value will be inferred by
149
- reading a file pointed at by GOOGLE_API_CERTIFICATE_CONFIG, and verifying it
141
+ reading a file pointed at by GOOGLE_API_CERTIFICATE_CONFIG or
142
+ CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH, or the default path
143
+ like ~/.config/gcloud/certificate_config.json, and verifying it
150
144
  contains a "workload" section. If so, the function will return True,
151
145
  otherwise False.
152
146
 
@@ -208,7 +208,7 @@ class _MutualTlsAdapter(requests.adapters.HTTPAdapter):
208
208
  google.auth.exceptions.MutualTLSChannelError: If the cert or key is invalid.
209
209
  """
210
210
 
211
- def __init__(self, cert, key):
211
+ def __init__(self, cert, key, **kwargs):
212
212
  import certifi
213
213
  import ssl
214
214
 
@@ -250,7 +250,7 @@ class _MutualTlsAdapter(requests.adapters.HTTPAdapter):
250
250
  self._ctx_poolmanager = ctx_poolmanager
251
251
  self._ctx_proxymanager = ctx_proxymanager
252
252
 
253
- super(_MutualTlsAdapter, self).__init__()
253
+ super(_MutualTlsAdapter, self).__init__(**kwargs)
254
254
 
255
255
  def init_poolmanager(self, *args, **kwargs):
256
256
  kwargs["ssl_context"] = self._ctx_poolmanager
@@ -457,6 +457,11 @@ class AuthorizedSession(requests.Session):
457
457
  If the callback is None, application default SSL credentials
458
458
  will be used.
459
459
 
460
+ .. warning::
461
+ Calling this method mutates the underlying `requests.Session` adapter
462
+ dictionary. It is not thread-safe to call this explicitly while other
463
+ threads are making requests.
464
+
460
465
  Raises:
461
466
  google.auth.exceptions.MutualTLSChannelError: If mutual TLS channel
462
467
  creation failed for any reason. The existing session state (such
@@ -475,10 +480,58 @@ class AuthorizedSession(requests.Session):
475
480
  client_cert_callback
476
481
  )
477
482
 
483
+ old_adapter = self.adapters.get("https://")
484
+
485
+ kwargs = {}
486
+ if old_adapter is not None:
487
+ kwargs["max_retries"] = getattr(old_adapter, "max_retries", 0)
488
+ kwargs["pool_connections"] = getattr(
489
+ old_adapter, "_pool_connections", requests.adapters.DEFAULT_POOLSIZE
490
+ )
491
+ kwargs["pool_maxsize"] = getattr(
492
+ old_adapter, "_pool_maxsize", requests.adapters.DEFAULT_POOLSIZE
493
+ )
494
+ kwargs["pool_block"] = getattr(
495
+ old_adapter, "_pool_block", requests.adapters.DEFAULT_POOLBLOCK
496
+ )
497
+
498
+ old_auth_adapter = None
499
+ auth_kwargs = {}
500
+ if self._auth_request_session is not None:
501
+ old_auth_adapter = self._auth_request_session.adapters.get("https://")
502
+
503
+ if old_auth_adapter is not None:
504
+ auth_kwargs["max_retries"] = getattr(
505
+ old_auth_adapter, "max_retries", 0
506
+ )
507
+ auth_kwargs["pool_connections"] = getattr(
508
+ old_auth_adapter,
509
+ "_pool_connections",
510
+ requests.adapters.DEFAULT_POOLSIZE,
511
+ )
512
+ auth_kwargs["pool_maxsize"] = getattr(
513
+ old_auth_adapter,
514
+ "_pool_maxsize",
515
+ requests.adapters.DEFAULT_POOLSIZE,
516
+ )
517
+ auth_kwargs["pool_block"] = getattr(
518
+ old_auth_adapter,
519
+ "_pool_block",
520
+ requests.adapters.DEFAULT_POOLBLOCK,
521
+ )
522
+
478
523
  if is_mtls:
479
- new_adapter = _MutualTlsAdapter(cert, key)
524
+ new_adapter = _MutualTlsAdapter(cert, key, **kwargs)
525
+ if self._auth_request_session is not None:
526
+ new_auth_adapter = _MutualTlsAdapter(cert, key, **auth_kwargs)
527
+ else:
528
+ new_auth_adapter = None
480
529
  else:
481
- new_adapter = requests.adapters.HTTPAdapter()
530
+ new_adapter = requests.adapters.HTTPAdapter(**kwargs)
531
+ if self._auth_request_session is not None:
532
+ new_auth_adapter = requests.adapters.HTTPAdapter(**auth_kwargs)
533
+ else:
534
+ new_auth_adapter = None
482
535
  except (
483
536
  exceptions.ClientCertError,
484
537
  ImportError,
@@ -489,6 +542,19 @@ class AuthorizedSession(requests.Session):
489
542
  raise new_exc from caught_exc
490
543
 
491
544
  self.mount("https://", new_adapter)
545
+
546
+ if old_adapter is not None and old_adapter is not new_adapter:
547
+ old_adapter.close()
548
+
549
+ if self._auth_request_session is not None and new_auth_adapter is not None:
550
+ self._auth_request_session.mount("https://", new_auth_adapter)
551
+
552
+ if (
553
+ old_auth_adapter is not None
554
+ and old_auth_adapter is not new_auth_adapter
555
+ ):
556
+ old_auth_adapter.close()
557
+
492
558
  self._is_mtls = is_mtls
493
559
  if is_mtls:
494
560
  self._cached_cert = cert
@@ -335,6 +335,11 @@ class AuthorizedHttp(RequestMethods): # type: ignore
335
335
  If the callback is None, application default SSL credentials
336
336
  will be used.
337
337
 
338
+ .. warning::
339
+ Calling this method mutates the underlying `urllib3.PoolManager`.
340
+ It is not thread-safe to call this explicitly while other
341
+ threads are making requests.
342
+
338
343
  Returns:
339
344
  True if the channel is mutual TLS and False otherwise.
340
345
 
@@ -367,9 +372,15 @@ class AuthorizedHttp(RequestMethods): # type: ignore
367
372
  new_exc = exceptions.MutualTLSChannelError(caught_exc)
368
373
  raise new_exc from caught_exc
369
374
 
375
+ old_http = self.http
376
+
370
377
  self.http = new_http
371
378
  self._is_mtls = new_is_mtls
372
379
  self._request.http = new_http
380
+
381
+ if old_http is not None and old_http is not new_http:
382
+ getattr(old_http, "clear", getattr(old_http, "close", lambda: None))()
383
+
373
384
  if new_is_mtls:
374
385
  self._cached_cert = cert
375
386
  else:
@@ -491,7 +502,7 @@ class AuthorizedHttp(RequestMethods): # type: ignore
491
502
 
492
503
  def __del__(self):
493
504
  if hasattr(self, "http") and self.http is not None:
494
- self.http.clear()
505
+ getattr(self.http, "clear", getattr(self.http, "close", lambda: None))()
495
506
 
496
507
  @property
497
508
  def headers(self):
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "2.56.0"
15
+ __version__ = "2.56.2"
@@ -514,8 +514,12 @@ class Credentials(
514
514
 
515
515
  Returns:
516
516
  Optional[str]: The URL for the Regional Access Boundary lookup endpoint, or None
517
- if the service account email is missing.
517
+ if the service account email is missing. Returns None if the subject is populated.
518
518
  """
519
+ if self._subject:
520
+ # RAB does not apply to Workspace User Accounts via Domain-wide Delegation.
521
+ return None
522
+
519
523
  if not self.service_account_email:
520
524
  _LOGGER.error(
521
525
  "Service account email is required to build the Regional Access Boundary lookup URL for service account credentials."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-auth
3
- Version: 2.56.0
3
+ Version: 2.56.2
4
4
  Summary: Google Authentication Library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth
6
6
  Author: Google Cloud Platform