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

fix(auth): Migrate IAM SignBlob to IAMCredentials SignBlob #404

Merged
merged 3 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ func NewClient(ctx context.Context, conf *internal.AuthConfig) (*Client, error)
// - If the SDK was initialized with service account credentials, uses the private key present in
// the credentials to sign tokens locally.
// - If a service account email was specified during initialization (via firebase.Config struct),
// calls the IAM service with that email to sign tokens remotely. See
// https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signBlob.
// calls the IAMCredentials service with that email to sign tokens remotely. See
// https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob.
// - If the code is deployed in the Google App Engine standard environment, uses the App Identity
// service to sign tokens. See https://cloud.google.com/appengine/docs/standard/go/reference#SignBytes.
// - If the code is deployed in a different GCP-managed environment (e.g. Google Compute Engine),
Expand Down
14 changes: 7 additions & 7 deletions auth/token_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ func (s serviceAccountSigner) Email(ctx context.Context) (string, error) {
return s.clientEmail, nil
}

// iamSigner is a cryptoSigner that signs data by sending them to the remote IAM service. See
// https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signBlob for details
// regarding the REST API.
// iamSigner is a cryptoSigner that signs data by sending them to the IAMCredentials service. See
// https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob
// for details regarding the REST API.
//
// The IAM service requires the identity of a service account. This can be specified explicitly
// IAMCredentials requires the identity of a service account. This can be specified explicitly
// at initialization. If not specified iamSigner attempts to discover a service account identity by
// calling the local metadata service (works in environments like Google Compute Engine).
type iamSigner struct {
Expand All @@ -169,7 +169,7 @@ func newIAMSigner(ctx context.Context, config *internal.AuthConfig) (*iamSigner,
httpClient: hc,
serviceAcct: config.ServiceAccountID,
metadataHost: "http://metadata.google.internal",
iamHost: "https://iam.googleapis.com",
iamHost: "https://iamcredentials.googleapis.com",
}, nil
}

Expand All @@ -181,15 +181,15 @@ func (s iamSigner) Sign(ctx context.Context, b []byte) ([]byte, error) {

url := fmt.Sprintf("%s/v1/projects/-/serviceAccounts/%s:signBlob", s.iamHost, account)
body := map[string]interface{}{
"bytesToSign": base64.StdEncoding.EncodeToString(b),
"payload": base64.StdEncoding.EncodeToString(b),
}
req := &internal.Request{
Method: http.MethodPost,
URL: url,
Body: internal.NewJSONEntity(body),
}
var signResponse struct {
Signature string `json:"signature"`
Signature string `json:"signedBlob"`
}
if _, err := s.httpClient.DoAndUnmarshal(ctx, req, &signResponse); err != nil {
return nil, err
Expand Down
12 changes: 6 additions & 6 deletions auth/token_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func TestEncodeToken(t *testing.T) {

if sig, err := base64.RawURLEncoding.DecodeString(parts[2]); err != nil {
t.Fatal(err)
} else if string(sig) != "signature" {
t.Errorf("decode(signature) = %q; want = %q", string(sig), "signature")
} else if string(sig) != "signedBlob" {
t.Errorf("decode(signature) = %q; want = %q", string(sig), "signedBlob")
}
}

Expand Down Expand Up @@ -277,12 +277,12 @@ func (s *mockSigner) Sign(ctx context.Context, b []byte) ([]byte, error) {
if s.err != nil {
return nil, s.err
}
return []byte("signature"), nil
return []byte("signedBlob"), nil
}

func iamServer(t *testing.T, serviceAcct, signature string) *httptest.Server {
resp := map[string]interface{}{
"signature": base64.StdEncoding.EncodeToString([]byte(signature)),
"signedBlob": base64.StdEncoding.EncodeToString([]byte(signature)),
}
wantPath := fmt.Sprintf("/v1/projects/-/serviceAccounts/%s:signBlob", serviceAcct)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -295,8 +295,8 @@ func iamServer(t *testing.T, serviceAcct, signature string) *httptest.Server {
if err := json.Unmarshal(reqBody, &m); err != nil {
t.Fatal(err)
}
if m["bytesToSign"] == "" {
t.Fatal("BytesToSign = empty; want = non-empty")
if m["payload"] == "" {
t.Fatal("payload = empty; want = non-empty")
}
if r.URL.Path != wantPath {
t.Errorf("Path = %q; want = %q", r.URL.Path, wantPath)
Expand Down