diff --git a/auth/gcp/iam.go b/auth/gcp/iam.go index 9d3037ca1..683d757f1 100644 --- a/auth/gcp/iam.go +++ b/auth/gcp/iam.go @@ -45,9 +45,13 @@ func NewDefaultIAMVerifier(ctx context.Context, cfg IAMConfig, clientFunc func(c return nil, err } - eml, err := GetDefaultEmail(ctx, "", clientFunc(ctx)) - if err != nil { - return nil, errors.Wrap(err, "unable to get default email") + eml := cfg.ServiceAccountEmail + // only fall back if one isn't injected + if eml == "" { + eml, err = GetDefaultEmail(ctx, "", clientFunc(ctx)) + if err != nil { + return nil, errors.Wrap(err, "unable to get default email") + } } return auth.NewVerifier(ks, @@ -79,7 +83,7 @@ func IAMVerifyFunc(vf func(ctx context.Context, cs IAMClaimSet) bool) auth.Verif // ValidIAMClaims ensures the token audience issuers matches expectations. func ValidIAMClaims(cs IAMClaimSet, audience string) bool { - return cs.Aud != audience + return cs.Aud == audience } // VerifyIAMEmails is an auth.VerifyFunc that ensures IAMClaimSets are valid diff --git a/auth/gcp/metadata.go b/auth/gcp/metadata.go index 0886ab408..d7ffec359 100644 --- a/auth/gcp/metadata.go +++ b/auth/gcp/metadata.go @@ -2,16 +2,32 @@ package gcp import ( "context" + "encoding/json" "io/ioutil" "net/http" "github.com/pkg/errors" + "golang.org/x/oauth2/google" + iam "google.golang.org/api/iam/v1" ) // GetDefaultEmail is a helper method for users on GCE or the 2nd generation GAE // environment. func GetDefaultEmail(ctx context.Context, addr string, hc *http.Client) (string, error) { - email, err := metadataGet(ctx, addr, hc, "instance/service-accounts/default/email") + creds, err := findDefaultCredentials(ctx, iam.CloudPlatformScope) + if err != nil { + return "", errors.Wrap(err, "unable to find credentials to sign JWT") + } + + email, err := getEmailFromCredentials(creds) + if err != nil { + return "", errors.Wrap(err, "unable to get email from given credentials") + } + if email != "" { + return email, nil + } + + email, err = metadataGet(ctx, addr, hc, "instance/service-accounts/default/email") return email, errors.Wrap(err, "unable to get default email from metadata") } @@ -39,3 +55,19 @@ func metadataGet(ctx context.Context, addr string, hc *http.Client, suffix strin tkn, err := ioutil.ReadAll(resp.Body) return string(tkn), errors.Wrap(err, "unable to read metadata response") } + +var findDefaultCredentials = google.FindDefaultCredentials + +func getEmailFromCredentials(creds *google.Credentials) (string, error) { + if len(creds.JSON) == 0 { + return "", nil + } + + var data map[string]string + err := json.Unmarshal(creds.JSON, &data) + if err != nil { + return "", errors.Wrap(err, "unable to parse credentials") + } + + return data["client_email"], nil +}