Skip to content

Commit 4dd29b9

Browse files
committed
fix: deprecate credentials_file argument
1 parent 14a5978 commit 4dd29b9

File tree

7 files changed

+111
-29
lines changed

7 files changed

+111
-29
lines changed

google/api_core/client_options.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ def get_client_cert():
4949
"""
5050

5151
from typing import Callable, Mapping, Optional, Sequence, Tuple
52+
import warnings
53+
54+
from google.api_core import general_helpers
5255

5356

5457
class ClientOptions(object):
@@ -67,8 +70,9 @@ class ClientOptions(object):
6770
and ``client_encrypted_cert_source`` are mutually exclusive.
6871
quota_project_id (Optional[str]): A project name that a client's
6972
quota belongs to.
70-
credentials_file (Optional[str]): A path to a file storing credentials.
71-
``credentials_file` and ``api_key`` are mutually exclusive.
73+
credentials_file (Optional[str]): Deprecated. A path to a file storing credentials.
74+
``credentials_file` and ``api_key`` are mutually exclusive. This argument will be
75+
removed in the next major version of `google-api-core`.
7276
7377
.. warning::
7478
Important: If you accept a credential configuration (credential JSON/File/Stream)
@@ -114,6 +118,9 @@ def __init__(
114118
api_audience: Optional[str] = None,
115119
universe_domain: Optional[str] = None,
116120
):
121+
if credentials_file is not None:
122+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
123+
117124
if client_cert_source and client_encrypted_cert_source:
118125
raise ValueError(
119126
"client_cert_source and client_encrypted_cert_source are mutually exclusive"

google/api_core/general_helpers.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,36 @@
1414

1515
# This import for backward compatibility only.
1616
from functools import wraps # noqa: F401 pragma: NO COVER
17+
18+
_CREDENTIALS_FILE_WARNING = """\
19+
The `credentials_file` argument is deprecated because of a potential security risk.
20+
21+
The `google.auth.load_credentials_from_file` method does not validate the credential
22+
configuration. The security risk occurs when a credential configuration is accepted
23+
from a source that is not under your control and used without validation on your side.
24+
25+
If you know that you will be loading credential configurations of a
26+
specific type, it is recommended to use a credential-type-specific
27+
load method.
28+
29+
This will ensure that an unexpected credential type with potential for
30+
malicious intent is not loaded unintentionally. You might still have to do
31+
validation for certain credential types. Please follow the recommendations
32+
for that method. For example, if you want to load only service accounts,
33+
you can create the service account credentials explicitly:
34+
35+
```
36+
from google.oauth2 import service_account
37+
creds = service_account.Credentials.from_service_account_file(filename)
38+
```
39+
40+
If you are loading your credential configuration from an untrusted source and have
41+
not mitigated the risks (e.g. by validating the configuration yourself), make
42+
these changes as soon as possible to prevent security risks to your environment.
43+
44+
Regardless of the method used, it is always your responsibility to validate
45+
configurations received from external sources.
46+
47+
Refer to https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
48+
for more details.
49+
"""

google/api_core/grpc_helpers.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,19 @@
1313
# limitations under the License.
1414

1515
"""Helpers for :mod:`grpc`."""
16-
from typing import Generic, Iterator, Optional, TypeVar
17-
1816
import collections
1917
import functools
18+
from typing import Generic, Iterator, Optional, TypeVar
2019
import warnings
2120

22-
import grpc
23-
24-
from google.api_core import exceptions
2521
import google.auth
2622
import google.auth.credentials
2723
import google.auth.transport.grpc
2824
import google.auth.transport.requests
2925
import google.protobuf
26+
import grpc
27+
28+
from google.api_core import exceptions, general_helpers
3029

3130
PROTOBUF_VERSION = google.protobuf.__version__
3231

@@ -213,9 +212,10 @@ def _create_composite_credentials(
213212
credentials (google.auth.credentials.Credentials): The credentials. If
214213
not specified, then this function will attempt to ascertain the
215214
credentials from the environment using :func:`google.auth.default`.
216-
credentials_file (str): A file with credentials that can be loaded with
215+
credentials_file (str): Deprecated. A file with credentials that can be loaded with
217216
:func:`google.auth.load_credentials_from_file`. This argument is
218-
mutually exclusive with credentials.
217+
mutually exclusive with credentials. This argument will be
218+
removed in the next major version of `google-api-core`.
219219
220220
.. warning::
221221
Important: If you accept a credential configuration (credential JSON/File/Stream)
@@ -245,6 +245,9 @@ def _create_composite_credentials(
245245
Raises:
246246
google.api_core.DuplicateCredentialArgs: If both a credentials object and credentials_file are passed.
247247
"""
248+
if credentials_file is not None:
249+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
250+
248251
if credentials and credentials_file:
249252
raise exceptions.DuplicateCredentialArgs(
250253
"'credentials' and 'credentials_file' are mutually exclusive."

google/api_core/grpc_helpers_async.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020

2121
import asyncio
2222
import functools
23+
import warnings
2324

2425
from typing import AsyncGenerator, Generic, Iterator, Optional, TypeVar
2526

2627
import grpc
2728
from grpc import aio
2829

29-
from google.api_core import exceptions, grpc_helpers
30+
from google.api_core import exceptions, general_helpers, grpc_helpers
3031

3132
# denotes the proto response type for grpc calls
3233
P = TypeVar("P")
@@ -233,9 +234,10 @@ def create_channel(
233234
are passed to :func:`google.auth.default`.
234235
ssl_credentials (grpc.ChannelCredentials): Optional SSL channel
235236
credentials. This can be used to specify different certificates.
236-
credentials_file (str): A file with credentials that can be loaded with
237+
credentials_file (str): Deprecated. A file with credentials that can be loaded with
237238
:func:`google.auth.load_credentials_from_file`. This argument is
238-
mutually exclusive with credentials.
239+
mutually exclusive with credentials. This argument will be
240+
removed in the next major version of `google-api-core`.
239241
240242
.. warning::
241243
Important: If you accept a credential configuration (credential JSON/File/Stream)
@@ -280,6 +282,9 @@ def create_channel(
280282
ValueError: If `ssl_credentials` is set and `attempt_direct_path` is set to `True`.
281283
"""
282284

285+
if credentials_file is not None:
286+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
287+
283288
# If `ssl_credentials` is set and `attempt_direct_path` is set to `True`,
284289
# raise ValueError as this is not yet supported.
285290
# See https://github.com/googleapis/python-api-core/issues/590

google/api_core/operations_v1/transports/base.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@
1616
import abc
1717
import re
1818
from typing import Awaitable, Callable, Optional, Sequence, Union
19+
import warnings
1920

20-
import google.api_core # type: ignore
21-
from google.api_core import exceptions as core_exceptions # type: ignore
22-
from google.api_core import gapic_v1 # type: ignore
23-
from google.api_core import retry as retries # type: ignore
24-
from google.api_core import version
2521
import google.auth # type: ignore
2622
from google.auth import credentials as ga_credentials # type: ignore
2723
from google.longrunning import operations_pb2
@@ -30,6 +26,12 @@
3026
from google.protobuf import empty_pb2, json_format # type: ignore
3127
from grpc import Compression
3228

29+
import google.api_core # type: ignore
30+
from google.api_core import exceptions as core_exceptions # type: ignore
31+
from google.api_core import gapic_v1 # type: ignore
32+
from google.api_core import general_helpers
33+
from google.api_core import retry as retries # type: ignore
34+
from google.api_core import version
3335

3436
PROTOBUF_VERSION = google.protobuf.__version__
3537

@@ -69,9 +71,10 @@ def __init__(
6971
credentials identify the application to the service; if none
7072
are specified, the client will attempt to ascertain the
7173
credentials from the environment.
72-
credentials_file (Optional[str]): A file with credentials that can
74+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
7375
be loaded with :func:`google.auth.load_credentials_from_file`.
74-
This argument is mutually exclusive with credentials.
76+
This argument is mutually exclusive with credentials. This argument will be
77+
removed in the next major version of `google-api-core`.
7578
7679
.. warning::
7780
Important: If you accept a credential configuration (credential JSON/File/Stream)
@@ -98,6 +101,9 @@ def __init__(
98101
"https", but for testing or local servers,
99102
"http" can be specified.
100103
"""
104+
if credentials_file is not None:
105+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
106+
101107
maybe_url_match = re.match("^(?P<scheme>http(?:s)?://)?(?P<host>.*)$", host)
102108
if maybe_url_match is None:
103109
raise ValueError(

google/api_core/operations_v1/transports/rest.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,26 @@
1515
#
1616

1717
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
18+
import warnings
1819

20+
from google.auth import credentials as ga_credentials # type: ignore
21+
from google.auth.transport.requests import AuthorizedSession # type: ignore
22+
from google.longrunning import operations_pb2 # type: ignore
23+
import google.protobuf
24+
from google.protobuf import empty_pb2 # type: ignore
25+
from google.protobuf import json_format # type: ignore
26+
import grpc
1927
from requests import __version__ as requests_version
2028

2129
from google.api_core import exceptions as core_exceptions # type: ignore
2230
from google.api_core import gapic_v1 # type: ignore
31+
from google.api_core import general_helpers
2332
from google.api_core import path_template # type: ignore
2433
from google.api_core import rest_helpers # type: ignore
2534
from google.api_core import retry as retries # type: ignore
26-
from google.auth import credentials as ga_credentials # type: ignore
27-
from google.auth.transport.requests import AuthorizedSession # type: ignore
28-
from google.longrunning import operations_pb2 # type: ignore
29-
from google.protobuf import empty_pb2 # type: ignore
30-
from google.protobuf import json_format # type: ignore
31-
import google.protobuf
3235

33-
import grpc
34-
from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO, OperationsTransport
36+
from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
37+
from .base import OperationsTransport
3538

3639
PROTOBUF_VERSION = google.protobuf.__version__
3740

@@ -91,9 +94,10 @@ def __init__(
9194
are specified, the client will attempt to ascertain the
9295
credentials from the environment.
9396
94-
credentials_file (Optional[str]): A file with credentials that can
97+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
9598
be loaded with :func:`google.auth.load_credentials_from_file`.
96-
This argument is ignored if ``channel`` is provided.
99+
This argument is ignored if ``channel`` is provided. This argument will be
100+
removed in the next major version of `google-api-core`.
97101
98102
.. warning::
99103
Important: If you accept a credential configuration (credential JSON/File/Stream)
@@ -130,6 +134,9 @@ def __init__(
130134
"v1" by default.
131135
132136
"""
137+
if credentials_file is not None:
138+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
139+
133140
# Run the base constructor
134141
# TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
135142
# TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the

google/api_core/operations_v1/transports/rest_asyncio.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import json
1818
from typing import Any, Callable, Coroutine, Dict, Optional, Sequence, Tuple
19+
import warnings
1920

2021
from google.auth import __version__ as auth_version
2122

@@ -29,6 +30,7 @@
2930

3031
from google.api_core import exceptions as core_exceptions # type: ignore
3132
from google.api_core import gapic_v1 # type: ignore
33+
from google.api_core import general_helpers
3234
from google.api_core import path_template # type: ignore
3335
from google.api_core import rest_helpers # type: ignore
3436
from google.api_core import retry_async as retries_async # type: ignore
@@ -96,6 +98,22 @@ def __init__(
9698
credentials identify the application to the service; if none
9799
are specified, the client will attempt to ascertain the
98100
credentials from the environment.
101+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
102+
be loaded with :func:`google.auth.load_credentials_from_file`.
103+
This argument is ignored if ``channel`` is provided. This argument will be
104+
removed in the next major version of `google-api-core`.
105+
106+
.. warning::
107+
Important: If you accept a credential configuration (credential JSON/File/Stream)
108+
from an external source for authentication to Google Cloud Platform, you must
109+
validate it before providing it to any Google API or client library. Providing an
110+
unvalidated credential configuration to Google APIs or libraries can compromise
111+
the security of your systems and data. For more information, refer to
112+
`Validate credential configurations from external sources`_.
113+
114+
.. _Validate credential configurations from external sources:
115+
116+
https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
99117
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
100118
The client info used to send a user-agent string along with
101119
API requests. If ``None``, then default info will be used.
@@ -113,6 +131,9 @@ def __init__(
113131
"v1" by default.
114132
115133
"""
134+
if credentials_file is not None:
135+
warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
136+
116137
unsupported_params = {
117138
# TODO(https://github.com/googleapis/python-api-core/issues/715): Add support for `credentials_file` to async REST transport.
118139
"google.api_core.client_options.ClientOptions.credentials_file": credentials_file,

0 commit comments

Comments
 (0)