Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ENVAR for service account impersonation #1763

Open
rhodgkins opened this issue Feb 28, 2024 · 1 comment
Open

Use ENVAR for service account impersonation #1763

rhodgkins opened this issue Feb 28, 2024 · 1 comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.

Comments

@rhodgkins
Copy link

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

I've already raised this in @google-cloud/common, but thought I'd re-raise here as this library seems to be a bit more active.

I was thinking as something as simple as checking for an envar when loading up the ADC and creating an Impersonated auth client here

async _tryGetApplicationCredentialsFromEnvironmentVariable(
options?: RefreshOptions
): Promise<JSONClient | null> {
const credentialsPath =
process.env['GOOGLE_APPLICATION_CREDENTIALS'] ||
process.env['google_application_credentials'];
if (!credentialsPath || credentialsPath.length === 0) {
return null;
}
try {
return this._getApplicationCredentialsFromFilePath(
credentialsPath,
options
);
} catch (e) {
e.message = `Unable to read the credential file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable: ${e.message}`;
throw e;
}
}

  async _tryGetApplicationCredentialsFromEnvironmentVariable(
    options?: RefreshOptions
  ): Promise<JSONClient | null> {
    const credentialsPath =
      process.env['GOOGLE_APPLICATION_CREDENTIALS'] ||
      process.env['google_application_credentials'];
    if (!credentialsPath || credentialsPath.length === 0) {
      // Check if we're trying to impersonate a service account with envar
      if (process.env.CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT) {
        return new Impersonated({
          ...options,
          targetPrincipal: process.env.CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT,
          targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
        })
      }
      return null;
    }
    try {
      return this._getApplicationCredentialsFromFilePath(
        credentialsPath,
        options
      );
    } catch (e) {
      e.message = `Unable to read the credential file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable: ${e.message}`;
      throw e;
    }
  }

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 still not sure if this should be raised here or in @google-cloud/common as previously mentioned, but I feel 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 auth client across the board.

@rhodgkins rhodgkins added priority: p3 Desirable enhancement or fix. May not be included in next release. type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design. labels Feb 28, 2024
@danielbankhead danielbankhead removed their assignment Apr 15, 2024
@Jake7D
Copy link

Jake7D commented Jun 11, 2024

We have a similar scenario where we want to use impersonated service accounts to run tests in a containerised environment.
We've tried a few things to get it working, but it seems currently the only way to do it is by adding additional code in for impersonating (which we avoid at all costs).

Any update on whether this is likely to be implemented?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p3 Desirable enhancement or fix. May not be included in next release. type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.
Projects
None yet
Development

No branches or pull requests

3 participants