Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/auth/_default.py: 18%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

216 statements  

1# Copyright 2015 Google Inc. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Application default credentials. 

16 

17Implements application default credentials and project ID detection. 

18""" 

19 

20import io 

21import json 

22import logging 

23import os 

24import warnings 

25 

26from google.auth import environment_vars 

27from google.auth import exceptions 

28import google.auth.transport._http_client 

29 

30_LOGGER = logging.getLogger(__name__) 

31 

32# Valid types accepted for file-based credentials. 

33_AUTHORIZED_USER_TYPE = "authorized_user" 

34_SERVICE_ACCOUNT_TYPE = "service_account" 

35_EXTERNAL_ACCOUNT_TYPE = "external_account" 

36_EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE = "external_account_authorized_user" 

37_IMPERSONATED_SERVICE_ACCOUNT_TYPE = "impersonated_service_account" 

38_GDCH_SERVICE_ACCOUNT_TYPE = "gdch_service_account" 

39_VALID_TYPES = ( 

40 _AUTHORIZED_USER_TYPE, 

41 _SERVICE_ACCOUNT_TYPE, 

42 _EXTERNAL_ACCOUNT_TYPE, 

43 _EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE, 

44 _IMPERSONATED_SERVICE_ACCOUNT_TYPE, 

45 _GDCH_SERVICE_ACCOUNT_TYPE, 

46) 

47 

48# Help message when no credentials can be found. 

49_CLOUD_SDK_MISSING_CREDENTIALS = """\ 

50Your default credentials were not found. To set up Application Default Credentials, \ 

51see https://cloud.google.com/docs/authentication/external/set-up-adc for more information.\ 

52""" 

53 

54# Warning when using Cloud SDK user credentials 

55_CLOUD_SDK_CREDENTIALS_WARNING = """\ 

56Your application has authenticated using end user credentials from Google \ 

57Cloud SDK without a quota project. You might receive a "quota exceeded" \ 

58or "API not enabled" error. See the following page for troubleshooting: \ 

59https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds. \ 

60""" 

61 

62_GENERIC_LOAD_METHOD_WARNING = """\ 

63The {} method is deprecated because of a potential security risk. 

64 

65This method does not validate the credential configuration. The security 

66risk occurs when a credential configuration is accepted from a source that 

67is not under your control and used without validation on your side. 

68 

69If you know that you will be loading credential configurations of a 

70specific type, it is recommended to use a credential-type-specific 

71load method. 

72This will ensure that an unexpected credential type with potential for 

73malicious intent is not loaded unintentionally. You might still have to do 

74validation for certain credential types. Please follow the recommendations 

75for that method. For example, if you want to load only service accounts, 

76you can create the service account credentials explicitly: 

77 

78``` 

79from google.oauth2 import service_account 

80creds = service_account.Credentials.from_service_account_file(filename) 

81``` 

82 

83If you are loading your credential configuration from an untrusted source and have 

84not mitigated the risks (e.g. by validating the configuration yourself), make 

85these changes as soon as possible to prevent security risks to your environment. 

86 

87Regardless of the method used, it is always your responsibility to validate 

88configurations received from external sources. 

89 

90Refer to https://cloud.google.com/docs/authentication/external/externally-sourced-credentials 

91for more details. 

92""" 

93 

94# The subject token type used for AWS external_account credentials. 

95_AWS_SUBJECT_TOKEN_TYPE = "urn:ietf:params:aws:token-type:aws4_request" 

96 

97 

98def _warn_about_problematic_credentials(credentials): 

99 """Determines if the credentials are problematic. 

100 

101 Credentials from the Cloud SDK that are associated with Cloud SDK's project 

102 are problematic because they may not have APIs enabled and have limited 

103 quota. If this is the case, warn about it. 

104 """ 

105 from google.auth import _cloud_sdk 

106 

107 if credentials.client_id == _cloud_sdk.CLOUD_SDK_CLIENT_ID: 

108 warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING) 

109 

110 

111def _warn_about_generic_load_method(method_name): # pragma: NO COVER 

112 """Warns that a generic load method is being used. 

113 

114 This is to discourage use of the generic load methods in favor of 

115 more specific methods. The generic methods are more likely to lead to 

116 security issues if the input is not validated. 

117 

118 Args: 

119 method_name (str): The name of the method being used. 

120 """ 

121 

122 warnings.warn(_GENERIC_LOAD_METHOD_WARNING.format(method_name), DeprecationWarning) 

123 

124 

125def load_credentials_from_file( 

126 filename, scopes=None, default_scopes=None, quota_project_id=None, request=None 

127): 

128 """Loads Google credentials from a file. 

129 

130 The credentials file must be a service account key, stored authorized 

131 user credentials, external account credentials, or impersonated service 

132 account credentials. 

133 

134 .. warning:: 

135 Important: If you accept a credential configuration (credential JSON/File/Stream) 

136 from an external source for authentication to Google Cloud Platform, you must 

137 validate it before providing it to any Google API or client library. Providing an 

138 unvalidated credential configuration to Google APIs or libraries can compromise 

139 the security of your systems and data. For more information, refer to 

140 `Validate credential configurations from external sources`_. 

141 

142 .. _Validate credential configurations from external sources: 

143 https://cloud.google.com/docs/authentication/external/externally-sourced-credentials 

144 

145 Args: 

146 filename (str): The full path to the credentials file. 

147 scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If 

148 specified, the credentials will automatically be scoped if 

149 necessary 

150 default_scopes (Optional[Sequence[str]]): Default scopes passed by a 

151 Google client library. Use 'scopes' for user-defined scopes. 

152 quota_project_id (Optional[str]): The project ID used for 

153 quota and billing. 

154 request (Optional[google.auth.transport.Request]): An object used to make 

155 HTTP requests. This is used to determine the associated project ID 

156 for a workload identity pool resource (external account credentials). 

157 If not specified, then it will use a 

158 google.auth.transport.requests.Request client to make requests. 

159 

160 Returns: 

161 Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded 

162 credentials and the project ID. Authorized user credentials do not 

163 have the project ID information. External account credentials project 

164 IDs may not always be determined. 

165 

166 Raises: 

167 google.auth.exceptions.DefaultCredentialsError: if the file is in the 

168 wrong format or is missing. 

169 """ 

170 _warn_about_generic_load_method("load_credentials_from_file") 

171 

172 if not os.path.exists(filename): 

173 raise exceptions.DefaultCredentialsError( 

174 "File {} was not found.".format(filename) 

175 ) 

176 

177 with io.open(filename, "r") as file_obj: 

178 try: 

179 info = json.load(file_obj) 

180 except ValueError as caught_exc: 

181 new_exc = exceptions.DefaultCredentialsError( 

182 "File {} is not a valid json file.".format(filename), caught_exc 

183 ) 

184 raise new_exc from caught_exc 

185 return _load_credentials_from_info( 

186 filename, info, scopes, default_scopes, quota_project_id, request 

187 ) 

188 

189 

190def load_credentials_from_dict( 

191 info, scopes=None, default_scopes=None, quota_project_id=None, request=None 

192): 

193 """Loads Google credentials from a dict. 

194 

195 The credentials file must be a service account key, stored authorized 

196 user credentials, external account credentials, or impersonated service 

197 account credentials. 

198 

199 .. warning:: 

200 Important: If you accept a credential configuration (credential JSON/File/Stream) 

201 from an external source for authentication to Google Cloud Platform, you must 

202 validate it before providing it to any Google API or client library. Providing an 

203 unvalidated credential configuration to Google APIs or libraries can compromise 

204 the security of your systems and data. For more information, refer to 

205 `Validate credential configurations from external sources`_. 

206 

207 .. _Validate credential configurations from external sources: 

208 https://cloud.google.com/docs/authentication/external/externally-sourced-credentials 

209 

210 Args: 

211 info (Dict[str, Any]): A dict object containing the credentials 

212 scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If 

213 specified, the credentials will automatically be scoped if 

214 necessary 

215 default_scopes (Optional[Sequence[str]]): Default scopes passed by a 

216 Google client library. Use 'scopes' for user-defined scopes. 

217 quota_project_id (Optional[str]): The project ID used for 

218 quota and billing. 

219 request (Optional[google.auth.transport.Request]): An object used to make 

220 HTTP requests. This is used to determine the associated project ID 

221 for a workload identity pool resource (external account credentials). 

222 If not specified, then it will use a 

223 google.auth.transport.requests.Request client to make requests. 

224 

225 Returns: 

226 Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded 

227 credentials and the project ID. Authorized user credentials do not 

228 have the project ID information. External account credentials project 

229 IDs may not always be determined. 

230 

231 Raises: 

232 google.auth.exceptions.DefaultCredentialsError: if the file is in the 

233 wrong format or is missing. 

234 """ 

235 _warn_about_generic_load_method("load_credentials_from_dict") 

236 if not isinstance(info, dict): 

237 raise exceptions.DefaultCredentialsError( 

238 "info object was of type {} but dict type was expected.".format(type(info)) 

239 ) 

240 

241 return _load_credentials_from_info( 

242 "dict object", info, scopes, default_scopes, quota_project_id, request 

243 ) 

244 

245 

246def _load_credentials_from_info( 

247 filename, info, scopes, default_scopes, quota_project_id, request 

248): 

249 from google.auth.credentials import CredentialsWithQuotaProject 

250 

251 credential_type = info.get("type") 

252 

253 if credential_type == _AUTHORIZED_USER_TYPE: 

254 credentials, project_id = _get_authorized_user_credentials( 

255 filename, info, scopes 

256 ) 

257 

258 elif credential_type == _SERVICE_ACCOUNT_TYPE: 

259 credentials, project_id = _get_service_account_credentials( 

260 filename, info, scopes, default_scopes 

261 ) 

262 

263 elif credential_type == _EXTERNAL_ACCOUNT_TYPE: 

264 credentials, project_id = _get_external_account_credentials( 

265 info, 

266 filename, 

267 scopes=scopes, 

268 default_scopes=default_scopes, 

269 request=request, 

270 ) 

271 

272 elif credential_type == _EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE: 

273 credentials, project_id = _get_external_account_authorized_user_credentials( 

274 filename, info, request 

275 ) 

276 

277 elif credential_type == _IMPERSONATED_SERVICE_ACCOUNT_TYPE: 

278 credentials, project_id = _get_impersonated_service_account_credentials( 

279 filename, info, scopes 

280 ) 

281 elif credential_type == _GDCH_SERVICE_ACCOUNT_TYPE: 

282 credentials, project_id = _get_gdch_service_account_credentials(filename, info) 

283 else: 

284 raise exceptions.DefaultCredentialsError( 

285 "The file {file} does not have a valid type. " 

286 "Type is {type}, expected one of {valid_types}.".format( 

287 file=filename, type=credential_type, valid_types=_VALID_TYPES 

288 ) 

289 ) 

290 if isinstance(credentials, CredentialsWithQuotaProject): 

291 credentials = _apply_quota_project_id(credentials, quota_project_id) 

292 return credentials, project_id 

293 

294 

295def _get_gcloud_sdk_credentials(quota_project_id=None): 

296 """Gets the credentials and project ID from the Cloud SDK.""" 

297 from google.auth import _cloud_sdk 

298 

299 _LOGGER.debug("Checking Cloud SDK credentials as part of auth process...") 

300 

301 # Check if application default credentials exist. 

302 credentials_filename = _cloud_sdk.get_application_default_credentials_path() 

303 

304 if not os.path.isfile(credentials_filename): 

305 _LOGGER.debug("Cloud SDK credentials not found on disk; not using them") 

306 return None, None 

307 

308 with warnings.catch_warnings(): 

309 warnings.simplefilter("ignore", DeprecationWarning) 

310 credentials, project_id = load_credentials_from_file( 

311 credentials_filename, quota_project_id=quota_project_id 

312 ) 

313 credentials._cred_file_path = credentials_filename 

314 

315 if not project_id: 

316 project_id = _cloud_sdk.get_project_id() 

317 

318 return credentials, project_id 

319 

320 

321def _get_explicit_environ_credentials(quota_project_id=None): 

322 """Gets credentials from the GOOGLE_APPLICATION_CREDENTIALS environment 

323 variable.""" 

324 from google.auth import _cloud_sdk 

325 

326 cloud_sdk_adc_path = _cloud_sdk.get_application_default_credentials_path() 

327 explicit_file = os.environ.get(environment_vars.CREDENTIALS) 

328 

329 _LOGGER.debug( 

330 "Checking %s for explicit credentials as part of auth process...", explicit_file 

331 ) 

332 

333 if explicit_file is not None and explicit_file == cloud_sdk_adc_path: 

334 # Cloud sdk flow calls gcloud to fetch project id, so if the explicit 

335 # file path is cloud sdk credentials path, then we should fall back 

336 # to cloud sdk flow, otherwise project id cannot be obtained. 

337 _LOGGER.debug( 

338 "Explicit credentials path %s is the same as Cloud SDK credentials path, fall back to Cloud SDK credentials flow...", 

339 explicit_file, 

340 ) 

341 return _get_gcloud_sdk_credentials(quota_project_id=quota_project_id) 

342 

343 if explicit_file is not None: 

344 with warnings.catch_warnings(): 

345 warnings.simplefilter("ignore", DeprecationWarning) 

346 credentials, project_id = load_credentials_from_file( 

347 os.environ[environment_vars.CREDENTIALS], 

348 quota_project_id=quota_project_id, 

349 ) 

350 credentials._cred_file_path = f"{explicit_file} file via the GOOGLE_APPLICATION_CREDENTIALS environment variable" 

351 

352 return credentials, project_id 

353 

354 else: 

355 return None, None 

356 

357 

358def _get_gae_credentials(): 

359 """Gets Google App Engine App Identity credentials and project ID.""" 

360 # If not GAE gen1, prefer the metadata service even if the GAE APIs are 

361 # available as per https://google.aip.dev/auth/4115. 

362 if os.environ.get(environment_vars.LEGACY_APPENGINE_RUNTIME) != "python27": 

363 return None, None 

364 

365 # While this library is normally bundled with app_engine, there are 

366 # some cases where it's not available, so we tolerate ImportError. 

367 try: 

368 _LOGGER.debug("Checking for App Engine runtime as part of auth process...") 

369 import google.auth.app_engine as app_engine 

370 except ImportError: 

371 _LOGGER.warning("Import of App Engine auth library failed.") 

372 return None, None 

373 

374 try: 

375 credentials = app_engine.Credentials() 

376 project_id = app_engine.get_project_id() 

377 return credentials, project_id 

378 except EnvironmentError: 

379 _LOGGER.debug( 

380 "No App Engine library was found so cannot authentication via App Engine Identity Credentials." 

381 ) 

382 return None, None 

383 

384 

385def _get_gce_credentials(request=None, quota_project_id=None): 

386 """Gets credentials and project ID from the GCE Metadata Service.""" 

387 # Ping requires a transport, but we want application default credentials 

388 # to require no arguments. So, we'll use the _http_client transport which 

389 # uses http.client. This is only acceptable because the metadata server 

390 # doesn't do SSL and never requires proxies. 

391 

392 # While this library is normally bundled with compute_engine, there are 

393 # some cases where it's not available, so we tolerate ImportError. 

394 try: 

395 from google.auth import compute_engine 

396 from google.auth.compute_engine import _metadata 

397 except ImportError: 

398 _LOGGER.warning("Import of Compute Engine auth library failed.") 

399 return None, None 

400 

401 if request is None: 

402 request = google.auth.transport._http_client.Request() 

403 

404 if _metadata.is_on_gce(request=request): 

405 # Get the project ID. 

406 try: 

407 project_id = _metadata.get_project_id(request=request) 

408 except exceptions.TransportError: 

409 project_id = None 

410 

411 cred = compute_engine.Credentials() 

412 cred = _apply_quota_project_id(cred, quota_project_id) 

413 

414 return cred, project_id 

415 else: 

416 _LOGGER.warning( 

417 "Authentication failed using Compute Engine authentication due to unavailable metadata server." 

418 ) 

419 return None, None 

420 

421 

422def _get_external_account_credentials( 

423 info, filename, scopes=None, default_scopes=None, request=None 

424): 

425 """Loads external account Credentials from the parsed external account info. 

426 

427 The credentials information must correspond to a supported external account 

428 credentials. 

429 

430 Args: 

431 info (Mapping[str, str]): The external account info in Google format. 

432 filename (str): The full path to the credentials file. 

433 scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If 

434 specified, the credentials will automatically be scoped if 

435 necessary. 

436 default_scopes (Optional[Sequence[str]]): Default scopes passed by a 

437 Google client library. Use 'scopes' for user-defined scopes. 

438 request (Optional[google.auth.transport.Request]): An object used to make 

439 HTTP requests. This is used to determine the associated project ID 

440 for a workload identity pool resource (external account credentials). 

441 If not specified, then it will use a 

442 google.auth.transport.requests.Request client to make requests. 

443 

444 Returns: 

445 Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded 

446 credentials and the project ID. External account credentials project 

447 IDs may not always be determined. 

448 

449 Raises: 

450 google.auth.exceptions.DefaultCredentialsError: if the info dictionary 

451 is in the wrong format or is missing required information. 

452 """ 

453 # There are currently 3 types of external_account credentials. 

454 if info.get("subject_token_type") == _AWS_SUBJECT_TOKEN_TYPE: 

455 # Check if configuration corresponds to an AWS credentials. 

456 from google.auth import aws 

457 

458 credentials = aws.Credentials.from_info( 

459 info, scopes=scopes, default_scopes=default_scopes 

460 ) 

461 elif ( 

462 info.get("credential_source") is not None 

463 and info.get("credential_source").get("executable") is not None 

464 ): 

465 from google.auth import pluggable 

466 

467 credentials = pluggable.Credentials.from_info( 

468 info, scopes=scopes, default_scopes=default_scopes 

469 ) 

470 else: 

471 try: 

472 # Check if configuration corresponds to an Identity Pool credentials. 

473 from google.auth import identity_pool 

474 

475 credentials = identity_pool.Credentials.from_info( 

476 info, scopes=scopes, default_scopes=default_scopes 

477 ) 

478 except ValueError: 

479 # If the configuration is invalid or does not correspond to any 

480 # supported external_account credentials, raise an error. 

481 raise exceptions.DefaultCredentialsError( 

482 "Failed to load external account credentials from {}".format(filename) 

483 ) 

484 if request is None: 

485 import google.auth.transport.requests 

486 

487 request = google.auth.transport.requests.Request() 

488 

489 return credentials, credentials.get_project_id(request=request) 

490 

491 

492def _get_external_account_authorized_user_credentials( 

493 filename, info, scopes=None, default_scopes=None, request=None 

494): 

495 try: 

496 from google.auth import external_account_authorized_user 

497 

498 credentials = external_account_authorized_user.Credentials.from_info(info) 

499 except ValueError: 

500 raise exceptions.DefaultCredentialsError( 

501 "Failed to load external account authorized user credentials from {}".format( 

502 filename 

503 ) 

504 ) 

505 

506 return credentials, None 

507 

508 

509def _get_authorized_user_credentials(filename, info, scopes=None): 

510 from google.oauth2 import credentials 

511 

512 try: 

513 credentials = credentials.Credentials.from_authorized_user_info( 

514 info, scopes=scopes 

515 ) 

516 except ValueError as caught_exc: 

517 msg = "Failed to load authorized user credentials from {}".format(filename) 

518 new_exc = exceptions.DefaultCredentialsError(msg, caught_exc) 

519 raise new_exc from caught_exc 

520 return credentials, None 

521 

522 

523def _get_service_account_credentials(filename, info, scopes=None, default_scopes=None): 

524 from google.oauth2 import service_account 

525 

526 try: 

527 credentials = service_account.Credentials.from_service_account_info( 

528 info, scopes=scopes, default_scopes=default_scopes 

529 ) 

530 except ValueError as caught_exc: 

531 msg = "Failed to load service account credentials from {}".format(filename) 

532 new_exc = exceptions.DefaultCredentialsError(msg, caught_exc) 

533 raise new_exc from caught_exc 

534 return credentials, info.get("project_id") 

535 

536 

537def _get_impersonated_service_account_credentials(filename, info, scopes): 

538 from google.auth import impersonated_credentials 

539 

540 try: 

541 credentials = impersonated_credentials.Credentials.from_impersonated_service_account_info( 

542 info, scopes=scopes 

543 ) 

544 except ValueError as caught_exc: 

545 msg = "Failed to load impersonated service account credentials from {}".format( 

546 filename 

547 ) 

548 new_exc = exceptions.DefaultCredentialsError(msg, caught_exc) 

549 raise new_exc from caught_exc 

550 return credentials, None 

551 

552 

553def _get_gdch_service_account_credentials(filename, info): 

554 from google.oauth2 import gdch_credentials 

555 

556 try: 

557 credentials = gdch_credentials.ServiceAccountCredentials.from_service_account_info( 

558 info 

559 ) 

560 except ValueError as caught_exc: 

561 msg = "Failed to load GDCH service account credentials from {}".format(filename) 

562 new_exc = exceptions.DefaultCredentialsError(msg, caught_exc) 

563 raise new_exc from caught_exc 

564 return credentials, info.get("project") 

565 

566 

567def get_api_key_credentials(key): 

568 """Return credentials with the given API key.""" 

569 from google.auth import api_key 

570 

571 return api_key.Credentials(key) 

572 

573 

574def _apply_quota_project_id(credentials, quota_project_id): 

575 if quota_project_id: 

576 credentials = credentials.with_quota_project(quota_project_id) 

577 else: 

578 credentials = credentials.with_quota_project_from_environment() 

579 

580 from google.oauth2 import credentials as authorized_user_credentials 

581 

582 if isinstance(credentials, authorized_user_credentials.Credentials) and ( 

583 not credentials.quota_project_id 

584 ): 

585 _warn_about_problematic_credentials(credentials) 

586 return credentials 

587 

588 

589def default(scopes=None, request=None, quota_project_id=None, default_scopes=None): 

590 """Gets the default credentials for the current environment. 

591 

592 `Application Default Credentials`_ provides an easy way to obtain 

593 credentials to call Google APIs for server-to-server or local applications. 

594 This function acquires credentials from the environment in the following 

595 order: 

596 

597 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set 

598 to the path of a valid service account JSON private key file, then it is 

599 loaded and returned. The project ID returned is the project ID defined 

600 in the service account file if available (some older files do not 

601 contain project ID information). 

602 

603 If the environment variable is set to the path of a valid external 

604 account JSON configuration file (workload identity federation), then the 

605 configuration file is used to determine and retrieve the external 

606 credentials from the current environment (AWS, Azure, etc). 

607 These will then be exchanged for Google access tokens via the Google STS 

608 endpoint. 

609 The project ID returned in this case is the one corresponding to the 

610 underlying workload identity pool resource if determinable. 

611 

612 If the environment variable is set to the path of a valid GDCH service 

613 account JSON file (`Google Distributed Cloud Hosted`_), then a GDCH 

614 credential will be returned. The project ID returned is the project 

615 specified in the JSON file. 

616 2. If the `Google Cloud SDK`_ is installed and has application default 

617 credentials set they are loaded and returned. 

618 

619 To enable application default credentials with the Cloud SDK run:: 

620 

621 gcloud auth application-default login 

622 

623 If the Cloud SDK has an active project, the project ID is returned. The 

624 active project can be set using:: 

625 

626 gcloud config set project 

627 

628 3. If the application is running in the `App Engine standard environment`_ 

629 (first generation) then the credentials and project ID from the 

630 `App Identity Service`_ are used. 

631 4. If the application is running in `Compute Engine`_ or `Cloud Run`_ or 

632 the `App Engine flexible environment`_ or the `App Engine standard 

633 environment`_ (second generation) then the credentials and project ID 

634 are obtained from the `Metadata Service`_. 

635 5. If no credentials are found, 

636 :class:`~google.auth.exceptions.DefaultCredentialsError` will be raised. 

637 

638 .. _Application Default Credentials: https://developers.google.com\ 

639 /identity/protocols/application-default-credentials 

640 .. _Google Cloud SDK: https://cloud.google.com/sdk 

641 .. _App Engine standard environment: https://cloud.google.com/appengine 

642 .. _App Identity Service: https://cloud.google.com/appengine/docs/python\ 

643 /appidentity/ 

644 .. _Compute Engine: https://cloud.google.com/compute 

645 .. _App Engine flexible environment: https://cloud.google.com\ 

646 /appengine/flexible 

647 .. _Metadata Service: https://cloud.google.com/compute/docs\ 

648 /storing-retrieving-metadata 

649 .. _Cloud Run: https://cloud.google.com/run 

650 .. _Google Distributed Cloud Hosted: https://cloud.google.com/blog/topics\ 

651 /hybrid-cloud/announcing-google-distributed-cloud-edge-and-hosted 

652 

653 Example:: 

654 

655 import google.auth 

656 

657 credentials, project_id = google.auth.default() 

658 

659 Args: 

660 scopes (Sequence[str]): The list of scopes for the credentials. If 

661 specified, the credentials will automatically be scoped if 

662 necessary. 

663 request (Optional[google.auth.transport.Request]): An object used to make 

664 HTTP requests. This is used to either detect whether the application 

665 is running on Compute Engine or to determine the associated project 

666 ID for a workload identity pool resource (external account 

667 credentials). If not specified, then it will either use the standard 

668 library http client to make requests for Compute Engine credentials 

669 or a google.auth.transport.requests.Request client for external 

670 account credentials. 

671 quota_project_id (Optional[str]): The project ID used for 

672 quota and billing. 

673 default_scopes (Optional[Sequence[str]]): Default scopes passed by a 

674 Google client library. Use 'scopes' for user-defined scopes. 

675 Returns: 

676 Tuple[~google.auth.credentials.Credentials, Optional[str]]: 

677 the current environment's credentials and project ID. Project ID 

678 may be None, which indicates that the Project ID could not be 

679 ascertained from the environment. 

680 

681 Raises: 

682 ~google.auth.exceptions.DefaultCredentialsError: 

683 If no credentials were found, or if the credentials found were 

684 invalid. 

685 """ 

686 from google.auth.credentials import with_scopes_if_required 

687 from google.auth.credentials import CredentialsWithQuotaProject 

688 

689 explicit_project_id = os.environ.get( 

690 environment_vars.PROJECT, os.environ.get(environment_vars.LEGACY_PROJECT) 

691 ) 

692 

693 checkers = ( 

694 # Avoid passing scopes here to prevent passing scopes to user credentials. 

695 # with_scopes_if_required() below will ensure scopes/default scopes are 

696 # safely set on the returned credentials since requires_scopes will 

697 # guard against setting scopes on user credentials. 

698 lambda: _get_explicit_environ_credentials(quota_project_id=quota_project_id), 

699 lambda: _get_gcloud_sdk_credentials(quota_project_id=quota_project_id), 

700 _get_gae_credentials, 

701 lambda: _get_gce_credentials(request, quota_project_id=quota_project_id), 

702 ) 

703 

704 for checker in checkers: 

705 credentials, project_id = checker() 

706 if credentials is not None: 

707 credentials = with_scopes_if_required( 

708 credentials, scopes, default_scopes=default_scopes 

709 ) 

710 

711 effective_project_id = explicit_project_id or project_id 

712 

713 # For external account credentials, scopes are required to determine 

714 # the project ID. Try to get the project ID again if not yet 

715 # determined. 

716 if not effective_project_id and callable( 

717 getattr(credentials, "get_project_id", None) 

718 ): 

719 if request is None: 

720 import google.auth.transport.requests 

721 

722 request = google.auth.transport.requests.Request() 

723 effective_project_id = credentials.get_project_id(request=request) 

724 

725 if quota_project_id and isinstance( 

726 credentials, CredentialsWithQuotaProject 

727 ): 

728 credentials = credentials.with_quota_project(quota_project_id) 

729 

730 if not effective_project_id: 

731 _LOGGER.warning( 

732 "No project ID could be determined. Consider running " 

733 "`gcloud config set project` or setting the %s " 

734 "environment variable", 

735 environment_vars.PROJECT, 

736 ) 

737 return credentials, effective_project_id 

738 

739 raise exceptions.DefaultCredentialsError(_CLOUD_SDK_MISSING_CREDENTIALS)