googleapis / googleapis/google-cloud-node
Use ENVAR for service account impersonation
- Dominant language
- TypeScript
- Stars
- 3.2k
- Forks
- 712
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 99
Description
**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 `Impersonated` `authClient` 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`](https://github.com/googleapis/nodejs-storage/blob/755c9c2059ddd0cf5e446331f1b04b68417c230f/src/storage.ts#L449) for example) it just loads up a standard `GoogleAuth` 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 use `Impersonated` for example:
```js
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`).
Contributor guide
Assessment
This issue has not been assessed yet.