Skip to content

Commit e82764b

Browse files
ljyanesmljyanesm
andauthored
Refactor GS authentication to use default credentials (#514)
* Refactor authentication to use default credentials for Google Cloud Storage client This enables federated identity Updates HISTORY.md * Keeps same functionality for API whilst enhancing the env var alternative * Simplifies credential handling logic, and updates docstring * Updates HISTORY.md --------- Co-authored-by: ljyanesm <[email protected]>
1 parent 863e884 commit e82764b

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

HISTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## v0.21.1 (2025-05-14)
44

5+
- Fixed issue with GS credentials, using default auth enables a wider set of authentication methods in GS (Issue [#390](https://github.com/drivendataorg/cloudpathlib/issues/390), PR [#514](https://github.com/drivendataorg/cloudpathlib/pull/514), thanks @ljyanesm)
56
- Fixed `rmtree` fail on Azure with no `hns` and more than 256 blobs to drop (Issue [#509](https://github.com/drivendataorg/cloudpathlib/issues/509), PR [#508](https://github.com/drivendataorg/cloudpathlib/pull/508), thanks @alikefia)
67

78
## v0.21.0 (2025-03-03)

cloudpathlib/gs/gsclient.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from google.auth.credentials import Credentials
1616
from google.api_core.retry import Retry
1717

18+
from google.auth import default as google_default_auth
1819
from google.auth.exceptions import DefaultCredentialsError
1920
from google.cloud.storage import Client as StorageClient
2021

@@ -51,18 +52,14 @@ def __init__(
5152
):
5253
"""Class constructor. Sets up a [`Storage
5354
Client`](https://googleapis.dev/python/storage/latest/client.html).
54-
Supports the following authentication methods of `Storage Client`.
55+
Supports, in this order, the following authentication methods of `Storage Client`.
5556
56-
- Environment variable `"GOOGLE_APPLICATION_CREDENTIALS"` containing a
57-
path to a JSON credentials file for a Google service account. See
58-
[Authenticating as a Service
59-
Account](https://cloud.google.com/docs/authentication/production).
60-
- File path to a JSON credentials file for a Google service account.
61-
- OAuth2 Credentials object and a project name.
6257
- Instantiated and already authenticated `Storage Client`.
58+
- OAuth2 Credentials object and a project name.
59+
- File path to a JSON credentials file for a Google service account.
60+
- Google Cloud SDK default credentials. See [How Application Default Credentials works](https://cloud.google.com/docs/authentication/application-default-credentials)
6361
64-
If multiple methods are used, priority order is reverse of list above
65-
(later in list takes priority). If no authentication methods are used,
62+
If no authentication methods are used,
6663
then the client will be instantiated as anonymous, which will only have
6764
access to public buckets.
6865
@@ -91,18 +88,24 @@ def __init__(
9188
timeout (Optional[float]): Cloud Storage [timeout value](https://cloud.google.com/python/docs/reference/storage/1.39.0/retry_timeout)
9289
retry (Optional[google.api_core.retry.Retry]): Cloud Storage [retry configuration](https://cloud.google.com/python/docs/reference/storage/1.39.0/retry_timeout#configuring-retries)
9390
"""
94-
if application_credentials is None:
95-
application_credentials = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
96-
91+
# don't check `GOOGLE_APPLICATION_CREDENTIALS` since `google_default_auth` already does that
92+
# use explicit client
9793
if storage_client is not None:
9894
self.client = storage_client
95+
# use explicit credentials
9996
elif credentials is not None:
10097
self.client = StorageClient(credentials=credentials, project=project)
98+
# use explicit credential file
10199
elif application_credentials is not None:
102100
self.client = StorageClient.from_service_account_json(application_credentials)
101+
# use default credentials based on SDK precedence
103102
else:
104103
try:
105-
self.client = StorageClient()
104+
# use `google_default_auth` instead of `StorageClient()` since it
105+
# handles precedence of creds in different locations properly
106+
credentials, default_project = google_default_auth()
107+
project = project or default_project # use explicit project if present
108+
self.client = StorageClient(credentials=credentials, project=project)
106109
except DefaultCredentialsError:
107110
self.client = StorageClient.create_anonymous_client()
108111

0 commit comments

Comments
 (0)