Is your feature request related to a problem? Please describe.
Simpler, environment wide way to impersonate a service account across multiple client libraries during development when my the local machines ADC is set to a user google account (or a service account) with permissions to act as the specified service account.
Google's best practices also recommend service account impersonation.
Describe the solution you'd like
To use an envar to specify a service account email to be used for client library authentication.
Describe alternatives you've considered
Giving the ADC service account needed permissions - OK until you want to check you've given the deployed code service account the correct permissions (when run in Cloud Run etc.).
Setup the ADC to be an impersonated service account (via gcloud auth application-default login --impersonate-service-account=<>) - pain to have to run that each time you need to target a certain service account (and I think it still needs targetScopes to be specified).
Using user google account with needed permissions - same issues as above, but also some APIs (e.g Identity Toolkit) don't allow authorized_user credentials without a quota project needing it to be specified (which is added boilerplate).
Passing in an GoogleAuth (which has been created with an ImpersonatedauthClient option) using the authClient when creating each client library - just extra boilerplate to do for each client.
Using a downloaded service account key file and setting GOOGLE_APPLICATION_CREDENTIALS envar to the file local before starting - I don't want to have service account key files downloaded.
Additional context
Currently if no authClient is provided to a Service (and any inherited services, Storage for example) it just loads up a standard GoogleAuth object, as below:
The improvement would be, instead of falling back to a normal GoogleAuth above, it could check for the envar and use Impersonated for example:
if (googleAutoAuthConfig.authClient instanceof GoogleAuth) {
// Use an existing `GoogleAuth`
authClient = googleAutoAuthConfig.authClient;
} else {
// Pass an `AuthClient` to `GoogleAuth`, if available
const config = {
...googleAutoAuthConfig,
authClient: googleAutoAuthConfig.authClient,
};
// Check if we're trying to impersonate a service account
if (process.env.CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT) {
config.authClient = new Impersonated({
...config, // Not sure if this would be needed - picking up the googleAutoAuthConfig
sourceClient: config.authClient,
targetPrincipal: process.env.CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT,
targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
})
}
authClient = new GoogleAuth(config);
}
It wouldn't break anything for people already using a specified GoogleAuth in googleAutoAuthConfig.authClient, even with the envar set.
I've used the gcloud envar for service account impersonation just for an example.
Also I've noticed gcloud logs out warnings when using the --impersonated-service-account option - that could be added here too, to warn the user what's happening?
Note - I'm not sure if this should be raised here or in google-auth-library when tries to load things in GoogleAuth, but I can see where could possible fit in here so thought I'd start by raising it here... (It would probably be more useful if it could be done at the google-auth-library level as then if you created a GoogleAuth it would automatically be impersonated, but then if you're dropping to the google-auth-library level (and not using a client library) you're possibly doing something a bit more "custom" and can just handle it yourself when creating the GoogleAuth).
Is your feature request related to a problem? Please describe. Simpler, environment wide way to impersonate a service account across multiple client libraries during development when my the local machines ADC is set to a user google account (or a service account) with permissions to act as the specified service account. Google's best practices also recommend service account impersonation.
Describe the solution you'd like To use an envar to specify a service account email to be used for client library authentication.
Describe alternatives you've considered
gcloud auth application-default login --impersonate-service-account=<>
) - pain to have to run that each time you need to target a certain service account (and I think it still needstargetScopes
to be specified).authorized_user
credentials without a quota project needing it to be specified (which is added boilerplate).GoogleAuth
(which has been created with anImpersonated
authClient
option) using theauthClient
when creating each client library - just extra boilerplate to do for each client.Using a downloaded service account key file and setting
GOOGLE_APPLICATION_CREDENTIALS
envar to the file local before starting - I don't want to have service account key files downloaded.Additional context
Currently if no
authClient
is provided to aService
(and any inherited services,Storage
for example) it just loads up a standardGoogleAuth
object, as below:https://github.com/googleapis/nodejs-common/blob/43bfde79a24fe67e101e70945b09a1412c5eace9/src/util.ts#L606-L617
The improvement would be, instead of falling back to a normal
GoogleAuth
above, it could check for the envar and useImpersonated
for example:It wouldn't break anything for people already using a specified
GoogleAuth
ingoogleAutoAuthConfig.authClient
, even with the envar set.I've used the
gcloud
envar for service account impersonation just for an example. Also I've noticedgcloud
logs out warnings when using the--impersonated-service-account
option - that could be added here too, to warn the user what's happening?Note - I'm not sure if this should be raised here or in
google-auth-library
when tries to load things inGoogleAuth
, but I can see where could possible fit in here so thought I'd start by raising it here... (It would probably be more useful if it could be done at thegoogle-auth-library
level as then if you created aGoogleAuth
it would automatically be impersonated, but then if you're dropping to thegoogle-auth-library
level (and not using a client library) you're possibly doing something a bit more "custom" and can just handle it yourself when creating theGoogleAuth
).