Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit af02a9c

Browse files
fix: enable self signed jwt for grpc (#958)
1 parent d4994b2 commit af02a9c

14 files changed

Lines changed: 160 additions & 86 deletions

File tree

gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
304304
client_cert_source_for_mtls=client_cert_source_func,
305305
quota_project_id=client_options.quota_project_id,
306306
client_info=client_info,
307+
{% if "grpc" in opts.transport %}
308+
always_use_jwt_access=(
309+
Transport == type(self).get_transport_class("grpc")
310+
or Transport == type(self).get_transport_class("grpc_asyncio")
311+
),
312+
{% endif %}
307313
)
308314

309315

gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,6 @@ def test_{{ service.client_name|snake_case }}_from_service_account_info(client_c
113113
{% endif %}
114114

115115

116-
@pytest.mark.parametrize("client_class", [
117-
{{ service.client_name }},
118-
{% if 'grpc' in opts.transport %}
119-
{{ service.async_client_name }},
120-
{% endif %}
121-
])
122-
def test_{{ service.client_name|snake_case }}_service_account_always_use_jwt(client_class):
123-
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
124-
creds = service_account.Credentials(None, None, None)
125-
client = client_class(credentials=creds)
126-
use_jwt.assert_not_called()
127-
128-
129116
@pytest.mark.parametrize("transport_class,transport_name", [
130117
{% if 'grpc' in opts.transport %}
131118
(transports.{{ service.grpc_transport_name }}, "grpc"),
@@ -134,12 +121,17 @@ def test_{{ service.client_name|snake_case }}_service_account_always_use_jwt(cli
134121
(transports.{{ service.rest_transport_name }}, "rest"),
135122
{% endif %}
136123
])
137-
def test_{{ service.client_name|snake_case }}_service_account_always_use_jwt_true(transport_class, transport_name):
124+
def test_{{ service.client_name|snake_case }}_service_account_always_use_jwt(transport_class, transport_name):
138125
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
139126
creds = service_account.Credentials(None, None, None)
140127
transport = transport_class(credentials=creds, always_use_jwt_access=True)
141128
use_jwt.assert_called_once_with(True)
142129

130+
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
131+
creds = service_account.Credentials(None, None, None)
132+
transport = transport_class(credentials=creds, always_use_jwt_access=False)
133+
use_jwt.assert_not_called()
134+
143135

144136
@pytest.mark.parametrize("client_class", [
145137
{{ service.client_name }},
@@ -216,6 +208,9 @@ def test_{{ service.client_name|snake_case }}_client_options(client_class, trans
216208
client_cert_source_for_mtls=None,
217209
quota_project_id=None,
218210
client_info=transports.base.DEFAULT_CLIENT_INFO,
211+
{% if 'grpc' in opts.transport %}
212+
always_use_jwt_access=True,
213+
{% endif %}
219214
)
220215

221216
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -232,6 +227,9 @@ def test_{{ service.client_name|snake_case }}_client_options(client_class, trans
232227
client_cert_source_for_mtls=None,
233228
quota_project_id=None,
234229
client_info=transports.base.DEFAULT_CLIENT_INFO,
230+
{% if 'grpc' in opts.transport %}
231+
always_use_jwt_access=True,
232+
{% endif %}
235233
)
236234

237235
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -248,6 +246,9 @@ def test_{{ service.client_name|snake_case }}_client_options(client_class, trans
248246
client_cert_source_for_mtls=None,
249247
quota_project_id=None,
250248
client_info=transports.base.DEFAULT_CLIENT_INFO,
249+
{% if 'grpc' in opts.transport %}
250+
always_use_jwt_access=True,
251+
{% endif %}
251252
)
252253

253254
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
@@ -274,6 +275,9 @@ def test_{{ service.client_name|snake_case }}_client_options(client_class, trans
274275
client_cert_source_for_mtls=None,
275276
quota_project_id="octopus",
276277
client_info=transports.base.DEFAULT_CLIENT_INFO,
278+
{% if 'grpc' in opts.transport %}
279+
always_use_jwt_access=True,
280+
{% endif %}
277281
)
278282

279283
@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [
@@ -319,6 +323,9 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(client_class, transp
319323
client_cert_source_for_mtls=expected_client_cert_source,
320324
quota_project_id=None,
321325
client_info=transports.base.DEFAULT_CLIENT_INFO,
326+
{% if 'grpc' in opts.transport %}
327+
always_use_jwt_access=True,
328+
{% endif %}
322329
)
323330

324331
# Check the case ADC client cert is provided. Whether client cert is used depends on
@@ -344,6 +351,9 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(client_class, transp
344351
client_cert_source_for_mtls=expected_client_cert_source,
345352
quota_project_id=None,
346353
client_info=transports.base.DEFAULT_CLIENT_INFO,
354+
{% if 'grpc' in opts.transport %}
355+
always_use_jwt_access=True,
356+
{% endif %}
347357
)
348358

349359
# Check the case client_cert_source and ADC client cert are not provided.
@@ -360,6 +370,9 @@ def test_{{ service.client_name|snake_case }}_mtls_env_auto(client_class, transp
360370
client_cert_source_for_mtls=None,
361371
quota_project_id=None,
362372
client_info=transports.base.DEFAULT_CLIENT_INFO,
373+
{% if 'grpc' in opts.transport %}
374+
always_use_jwt_access=True,
375+
{% endif %}
363376
)
364377

365378

@@ -387,6 +400,9 @@ def test_{{ service.client_name|snake_case }}_client_options_scopes(client_class
387400
client_cert_source_for_mtls=None,
388401
quota_project_id=None,
389402
client_info=transports.base.DEFAULT_CLIENT_INFO,
403+
{% if 'grpc' in opts.transport %}
404+
always_use_jwt_access=True,
405+
{% endif %}
390406
)
391407

392408
@pytest.mark.parametrize("client_class,transport_class,transport_name", [
@@ -413,6 +429,9 @@ def test_{{ service.client_name|snake_case }}_client_options_credentials_file(cl
413429
client_cert_source_for_mtls=None,
414430
quota_project_id=None,
415431
client_info=transports.base.DEFAULT_CLIENT_INFO,
432+
{% if 'grpc' in opts.transport %}
433+
always_use_jwt_access=True,
434+
{% endif %}
416435
)
417436
{% if 'grpc' in opts.transport %}
418437

@@ -431,6 +450,7 @@ def test_{{ service.client_name|snake_case }}_client_options_from_dict():
431450
client_cert_source_for_mtls=None,
432451
quota_project_id=None,
433452
client_info=transports.base.DEFAULT_CLIENT_INFO,
453+
always_use_jwt_access=True,
434454
)
435455
{% endif %}
436456

tests/integration/goldens/asset/google/cloud/asset_v1/services/asset_service/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ def __init__(self, *,
344344
client_cert_source_for_mtls=client_cert_source_func,
345345
quota_project_id=client_options.quota_project_id,
346346
client_info=client_info,
347+
always_use_jwt_access=(
348+
Transport == type(self).get_transport_class("grpc")
349+
or Transport == type(self).get_transport_class("grpc_asyncio")
350+
),
347351
)
348352

349353
def export_assets(self,

tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,21 @@ def test_asset_service_client_from_service_account_info(client_class):
105105
assert client.transport._host == 'cloudasset.googleapis.com:443'
106106

107107

108-
@pytest.mark.parametrize("client_class", [
109-
AssetServiceClient,
110-
AssetServiceAsyncClient,
111-
])
112-
def test_asset_service_client_service_account_always_use_jwt(client_class):
113-
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
114-
creds = service_account.Credentials(None, None, None)
115-
client = client_class(credentials=creds)
116-
use_jwt.assert_not_called()
117-
118-
119108
@pytest.mark.parametrize("transport_class,transport_name", [
120109
(transports.AssetServiceGrpcTransport, "grpc"),
121110
(transports.AssetServiceGrpcAsyncIOTransport, "grpc_asyncio"),
122111
])
123-
def test_asset_service_client_service_account_always_use_jwt_true(transport_class, transport_name):
112+
def test_asset_service_client_service_account_always_use_jwt(transport_class, transport_name):
124113
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
125114
creds = service_account.Credentials(None, None, None)
126115
transport = transport_class(credentials=creds, always_use_jwt_access=True)
127116
use_jwt.assert_called_once_with(True)
128117

118+
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
119+
creds = service_account.Credentials(None, None, None)
120+
transport = transport_class(credentials=creds, always_use_jwt_access=False)
121+
use_jwt.assert_not_called()
122+
129123

130124
@pytest.mark.parametrize("client_class", [
131125
AssetServiceClient,
@@ -190,6 +184,7 @@ def test_asset_service_client_client_options(client_class, transport_class, tran
190184
client_cert_source_for_mtls=None,
191185
quota_project_id=None,
192186
client_info=transports.base.DEFAULT_CLIENT_INFO,
187+
always_use_jwt_access=True,
193188
)
194189

195190
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -206,6 +201,7 @@ def test_asset_service_client_client_options(client_class, transport_class, tran
206201
client_cert_source_for_mtls=None,
207202
quota_project_id=None,
208203
client_info=transports.base.DEFAULT_CLIENT_INFO,
204+
always_use_jwt_access=True,
209205
)
210206

211207
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -222,6 +218,7 @@ def test_asset_service_client_client_options(client_class, transport_class, tran
222218
client_cert_source_for_mtls=None,
223219
quota_project_id=None,
224220
client_info=transports.base.DEFAULT_CLIENT_INFO,
221+
always_use_jwt_access=True,
225222
)
226223

227224
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
@@ -248,6 +245,7 @@ def test_asset_service_client_client_options(client_class, transport_class, tran
248245
client_cert_source_for_mtls=None,
249246
quota_project_id="octopus",
250247
client_info=transports.base.DEFAULT_CLIENT_INFO,
248+
always_use_jwt_access=True,
251249
)
252250

253251
@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [
@@ -286,6 +284,7 @@ def test_asset_service_client_mtls_env_auto(client_class, transport_class, trans
286284
client_cert_source_for_mtls=expected_client_cert_source,
287285
quota_project_id=None,
288286
client_info=transports.base.DEFAULT_CLIENT_INFO,
287+
always_use_jwt_access=True,
289288
)
290289

291290
# Check the case ADC client cert is provided. Whether client cert is used depends on
@@ -311,6 +310,7 @@ def test_asset_service_client_mtls_env_auto(client_class, transport_class, trans
311310
client_cert_source_for_mtls=expected_client_cert_source,
312311
quota_project_id=None,
313312
client_info=transports.base.DEFAULT_CLIENT_INFO,
313+
always_use_jwt_access=True,
314314
)
315315

316316
# Check the case client_cert_source and ADC client cert are not provided.
@@ -327,6 +327,7 @@ def test_asset_service_client_mtls_env_auto(client_class, transport_class, trans
327327
client_cert_source_for_mtls=None,
328328
quota_project_id=None,
329329
client_info=transports.base.DEFAULT_CLIENT_INFO,
330+
always_use_jwt_access=True,
330331
)
331332

332333

@@ -350,6 +351,7 @@ def test_asset_service_client_client_options_scopes(client_class, transport_clas
350351
client_cert_source_for_mtls=None,
351352
quota_project_id=None,
352353
client_info=transports.base.DEFAULT_CLIENT_INFO,
354+
always_use_jwt_access=True,
353355
)
354356

355357
@pytest.mark.parametrize("client_class,transport_class,transport_name", [
@@ -372,6 +374,7 @@ def test_asset_service_client_client_options_credentials_file(client_class, tran
372374
client_cert_source_for_mtls=None,
373375
quota_project_id=None,
374376
client_info=transports.base.DEFAULT_CLIENT_INFO,
377+
always_use_jwt_access=True,
375378
)
376379

377380

@@ -389,6 +392,7 @@ def test_asset_service_client_client_options_from_dict():
389392
client_cert_source_for_mtls=None,
390393
quota_project_id=None,
391394
client_info=transports.base.DEFAULT_CLIENT_INFO,
395+
always_use_jwt_access=True,
392396
)
393397

394398

tests/integration/goldens/credentials/google/iam/credentials_v1/services/iam_credentials/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ def __init__(self, *,
340340
client_cert_source_for_mtls=client_cert_source_func,
341341
quota_project_id=client_options.quota_project_id,
342342
client_info=client_info,
343+
always_use_jwt_access=(
344+
Transport == type(self).get_transport_class("grpc")
345+
or Transport == type(self).get_transport_class("grpc_asyncio")
346+
),
343347
)
344348

345349
def generate_access_token(self,

tests/integration/goldens/credentials/tests/unit/gapic/credentials_v1/test_iam_credentials.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,27 +97,21 @@ def test_iam_credentials_client_from_service_account_info(client_class):
9797
assert client.transport._host == 'iamcredentials.googleapis.com:443'
9898

9999

100-
@pytest.mark.parametrize("client_class", [
101-
IAMCredentialsClient,
102-
IAMCredentialsAsyncClient,
103-
])
104-
def test_iam_credentials_client_service_account_always_use_jwt(client_class):
105-
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
106-
creds = service_account.Credentials(None, None, None)
107-
client = client_class(credentials=creds)
108-
use_jwt.assert_not_called()
109-
110-
111100
@pytest.mark.parametrize("transport_class,transport_name", [
112101
(transports.IAMCredentialsGrpcTransport, "grpc"),
113102
(transports.IAMCredentialsGrpcAsyncIOTransport, "grpc_asyncio"),
114103
])
115-
def test_iam_credentials_client_service_account_always_use_jwt_true(transport_class, transport_name):
104+
def test_iam_credentials_client_service_account_always_use_jwt(transport_class, transport_name):
116105
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
117106
creds = service_account.Credentials(None, None, None)
118107
transport = transport_class(credentials=creds, always_use_jwt_access=True)
119108
use_jwt.assert_called_once_with(True)
120109

110+
with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt:
111+
creds = service_account.Credentials(None, None, None)
112+
transport = transport_class(credentials=creds, always_use_jwt_access=False)
113+
use_jwt.assert_not_called()
114+
121115

122116
@pytest.mark.parametrize("client_class", [
123117
IAMCredentialsClient,
@@ -182,6 +176,7 @@ def test_iam_credentials_client_client_options(client_class, transport_class, tr
182176
client_cert_source_for_mtls=None,
183177
quota_project_id=None,
184178
client_info=transports.base.DEFAULT_CLIENT_INFO,
179+
always_use_jwt_access=True,
185180
)
186181

187182
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -198,6 +193,7 @@ def test_iam_credentials_client_client_options(client_class, transport_class, tr
198193
client_cert_source_for_mtls=None,
199194
quota_project_id=None,
200195
client_info=transports.base.DEFAULT_CLIENT_INFO,
196+
always_use_jwt_access=True,
201197
)
202198

203199
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
@@ -214,6 +210,7 @@ def test_iam_credentials_client_client_options(client_class, transport_class, tr
214210
client_cert_source_for_mtls=None,
215211
quota_project_id=None,
216212
client_info=transports.base.DEFAULT_CLIENT_INFO,
213+
always_use_jwt_access=True,
217214
)
218215

219216
# Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
@@ -240,6 +237,7 @@ def test_iam_credentials_client_client_options(client_class, transport_class, tr
240237
client_cert_source_for_mtls=None,
241238
quota_project_id="octopus",
242239
client_info=transports.base.DEFAULT_CLIENT_INFO,
240+
always_use_jwt_access=True,
243241
)
244242

245243
@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [
@@ -278,6 +276,7 @@ def test_iam_credentials_client_mtls_env_auto(client_class, transport_class, tra
278276
client_cert_source_for_mtls=expected_client_cert_source,
279277
quota_project_id=None,
280278
client_info=transports.base.DEFAULT_CLIENT_INFO,
279+
always_use_jwt_access=True,
281280
)
282281

283282
# Check the case ADC client cert is provided. Whether client cert is used depends on
@@ -303,6 +302,7 @@ def test_iam_credentials_client_mtls_env_auto(client_class, transport_class, tra
303302
client_cert_source_for_mtls=expected_client_cert_source,
304303
quota_project_id=None,
305304
client_info=transports.base.DEFAULT_CLIENT_INFO,
305+
always_use_jwt_access=True,
306306
)
307307

308308
# Check the case client_cert_source and ADC client cert are not provided.
@@ -319,6 +319,7 @@ def test_iam_credentials_client_mtls_env_auto(client_class, transport_class, tra
319319
client_cert_source_for_mtls=None,
320320
quota_project_id=None,
321321
client_info=transports.base.DEFAULT_CLIENT_INFO,
322+
always_use_jwt_access=True,
322323
)
323324

324325

@@ -342,6 +343,7 @@ def test_iam_credentials_client_client_options_scopes(client_class, transport_cl
342343
client_cert_source_for_mtls=None,
343344
quota_project_id=None,
344345
client_info=transports.base.DEFAULT_CLIENT_INFO,
346+
always_use_jwt_access=True,
345347
)
346348

347349
@pytest.mark.parametrize("client_class,transport_class,transport_name", [
@@ -364,6 +366,7 @@ def test_iam_credentials_client_client_options_credentials_file(client_class, tr
364366
client_cert_source_for_mtls=None,
365367
quota_project_id=None,
366368
client_info=transports.base.DEFAULT_CLIENT_INFO,
369+
always_use_jwt_access=True,
367370
)
368371

369372

@@ -381,6 +384,7 @@ def test_iam_credentials_client_client_options_from_dict():
381384
client_cert_source_for_mtls=None,
382385
quota_project_id=None,
383386
client_info=transports.base.DEFAULT_CLIENT_INFO,
387+
always_use_jwt_access=True,
384388
)
385389

386390

0 commit comments

Comments
 (0)