package iam import ( "fmt" "os" "path/filepath" "edge-infra.dev/pkg/lib/errors" "github.com/mitchellh/go-homedir" ) const ( // GoogleAppCredsEnvVar contains the env var name used to pass creds file // paths to google tooling GoogleAppCredsEnvVar = "GOOGLE_APPLICATION_CREDENTIALS" // nolint:gosec ) // ResolveGoogleAppCreds resolves the Google app creds file path // (https://cloud.google.com/docs/authentication/production) in this order: // - GOOGLE_APPLICATION_CREDENTIALS // - default location on disk // and will return an error if none of the three are present func ResolveGoogleAppCreds() (string, error) { if os.Getenv(GoogleAppCredsEnvVar) != "" { return os.Getenv(GoogleAppCredsEnvVar), nil } return DefaultGoogleAppCredsPath() } func DefaultGoogleAppCredsPath() (string, error) { // resolve home dir home, err := homedir.Dir() if err != nil { return "", errors.Wrap(err) } home, err = homedir.Expand(home) if err != nil { return "", errors.Wrap(err) } p := filepath.Join(home, ".config/gcloud/application_default_credentials.json") if _, err := os.Stat(p); err != nil { return "", errors.New( fmt.Sprintf("couldnt find google default application credentials at %s", p), err, ) } return p, nil } // CredentialsFile represents the JSON structure of Google creds files, // e.g., service account key files and default app creds files type CredentialsFile struct { Type string `json:"type"` // service_account or authorized_user // Service Account fields ClientEmail string `json:"client_email,omitempty"` PrivateKeyID string `json:"private_key_id,omitempty"` PrivateKey string `json:"private_key,omitempty"` TokenURL string `json:"token_uri,omitempty"` ProjectID string `json:"project_id,omitempty"` // User Credential fields // (These typically come from gcloud auth.) ClientSecret string `json:"client_secret,omitempty"` ClientID string `json:"client_id,omitempty"` RefreshToken string `json:"refresh_token,omitempty"` QuotaProjectID string `json:"quota_project_id,omitempty"` }