in client/jwt/jwt.go [69:118]
func GenerateJWT(ctx context.Context, audience string) (string, error) {
// First, check to see if the GOOGLE_APPLICATION_CREDENTIALS environment
// variable has been set. If so, we can assume we are running on either
// an on-prem environment (ie. not in GCE), or alternatively, we *are*
// running in a GCE VM, but the user has chosen to override the default
// service account with explicit credentials from another account. In
// either case, we want to use this private key file to generate our JWT.
if saKeyFile := os.Getenv(googleCredsEnvVar); saKeyFile != "" {
// Read the service account file manually, as we need the email.
sa, err := os.ReadFile(saKeyFile)
if err != nil {
return "", fmt.Errorf("failed to read service account file: %v", err)
}
conf, err := google.JWTConfigFromJSON(sa)
if err != nil {
return "", fmt.Errorf("could not parse service account JSON: %v", err)
}
// Request an OIDC token from IAM. Creating a new IAM credentials client
// implicitly will look for the private key file specified in the
// GOOGLE_APPLICATION_CREDENTIALS env var, so we don't need to pass
// option.WithCredentials(saKeyFile) as an argument here.
c, err := credentials.NewIamCredentialsClient(ctx)
if err != nil {
return "", fmt.Errorf("could not create a new IAM credentials client: %v", err)
}
defer c.Close()
resp, err := c.GenerateIdToken(ctx, &iamcredspb.GenerateIdTokenRequest{
Name: serviceAccountPrefix + conf.Email,
Audience: audience,
IncludeEmail: true,
})
if err != nil {
return "", fmt.Errorf("error generating ID token: %v", err)
}
return resp.GetToken(), nil
}
// Otherwise, if we're not running in a GCE VM, we can't generate a signed
// JWT from a service account, so return an error.
if !metadata.OnGCE() {
return "", fmt.Errorf("could not find GOOGLE_APPLICATION_CREDENTIALS and not running on GCE")
}
return instanceIdentityToken(audience)
}