3232from google .oauth2 import _client
3333
3434
35- class Credentials (credentials .ReadOnlyScoped , credentials .CredentialsWithQuotaProject ):
35+ class Credentials (credentials .Scoped , credentials .CredentialsWithQuotaProject ):
3636 """Compute Engine Credentials.
3737
3838 These credentials use the Google Compute Engine metadata server to obtain
39- OAuth 2.0 access tokens associated with the instance's service account.
39+ OAuth 2.0 access tokens associated with the instance's service account,
40+ and are also used for Cloud Run, Flex and App Engine (except for the Python
41+ 2.7 runtime).
4042
4143 For more information about Compute Engine authentication, including how
4244 to configure scopes, see the `Compute Engine authentication
4345 documentation`_.
4446
45- .. note:: Compute Engine instances can be created with scopes and therefore
46- these credentials are considered to be 'scoped'. However, you can
47- not use :meth:`~google.auth.credentials.ScopedCredentials.with_scopes`
48- because it is not possible to change the scopes that the instance
49- has. Also note that
50- :meth:`~google.auth.credentials.ScopedCredentials.has_scopes` will not
51- work until the credentials have been refreshed.
47+ .. note:: On Compute Engine the metadata server ignores requested scopes.
48+ On Cloud Run, Flex and App Engine the server honours requested scopes.
5249
5350 .. _Compute Engine authentication documentation:
5451 https://cloud.google.com/compute/docs/authentication#using
5552 """
5653
57- def __init__ (self , service_account_email = "default" , quota_project_id = None ):
54+ def __init__ (
55+ self , service_account_email = "default" , quota_project_id = None , scopes = None
56+ ):
5857 """
5958 Args:
6059 service_account_email (str): The service account email to use, or
@@ -66,6 +65,7 @@ def __init__(self, service_account_email="default", quota_project_id=None):
6665 super (Credentials , self ).__init__ ()
6766 self ._service_account_email = service_account_email
6867 self ._quota_project_id = quota_project_id
68+ self ._scopes = scopes
6969
7070 def _retrieve_info (self , request ):
7171 """Retrieve information about the service account.
@@ -81,7 +81,10 @@ def _retrieve_info(self, request):
8181 )
8282
8383 self ._service_account_email = info ["email" ]
84- self ._scopes = info ["scopes" ]
84+
85+ # Don't override scopes requested by the user.
86+ if self ._scopes is None :
87+ self ._scopes = info ["scopes" ]
8588
8689 def refresh (self , request ):
8790 """Refresh the access token and scopes.
@@ -98,7 +101,9 @@ def refresh(self, request):
98101 try :
99102 self ._retrieve_info (request )
100103 self .token , self .expiry = _metadata .get_service_account_token (
101- request , service_account = self ._service_account_email
104+ request ,
105+ service_account = self ._service_account_email ,
106+ scopes = self ._scopes ,
102107 )
103108 except exceptions .TransportError as caught_exc :
104109 new_exc = exceptions .RefreshError (caught_exc )
@@ -115,14 +120,25 @@ def service_account_email(self):
115120
116121 @property
117122 def requires_scopes (self ):
118- """False: Compute Engine credentials can not be scoped."""
119- return False
123+ return not self ._scopes
120124
121125 @_helpers .copy_docstring (credentials .CredentialsWithQuotaProject )
122126 def with_quota_project (self , quota_project_id ):
123127 return self .__class__ (
124128 service_account_email = self ._service_account_email ,
125129 quota_project_id = quota_project_id ,
130+ scopes = self ._scopes ,
131+ )
132+
133+ @_helpers .copy_docstring (credentials .Scoped )
134+ def with_scopes (self , scopes ):
135+ # Compute Engine credentials can not be scoped (the metadata service
136+ # ignores the scopes parameter). App Engine, Cloud Run and Flex support
137+ # requesting scopes.
138+ return self .__class__ (
139+ scopes = scopes ,
140+ service_account_email = self ._service_account_email ,
141+ quota_project_id = self ._quota_project_id ,
126142 )
127143
128144
0 commit comments