17
17
from __future__ import absolute_import
18
18
19
19
import logging
20
+ import os
20
21
21
22
import six
22
23
24
+ from google .auth import environment_vars
23
25
from google .auth import exceptions
24
26
from google .auth .transport import _mtls_helper
25
27
@@ -96,6 +98,9 @@ def secure_authorized_channel(
96
98
97
99
This creates a channel with SSL and :class:`AuthMetadataPlugin`. This
98
100
channel can be used to create a stub that can make authorized requests.
101
+ Users can configure client certificate or rely on device certificates to
102
+ establish a mutual TLS channel, if the `GOOGLE_API_USE_CLIENT_CERTIFICATE`
103
+ variable is explicitly set to `true`.
99
104
100
105
Example::
101
106
@@ -138,7 +143,9 @@ def secure_authorized_channel(
138
143
ssl_credentials=regular_ssl_credentials)
139
144
140
145
Option 2: create a mutual TLS channel by calling a callback which returns
141
- the client side certificate and the key::
146
+ the client side certificate and the key (Note that
147
+ `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable must be explicitly
148
+ set to `true`)::
142
149
143
150
def my_client_cert_callback():
144
151
code_to_load_client_cert_and_key()
@@ -155,7 +162,9 @@ def my_client_cert_callback():
155
162
156
163
Option 3: use application default SSL credentials. It searches and uses
157
164
the command in a context aware metadata file, which is available on devices
158
- with endpoint verification support.
165
+ with endpoint verification support (Note that
166
+ `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable must be explicitly
167
+ set to `true`).
159
168
See https://cloud.google.com/endpoint-verification/docs/overview::
160
169
161
170
try:
@@ -174,7 +183,8 @@ def my_client_cert_callback():
174
183
ssl_credentials=default_ssl_credentials)
175
184
176
185
Option 4: not setting ssl_credentials and client_cert_callback. For devices
177
- without endpoint verification support, a regular TLS channel is created;
186
+ without endpoint verification support or `GOOGLE_API_USE_CLIENT_CERTIFICATE`
187
+ environment variable is not `true`, a regular TLS channel is created;
178
188
otherwise, a mutual TLS channel is created, however, the call should be
179
189
wrapped in a try/except block in case of malformed context aware metadata.
180
190
@@ -205,13 +215,15 @@ def my_client_cert_callback():
205
215
This argument is mutually exclusive with client_cert_callback;
206
216
providing both will raise an exception.
207
217
If ssl_credentials and client_cert_callback are None, application
208
- default SSL credentials will be used.
218
+ default SSL credentials are used if `GOOGLE_API_USE_CLIENT_CERTIFICATE`
219
+ environment variable is explicitly set to `true`, otherwise one way TLS
220
+ SSL credentials are used.
209
221
client_cert_callback (Callable[[], (bytes, bytes)]): Optional
210
222
callback function to obtain client certicate and key for mutual TLS
211
223
connection. This argument is mutually exclusive with
212
224
ssl_credentials; providing both will raise an exception.
213
- If ssl_credentials and client_cert_callback are None, application
214
- default SSL credentials will be used .
225
+ This argument does nothing unless `GOOGLE_API_USE_CLIENT_CERTIFICATE`
226
+ environment variable is explicitly set to `true` .
215
227
kwargs: Additional arguments to pass to :func:`grpc.secure_channel`.
216
228
217
229
Returns:
@@ -235,16 +247,21 @@ def my_client_cert_callback():
235
247
236
248
# If SSL credentials are not explicitly set, try client_cert_callback and ADC.
237
249
if not ssl_credentials :
238
- if client_cert_callback :
250
+ use_client_cert = os .getenv (
251
+ environment_vars .GOOGLE_API_USE_CLIENT_CERTIFICATE , "false"
252
+ )
253
+ if use_client_cert == "true" and client_cert_callback :
239
254
# Use the callback if provided.
240
255
cert , key = client_cert_callback ()
241
256
ssl_credentials = grpc .ssl_channel_credentials (
242
257
certificate_chain = cert , private_key = key
243
258
)
244
- else :
259
+ elif use_client_cert == "true" :
245
260
# Use application default SSL credentials.
246
261
adc_ssl_credentils = SslCredentials ()
247
262
ssl_credentials = adc_ssl_credentils .ssl_credentials
263
+ else :
264
+ ssl_credentials = grpc .ssl_channel_credentials ()
248
265
249
266
# Combine the ssl credentials and the authorization credentials.
250
267
composite_credentials = grpc .composite_channel_credentials (
@@ -257,17 +274,29 @@ def my_client_cert_callback():
257
274
class SslCredentials :
258
275
"""Class for application default SSL credentials.
259
276
260
- For devices with endpoint verification support, a device certificate will be
261
- automatically loaded and mutual TLS will be established.
277
+ The behavior is controlled by `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment
278
+ variable whose default value is `false`. Client certificate will not be used
279
+ unless the environment variable is explicitly set to `true`. See
280
+ https://google.aip.dev/auth/4114
281
+
282
+ If the environment variable is `true`, then for devices with endpoint verification
283
+ support, a device certificate will be automatically loaded and mutual TLS will
284
+ be established.
262
285
See https://cloud.google.com/endpoint-verification/docs/overview.
263
286
"""
264
287
265
288
def __init__ (self ):
266
- # Load client SSL credentials.
267
- metadata_path = _mtls_helper ._check_dca_metadata_path (
268
- _mtls_helper .CONTEXT_AWARE_METADATA_PATH
289
+ use_client_cert = os .getenv (
290
+ environment_vars .GOOGLE_API_USE_CLIENT_CERTIFICATE , "false"
269
291
)
270
- self ._is_mtls = metadata_path is not None
292
+ if use_client_cert != "true" :
293
+ self ._is_mtls = False
294
+ else :
295
+ # Load client SSL credentials.
296
+ metadata_path = _mtls_helper ._check_dca_metadata_path (
297
+ _mtls_helper .CONTEXT_AWARE_METADATA_PATH
298
+ )
299
+ self ._is_mtls = metadata_path is not None
271
300
272
301
@property
273
302
def ssl_credentials (self ):
0 commit comments