@@ -131,6 +131,7 @@ def __init__(
131131 project_id = None ,
132132 quota_project_id = None ,
133133 additional_claims = None ,
134+ always_use_jwt_access = False ,
134135 ):
135136 """
136137 Args:
@@ -149,6 +150,8 @@ def __init__(
149150 billing.
150151 additional_claims (Mapping[str, str]): Any additional claims for
151152 the JWT assertion used in the authorization grant.
153+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
154+ be always used.
152155
153156 .. note:: Typically one of the helper constructors
154157 :meth:`from_service_account_file` or
@@ -165,6 +168,7 @@ def __init__(
165168 self ._project_id = project_id
166169 self ._quota_project_id = quota_project_id
167170 self ._token_uri = token_uri
171+ self ._always_use_jwt_access = always_use_jwt_access
168172
169173 self ._jwt_credentials = None
170174
@@ -266,6 +270,30 @@ def with_scopes(self, scopes, default_scopes=None):
266270 project_id = self ._project_id ,
267271 quota_project_id = self ._quota_project_id ,
268272 additional_claims = self ._additional_claims .copy (),
273+ always_use_jwt_access = self ._always_use_jwt_access ,
274+ )
275+
276+ def with_always_use_jwt_access (self , always_use_jwt_access ):
277+ """Create a copy of these credentials with the specified always_use_jwt_access value.
278+
279+ Args:
280+ always_use_jwt_access (bool): Whether always use self signed JWT or not.
281+
282+ Returns:
283+ google.auth.service_account.Credentials: A new credentials
284+ instance.
285+ """
286+ return self .__class__ (
287+ self ._signer ,
288+ service_account_email = self ._service_account_email ,
289+ scopes = self ._scopes ,
290+ default_scopes = self ._default_scopes ,
291+ token_uri = self ._token_uri ,
292+ subject = self ._subject ,
293+ project_id = self ._project_id ,
294+ quota_project_id = self ._quota_project_id ,
295+ additional_claims = self ._additional_claims .copy (),
296+ always_use_jwt_access = always_use_jwt_access ,
269297 )
270298
271299 def with_subject (self , subject ):
@@ -288,6 +316,7 @@ def with_subject(self, subject):
288316 project_id = self ._project_id ,
289317 quota_project_id = self ._quota_project_id ,
290318 additional_claims = self ._additional_claims .copy (),
319+ always_use_jwt_access = self ._always_use_jwt_access ,
291320 )
292321
293322 def with_claims (self , additional_claims ):
@@ -315,6 +344,7 @@ def with_claims(self, additional_claims):
315344 project_id = self ._project_id ,
316345 quota_project_id = self ._quota_project_id ,
317346 additional_claims = new_additional_claims ,
347+ always_use_jwt_access = self ._always_use_jwt_access ,
318348 )
319349
320350 @_helpers .copy_docstring (credentials .CredentialsWithQuotaProject )
@@ -330,6 +360,7 @@ def with_quota_project(self, quota_project_id):
330360 project_id = self ._project_id ,
331361 quota_project_id = quota_project_id ,
332362 additional_claims = self ._additional_claims .copy (),
363+ always_use_jwt_access = self ._always_use_jwt_access ,
333364 )
334365
335366 def _make_authorization_grant_assertion (self ):
@@ -386,8 +417,22 @@ def _create_self_signed_jwt(self, audience):
386417 audience (str): The service URL. ``https://[API_ENDPOINT]/``
387418 """
388419 # https://google.aip.dev/auth/4111
389- # If the user has not defined scopes, create a self-signed jwt
390- if not self .scopes :
420+ if self ._always_use_jwt_access :
421+ if self ._scopes :
422+ self ._jwt_credentials = jwt .Credentials .from_signing_credentials (
423+ self , None , additional_claims = {"scope" : " " .join (self ._scopes )}
424+ )
425+ elif audience :
426+ self ._jwt_credentials = jwt .Credentials .from_signing_credentials (
427+ self , audience
428+ )
429+ elif self ._default_scopes :
430+ self ._jwt_credentials = jwt .Credentials .from_signing_credentials (
431+ self ,
432+ None ,
433+ additional_claims = {"scope" : " " .join (self ._default_scopes )},
434+ )
435+ elif not self ._scopes and audience :
391436 self ._jwt_credentials = jwt .Credentials .from_signing_credentials (
392437 self , audience
393438 )
0 commit comments