fix: use gcloud creds flow (#705)
diff --git a/google/auth/_default.py b/google/auth/_default.py
index 8e3b210..4dc0725 100644
--- a/google/auth/_default.py
+++ b/google/auth/_default.py
@@ -198,12 +198,25 @@
def _get_explicit_environ_credentials():
"""Gets credentials from the GOOGLE_APPLICATION_CREDENTIALS environment
variable."""
+ from google.auth import _cloud_sdk
+
+ cloud_sdk_adc_path = _cloud_sdk.get_application_default_credentials_path()
explicit_file = os.environ.get(environment_vars.CREDENTIALS)
_LOGGER.debug(
"Checking %s for explicit credentials as part of auth process...", explicit_file
)
+ if explicit_file is not None and explicit_file == cloud_sdk_adc_path:
+ # Cloud sdk flow calls gcloud to fetch project id, so if the explicit
+ # file path is cloud sdk credentials path, then we should fall back
+ # to cloud sdk flow, otherwise project id cannot be obtained.
+ _LOGGER.debug(
+ "Explicit credentials path %s is the same as Cloud SDK credentials path, fall back to Cloud SDK credentials flow...",
+ explicit_file,
+ )
+ return _get_gcloud_sdk_credentials()
+
if explicit_file is not None:
credentials, project_id = load_credentials_from_file(
os.environ[environment_vars.CREDENTIALS]
diff --git a/google/auth/_default_async.py b/google/auth/_default_async.py
index 1a725af..d12a642 100644
--- a/google/auth/_default_async.py
+++ b/google/auth/_default_async.py
@@ -127,8 +127,17 @@
def _get_explicit_environ_credentials():
"""Gets credentials from the GOOGLE_APPLICATION_CREDENTIALS environment
variable."""
+ from google.auth import _cloud_sdk
+
+ cloud_sdk_adc_path = _cloud_sdk.get_application_default_credentials_path()
explicit_file = os.environ.get(environment_vars.CREDENTIALS)
+ if explicit_file is not None and explicit_file == cloud_sdk_adc_path:
+ # Cloud sdk flow calls gcloud to fetch project id, so if the explicit
+ # file path is cloud sdk credentials path, then we should fall back
+ # to cloud sdk flow, otherwise project id cannot be obtained.
+ return _get_gcloud_sdk_credentials()
+
if explicit_file is not None:
credentials, project_id = load_credentials_from_file(
os.environ[environment_vars.CREDENTIALS]
diff --git a/tests/test__default.py b/tests/test__default.py
index 74ed618..e136896 100644
--- a/tests/test__default.py
+++ b/tests/test__default.py
@@ -350,6 +350,24 @@
assert project_id is None
+@mock.patch(
+ "google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True
+)
+@mock.patch("google.auth._default._get_gcloud_sdk_credentials", autospec=True)
+def test__get_explicit_environ_credentials_fallback_to_gcloud(
+ get_gcloud_creds, get_adc_path, monkeypatch
+):
+ # Set explicit credentials path to cloud sdk credentials path.
+ get_adc_path.return_value = "filename"
+ monkeypatch.setenv(environment_vars.CREDENTIALS, "filename")
+
+ _default._get_explicit_environ_credentials()
+
+ # Check we fall back to cloud sdk flow since explicit credentials path is
+ # cloud sdk credentials path
+ get_gcloud_creds.assert_called_once()
+
+
@LOAD_FILE_PATCH
@mock.patch(
"google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True
diff --git a/tests_async/test__default_async.py b/tests_async/test__default_async.py
index bca396a..527a8da 100644
--- a/tests_async/test__default_async.py
+++ b/tests_async/test__default_async.py
@@ -187,6 +187,24 @@
assert project_id is None
+@mock.patch(
+ "google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True
+)
+@mock.patch("google.auth._default_async._get_gcloud_sdk_credentials", autospec=True)
+def test__get_explicit_environ_credentials_fallback_to_gcloud(
+ get_gcloud_creds, get_adc_path, monkeypatch
+):
+ # Set explicit credentials path to cloud sdk credentials path.
+ get_adc_path.return_value = "filename"
+ monkeypatch.setenv(environment_vars.CREDENTIALS, "filename")
+
+ _default._get_explicit_environ_credentials()
+
+ # Check we fall back to cloud sdk flow since explicit credentials path is
+ # cloud sdk credentials path
+ get_gcloud_creds.assert_called_once()
+
+
@LOAD_FILE_PATCH
@mock.patch(
"google.auth._cloud_sdk.get_application_default_credentials_path", autospec=True