about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/google/auth/_default.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/google/auth/_default.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/google/auth/_default.py')
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/_default.py719
1 files changed, 719 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/google/auth/_default.py b/.venv/lib/python3.12/site-packages/google/auth/_default.py
new file mode 100644
index 00000000..1234fb25
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/_default.py
@@ -0,0 +1,719 @@
+# Copyright 2015 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Application default credentials.
+
+Implements application default credentials and project ID detection.
+"""
+
+import io
+import json
+import logging
+import os
+import warnings
+
+from google.auth import environment_vars
+from google.auth import exceptions
+import google.auth.transport._http_client
+
+_LOGGER = logging.getLogger(__name__)
+
+# Valid types accepted for file-based credentials.
+_AUTHORIZED_USER_TYPE = "authorized_user"
+_SERVICE_ACCOUNT_TYPE = "service_account"
+_EXTERNAL_ACCOUNT_TYPE = "external_account"
+_EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE = "external_account_authorized_user"
+_IMPERSONATED_SERVICE_ACCOUNT_TYPE = "impersonated_service_account"
+_GDCH_SERVICE_ACCOUNT_TYPE = "gdch_service_account"
+_VALID_TYPES = (
+    _AUTHORIZED_USER_TYPE,
+    _SERVICE_ACCOUNT_TYPE,
+    _EXTERNAL_ACCOUNT_TYPE,
+    _EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE,
+    _IMPERSONATED_SERVICE_ACCOUNT_TYPE,
+    _GDCH_SERVICE_ACCOUNT_TYPE,
+)
+
+# Help message when no credentials can be found.
+_CLOUD_SDK_MISSING_CREDENTIALS = """\
+Your default credentials were not found. To set up Application Default Credentials, \
+see https://cloud.google.com/docs/authentication/external/set-up-adc for more information.\
+"""
+
+# Warning when using Cloud SDK user credentials
+_CLOUD_SDK_CREDENTIALS_WARNING = """\
+Your application has authenticated using end user credentials from Google \
+Cloud SDK without a quota project. You might receive a "quota exceeded" \
+or "API not enabled" error. See the following page for troubleshooting: \
+https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds. \
+"""
+
+# The subject token type used for AWS external_account credentials.
+_AWS_SUBJECT_TOKEN_TYPE = "urn:ietf:params:aws:token-type:aws4_request"
+
+
+def _warn_about_problematic_credentials(credentials):
+    """Determines if the credentials are problematic.
+
+    Credentials from the Cloud SDK that are associated with Cloud SDK's project
+    are problematic because they may not have APIs enabled and have limited
+    quota. If this is the case, warn about it.
+    """
+    from google.auth import _cloud_sdk
+
+    if credentials.client_id == _cloud_sdk.CLOUD_SDK_CLIENT_ID:
+        warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING)
+
+
+def load_credentials_from_file(
+    filename, scopes=None, default_scopes=None, quota_project_id=None, request=None
+):
+    """Loads Google credentials from a file.
+
+    The credentials file must be a service account key, stored authorized
+    user credentials, external account credentials, or impersonated service
+    account credentials.
+
+    .. warning::
+        Important: If you accept a credential configuration (credential JSON/File/Stream)
+        from an external source for authentication to Google Cloud Platform, you must
+        validate it before providing it to any Google API or client library. Providing an
+        unvalidated credential configuration to Google APIs or libraries can compromise
+        the security of your systems and data. For more information, refer to
+        `Validate credential configurations from external sources`_.
+
+        .. _Validate credential configurations from external sources:
+            https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
+
+    Args:
+        filename (str): The full path to the credentials file.
+        scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If
+            specified, the credentials will automatically be scoped if
+            necessary
+        default_scopes (Optional[Sequence[str]]): Default scopes passed by a
+            Google client library. Use 'scopes' for user-defined scopes.
+        quota_project_id (Optional[str]):  The project ID used for
+            quota and billing.
+        request (Optional[google.auth.transport.Request]): An object used to make
+            HTTP requests. This is used to determine the associated project ID
+            for a workload identity pool resource (external account credentials).
+            If not specified, then it will use a
+            google.auth.transport.requests.Request client to make requests.
+
+    Returns:
+        Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded
+            credentials and the project ID. Authorized user credentials do not
+            have the project ID information. External account credentials project
+            IDs may not always be determined.
+
+    Raises:
+        google.auth.exceptions.DefaultCredentialsError: if the file is in the
+            wrong format or is missing.
+    """
+    if not os.path.exists(filename):
+        raise exceptions.DefaultCredentialsError(
+            "File {} was not found.".format(filename)
+        )
+
+    with io.open(filename, "r") as file_obj:
+        try:
+            info = json.load(file_obj)
+        except ValueError as caught_exc:
+            new_exc = exceptions.DefaultCredentialsError(
+                "File {} is not a valid json file.".format(filename), caught_exc
+            )
+            raise new_exc from caught_exc
+    return _load_credentials_from_info(
+        filename, info, scopes, default_scopes, quota_project_id, request
+    )
+
+
+def load_credentials_from_dict(
+    info, scopes=None, default_scopes=None, quota_project_id=None, request=None
+):
+    """Loads Google credentials from a dict.
+
+    The credentials file must be a service account key, stored authorized
+    user credentials, external account credentials, or impersonated service
+    account credentials.
+
+    .. warning::
+        Important: If you accept a credential configuration (credential JSON/File/Stream)
+        from an external source for authentication to Google Cloud Platform, you must
+        validate it before providing it to any Google API or client library. Providing an
+        unvalidated credential configuration to Google APIs or libraries can compromise
+        the security of your systems and data. For more information, refer to
+        `Validate credential configurations from external sources`_.
+
+    .. _Validate credential configurations from external sources:
+        https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
+
+    Args:
+        info (Dict[str, Any]): A dict object containing the credentials
+        scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If
+            specified, the credentials will automatically be scoped if
+            necessary
+        default_scopes (Optional[Sequence[str]]): Default scopes passed by a
+            Google client library. Use 'scopes' for user-defined scopes.
+        quota_project_id (Optional[str]):  The project ID used for
+            quota and billing.
+        request (Optional[google.auth.transport.Request]): An object used to make
+            HTTP requests. This is used to determine the associated project ID
+            for a workload identity pool resource (external account credentials).
+            If not specified, then it will use a
+            google.auth.transport.requests.Request client to make requests.
+
+    Returns:
+        Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded
+            credentials and the project ID. Authorized user credentials do not
+            have the project ID information. External account credentials project
+            IDs may not always be determined.
+
+    Raises:
+        google.auth.exceptions.DefaultCredentialsError: if the file is in the
+            wrong format or is missing.
+    """
+    if not isinstance(info, dict):
+        raise exceptions.DefaultCredentialsError(
+            "info object was of type {} but dict type was expected.".format(type(info))
+        )
+
+    return _load_credentials_from_info(
+        "dict object", info, scopes, default_scopes, quota_project_id, request
+    )
+
+
+def _load_credentials_from_info(
+    filename, info, scopes, default_scopes, quota_project_id, request
+):
+    from google.auth.credentials import CredentialsWithQuotaProject
+
+    credential_type = info.get("type")
+
+    if credential_type == _AUTHORIZED_USER_TYPE:
+        credentials, project_id = _get_authorized_user_credentials(
+            filename, info, scopes
+        )
+
+    elif credential_type == _SERVICE_ACCOUNT_TYPE:
+        credentials, project_id = _get_service_account_credentials(
+            filename, info, scopes, default_scopes
+        )
+
+    elif credential_type == _EXTERNAL_ACCOUNT_TYPE:
+        credentials, project_id = _get_external_account_credentials(
+            info,
+            filename,
+            scopes=scopes,
+            default_scopes=default_scopes,
+            request=request,
+        )
+
+    elif credential_type == _EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE:
+        credentials, project_id = _get_external_account_authorized_user_credentials(
+            filename, info, request
+        )
+
+    elif credential_type == _IMPERSONATED_SERVICE_ACCOUNT_TYPE:
+        credentials, project_id = _get_impersonated_service_account_credentials(
+            filename, info, scopes
+        )
+    elif credential_type == _GDCH_SERVICE_ACCOUNT_TYPE:
+        credentials, project_id = _get_gdch_service_account_credentials(filename, info)
+    else:
+        raise exceptions.DefaultCredentialsError(
+            "The file {file} does not have a valid type. "
+            "Type is {type}, expected one of {valid_types}.".format(
+                file=filename, type=credential_type, valid_types=_VALID_TYPES
+            )
+        )
+    if isinstance(credentials, CredentialsWithQuotaProject):
+        credentials = _apply_quota_project_id(credentials, quota_project_id)
+    return credentials, project_id
+
+
+def _get_gcloud_sdk_credentials(quota_project_id=None):
+    """Gets the credentials and project ID from the Cloud SDK."""
+    from google.auth import _cloud_sdk
+
+    _LOGGER.debug("Checking Cloud SDK credentials as part of auth process...")
+
+    # Check if application default credentials exist.
+    credentials_filename = _cloud_sdk.get_application_default_credentials_path()
+
+    if not os.path.isfile(credentials_filename):
+        _LOGGER.debug("Cloud SDK credentials not found on disk; not using them")
+        return None, None
+
+    credentials, project_id = load_credentials_from_file(
+        credentials_filename, quota_project_id=quota_project_id
+    )
+    credentials._cred_file_path = credentials_filename
+
+    if not project_id:
+        project_id = _cloud_sdk.get_project_id()
+
+    return credentials, project_id
+
+
+def _get_explicit_environ_credentials(quota_project_id=None):
+    """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(quota_project_id=quota_project_id)
+
+    if explicit_file is not None:
+        credentials, project_id = load_credentials_from_file(
+            os.environ[environment_vars.CREDENTIALS], quota_project_id=quota_project_id
+        )
+        credentials._cred_file_path = f"{explicit_file} file via the GOOGLE_APPLICATION_CREDENTIALS environment variable"
+
+        return credentials, project_id
+
+    else:
+        return None, None
+
+
+def _get_gae_credentials():
+    """Gets Google App Engine App Identity credentials and project ID."""
+    # If not GAE gen1, prefer the metadata service even if the GAE APIs are
+    # available as per https://google.aip.dev/auth/4115.
+    if os.environ.get(environment_vars.LEGACY_APPENGINE_RUNTIME) != "python27":
+        return None, None
+
+    # While this library is normally bundled with app_engine, there are
+    # some cases where it's not available, so we tolerate ImportError.
+    try:
+        _LOGGER.debug("Checking for App Engine runtime as part of auth process...")
+        import google.auth.app_engine as app_engine
+    except ImportError:
+        _LOGGER.warning("Import of App Engine auth library failed.")
+        return None, None
+
+    try:
+        credentials = app_engine.Credentials()
+        project_id = app_engine.get_project_id()
+        return credentials, project_id
+    except EnvironmentError:
+        _LOGGER.debug(
+            "No App Engine library was found so cannot authentication via App Engine Identity Credentials."
+        )
+        return None, None
+
+
+def _get_gce_credentials(request=None, quota_project_id=None):
+    """Gets credentials and project ID from the GCE Metadata Service."""
+    # Ping requires a transport, but we want application default credentials
+    # to require no arguments. So, we'll use the _http_client transport which
+    # uses http.client. This is only acceptable because the metadata server
+    # doesn't do SSL and never requires proxies.
+
+    # While this library is normally bundled with compute_engine, there are
+    # some cases where it's not available, so we tolerate ImportError.
+    try:
+        from google.auth import compute_engine
+        from google.auth.compute_engine import _metadata
+    except ImportError:
+        _LOGGER.warning("Import of Compute Engine auth library failed.")
+        return None, None
+
+    if request is None:
+        request = google.auth.transport._http_client.Request()
+
+    if _metadata.is_on_gce(request=request):
+        # Get the project ID.
+        try:
+            project_id = _metadata.get_project_id(request=request)
+        except exceptions.TransportError:
+            project_id = None
+
+        cred = compute_engine.Credentials()
+        cred = _apply_quota_project_id(cred, quota_project_id)
+
+        return cred, project_id
+    else:
+        _LOGGER.warning(
+            "Authentication failed using Compute Engine authentication due to unavailable metadata server."
+        )
+        return None, None
+
+
+def _get_external_account_credentials(
+    info, filename, scopes=None, default_scopes=None, request=None
+):
+    """Loads external account Credentials from the parsed external account info.
+
+    The credentials information must correspond to a supported external account
+    credentials.
+
+    Args:
+        info (Mapping[str, str]): The external account info in Google format.
+        filename (str): The full path to the credentials file.
+        scopes (Optional[Sequence[str]]): The list of scopes for the credentials. If
+            specified, the credentials will automatically be scoped if
+            necessary.
+        default_scopes (Optional[Sequence[str]]): Default scopes passed by a
+            Google client library. Use 'scopes' for user-defined scopes.
+        request (Optional[google.auth.transport.Request]): An object used to make
+            HTTP requests. This is used to determine the associated project ID
+            for a workload identity pool resource (external account credentials).
+            If not specified, then it will use a
+            google.auth.transport.requests.Request client to make requests.
+
+    Returns:
+        Tuple[google.auth.credentials.Credentials, Optional[str]]: Loaded
+            credentials and the project ID. External account credentials project
+            IDs may not always be determined.
+
+    Raises:
+        google.auth.exceptions.DefaultCredentialsError: if the info dictionary
+            is in the wrong format or is missing required information.
+    """
+    # There are currently 3 types of external_account credentials.
+    if info.get("subject_token_type") == _AWS_SUBJECT_TOKEN_TYPE:
+        # Check if configuration corresponds to an AWS credentials.
+        from google.auth import aws
+
+        credentials = aws.Credentials.from_info(
+            info, scopes=scopes, default_scopes=default_scopes
+        )
+    elif (
+        info.get("credential_source") is not None
+        and info.get("credential_source").get("executable") is not None
+    ):
+        from google.auth import pluggable
+
+        credentials = pluggable.Credentials.from_info(
+            info, scopes=scopes, default_scopes=default_scopes
+        )
+    else:
+        try:
+            # Check if configuration corresponds to an Identity Pool credentials.
+            from google.auth import identity_pool
+
+            credentials = identity_pool.Credentials.from_info(
+                info, scopes=scopes, default_scopes=default_scopes
+            )
+        except ValueError:
+            # If the configuration is invalid or does not correspond to any
+            # supported external_account credentials, raise an error.
+            raise exceptions.DefaultCredentialsError(
+                "Failed to load external account credentials from {}".format(filename)
+            )
+    if request is None:
+        import google.auth.transport.requests
+
+        request = google.auth.transport.requests.Request()
+
+    return credentials, credentials.get_project_id(request=request)
+
+
+def _get_external_account_authorized_user_credentials(
+    filename, info, scopes=None, default_scopes=None, request=None
+):
+    try:
+        from google.auth import external_account_authorized_user
+
+        credentials = external_account_authorized_user.Credentials.from_info(info)
+    except ValueError:
+        raise exceptions.DefaultCredentialsError(
+            "Failed to load external account authorized user credentials from {}".format(
+                filename
+            )
+        )
+
+    return credentials, None
+
+
+def _get_authorized_user_credentials(filename, info, scopes=None):
+    from google.oauth2 import credentials
+
+    try:
+        credentials = credentials.Credentials.from_authorized_user_info(
+            info, scopes=scopes
+        )
+    except ValueError as caught_exc:
+        msg = "Failed to load authorized user credentials from {}".format(filename)
+        new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
+        raise new_exc from caught_exc
+    return credentials, None
+
+
+def _get_service_account_credentials(filename, info, scopes=None, default_scopes=None):
+    from google.oauth2 import service_account
+
+    try:
+        credentials = service_account.Credentials.from_service_account_info(
+            info, scopes=scopes, default_scopes=default_scopes
+        )
+    except ValueError as caught_exc:
+        msg = "Failed to load service account credentials from {}".format(filename)
+        new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
+        raise new_exc from caught_exc
+    return credentials, info.get("project_id")
+
+
+def _get_impersonated_service_account_credentials(filename, info, scopes):
+    from google.auth import impersonated_credentials
+
+    try:
+        source_credentials_info = info.get("source_credentials")
+        source_credentials_type = source_credentials_info.get("type")
+        if source_credentials_type == _AUTHORIZED_USER_TYPE:
+            source_credentials, _ = _get_authorized_user_credentials(
+                filename, source_credentials_info
+            )
+        elif source_credentials_type == _SERVICE_ACCOUNT_TYPE:
+            source_credentials, _ = _get_service_account_credentials(
+                filename, source_credentials_info
+            )
+        elif source_credentials_type == _EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE:
+            source_credentials, _ = _get_external_account_authorized_user_credentials(
+                filename, source_credentials_info
+            )
+        else:
+            raise exceptions.InvalidType(
+                "source credential of type {} is not supported.".format(
+                    source_credentials_type
+                )
+            )
+        impersonation_url = info.get("service_account_impersonation_url")
+        start_index = impersonation_url.rfind("/")
+        end_index = impersonation_url.find(":generateAccessToken")
+        if start_index == -1 or end_index == -1 or start_index > end_index:
+            raise exceptions.InvalidValue(
+                "Cannot extract target principal from {}".format(impersonation_url)
+            )
+        target_principal = impersonation_url[start_index + 1 : end_index]
+        delegates = info.get("delegates")
+        quota_project_id = info.get("quota_project_id")
+        credentials = impersonated_credentials.Credentials(
+            source_credentials,
+            target_principal,
+            scopes,
+            delegates,
+            quota_project_id=quota_project_id,
+        )
+    except ValueError as caught_exc:
+        msg = "Failed to load impersonated service account credentials from {}".format(
+            filename
+        )
+        new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
+        raise new_exc from caught_exc
+    return credentials, None
+
+
+def _get_gdch_service_account_credentials(filename, info):
+    from google.oauth2 import gdch_credentials
+
+    try:
+        credentials = gdch_credentials.ServiceAccountCredentials.from_service_account_info(
+            info
+        )
+    except ValueError as caught_exc:
+        msg = "Failed to load GDCH service account credentials from {}".format(filename)
+        new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
+        raise new_exc from caught_exc
+    return credentials, info.get("project")
+
+
+def get_api_key_credentials(key):
+    """Return credentials with the given API key."""
+    from google.auth import api_key
+
+    return api_key.Credentials(key)
+
+
+def _apply_quota_project_id(credentials, quota_project_id):
+    if quota_project_id:
+        credentials = credentials.with_quota_project(quota_project_id)
+    else:
+        credentials = credentials.with_quota_project_from_environment()
+
+    from google.oauth2 import credentials as authorized_user_credentials
+
+    if isinstance(credentials, authorized_user_credentials.Credentials) and (
+        not credentials.quota_project_id
+    ):
+        _warn_about_problematic_credentials(credentials)
+    return credentials
+
+
+def default(scopes=None, request=None, quota_project_id=None, default_scopes=None):
+    """Gets the default credentials for the current environment.
+
+    `Application Default Credentials`_ provides an easy way to obtain
+    credentials to call Google APIs for server-to-server or local applications.
+    This function acquires credentials from the environment in the following
+    order:
+
+    1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
+       to the path of a valid service account JSON private key file, then it is
+       loaded and returned. The project ID returned is the project ID defined
+       in the service account file if available (some older files do not
+       contain project ID information).
+
+       If the environment variable is set to the path of a valid external
+       account JSON configuration file (workload identity federation), then the
+       configuration file is used to determine and retrieve the external
+       credentials from the current environment (AWS, Azure, etc).
+       These will then be exchanged for Google access tokens via the Google STS
+       endpoint.
+       The project ID returned in this case is the one corresponding to the
+       underlying workload identity pool resource if determinable.
+
+       If the environment variable is set to the path of a valid GDCH service
+       account JSON file (`Google Distributed Cloud Hosted`_), then a GDCH
+       credential will be returned. The project ID returned is the project
+       specified in the JSON file.
+    2. If the `Google Cloud SDK`_ is installed and has application default
+       credentials set they are loaded and returned.
+
+       To enable application default credentials with the Cloud SDK run::
+
+            gcloud auth application-default login
+
+       If the Cloud SDK has an active project, the project ID is returned. The
+       active project can be set using::
+
+            gcloud config set project
+
+    3. If the application is running in the `App Engine standard environment`_
+       (first generation) then the credentials and project ID from the
+       `App Identity Service`_ are used.
+    4. If the application is running in `Compute Engine`_ or `Cloud Run`_ or
+       the `App Engine flexible environment`_ or the `App Engine standard
+       environment`_ (second generation) then the credentials and project ID
+       are obtained from the `Metadata Service`_.
+    5. If no credentials are found,
+       :class:`~google.auth.exceptions.DefaultCredentialsError` will be raised.
+
+    .. _Application Default Credentials: https://developers.google.com\
+            /identity/protocols/application-default-credentials
+    .. _Google Cloud SDK: https://cloud.google.com/sdk
+    .. _App Engine standard environment: https://cloud.google.com/appengine
+    .. _App Identity Service: https://cloud.google.com/appengine/docs/python\
+            /appidentity/
+    .. _Compute Engine: https://cloud.google.com/compute
+    .. _App Engine flexible environment: https://cloud.google.com\
+            /appengine/flexible
+    .. _Metadata Service: https://cloud.google.com/compute/docs\
+            /storing-retrieving-metadata
+    .. _Cloud Run: https://cloud.google.com/run
+    .. _Google Distributed Cloud Hosted: https://cloud.google.com/blog/topics\
+            /hybrid-cloud/announcing-google-distributed-cloud-edge-and-hosted
+
+    Example::
+
+        import google.auth
+
+        credentials, project_id = google.auth.default()
+
+    Args:
+        scopes (Sequence[str]): The list of scopes for the credentials. If
+            specified, the credentials will automatically be scoped if
+            necessary.
+        request (Optional[google.auth.transport.Request]): An object used to make
+            HTTP requests. This is used to either detect whether the application
+            is running on Compute Engine or to determine the associated project
+            ID for a workload identity pool resource (external account
+            credentials). If not specified, then it will either use the standard
+            library http client to make requests for Compute Engine credentials
+            or a google.auth.transport.requests.Request client for external
+            account credentials.
+        quota_project_id (Optional[str]): The project ID used for
+            quota and billing.
+        default_scopes (Optional[Sequence[str]]): Default scopes passed by a
+            Google client library. Use 'scopes' for user-defined scopes.
+    Returns:
+        Tuple[~google.auth.credentials.Credentials, Optional[str]]:
+            the current environment's credentials and project ID. Project ID
+            may be None, which indicates that the Project ID could not be
+            ascertained from the environment.
+
+    Raises:
+        ~google.auth.exceptions.DefaultCredentialsError:
+            If no credentials were found, or if the credentials found were
+            invalid.
+    """
+    from google.auth.credentials import with_scopes_if_required
+    from google.auth.credentials import CredentialsWithQuotaProject
+
+    explicit_project_id = os.environ.get(
+        environment_vars.PROJECT, os.environ.get(environment_vars.LEGACY_PROJECT)
+    )
+
+    checkers = (
+        # Avoid passing scopes here to prevent passing scopes to user credentials.
+        # with_scopes_if_required() below will ensure scopes/default scopes are
+        # safely set on the returned credentials since requires_scopes will
+        # guard against setting scopes on user credentials.
+        lambda: _get_explicit_environ_credentials(quota_project_id=quota_project_id),
+        lambda: _get_gcloud_sdk_credentials(quota_project_id=quota_project_id),
+        _get_gae_credentials,
+        lambda: _get_gce_credentials(request, quota_project_id=quota_project_id),
+    )
+
+    for checker in checkers:
+        credentials, project_id = checker()
+        if credentials is not None:
+            credentials = with_scopes_if_required(
+                credentials, scopes, default_scopes=default_scopes
+            )
+
+            effective_project_id = explicit_project_id or project_id
+
+            # For external account credentials, scopes are required to determine
+            # the project ID. Try to get the project ID again if not yet
+            # determined.
+            if not effective_project_id and callable(
+                getattr(credentials, "get_project_id", None)
+            ):
+                if request is None:
+                    import google.auth.transport.requests
+
+                    request = google.auth.transport.requests.Request()
+                effective_project_id = credentials.get_project_id(request=request)
+
+            if quota_project_id and isinstance(
+                credentials, CredentialsWithQuotaProject
+            ):
+                credentials = credentials.with_quota_project(quota_project_id)
+
+            if not effective_project_id:
+                _LOGGER.warning(
+                    "No project ID could be determined. Consider running "
+                    "`gcloud config set project` or setting the %s "
+                    "environment variable",
+                    environment_vars.PROJECT,
+                )
+            return credentials, effective_project_id
+
+    raise exceptions.DefaultCredentialsError(_CLOUD_SDK_MISSING_CREDENTIALS)