1

I'm reading the documentation for Cloud Identity and Access Management Method: projects.serviceAccounts.signBlob. I've got it figured out except for the body, which is

{
  "bytesToSign": string
}

The documentation says that this should be

The bytes to sign.

A base64-encoded string.

Gosh, how helpful! Can anyone explain what bytesToSign is? What do I put there? The service account private key?

Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100
  • This is often used to sign a JWT to request an Access Token. What are you trying to do? – John Hanley Nov 16 '18 at 00:36
  • I'm trying to get the download URL for files in my Firebase Storage. I'm getting a SigningError message: "Permission iam.serviceAccounts.signBlob is required to perform this operation." – Thomas David Kehoe Nov 16 '18 at 15:55
  • Here is my answer to another question on the exact steps to add permissions to use `signBlob`: https://stackoverflow.com/questions/53344238/unable-to-sign-jwt-when-using-serviceaccountid/53346892#53346892 – John Hanley Nov 17 '18 at 00:10

2 Answers2

3

The Google Cloud Platform (GCP) IAM API method projects.serviceAccounts.signBlob allows you to cryptographically "sign" a blob of data using the system-managed private key for a given service account.

More info: Digital Signature

Permissions

In order to sign blobs using a service account, you need to make sure your account has the iam.serviceAccounts.signBlob permission on the service account in question. The easiest way to do this is to grant your account the Service Account Token Creator on the Project or the Service Account. This role contains the following permissions:

  • iam.serviceAccounts.get
  • iam.serviceAccounts.getAccessToken
  • iam.serviceAccounts.implicitDelegation
  • iam.serviceAccounts.list
  • iam.serviceAccounts.signBlob
  • iam.serviceAccounts.signJwt
  • resourcemanager.projects.get
  • resourcemanager.projects.list

Using the API

This API endpoint takes two arguments:

  • service account name (in the URL of the request)
  • blob that you would like to cryptographically sign (in the body of the request)

As an example, let's say that you want to sign this text:

Here is some text that I would like to sign.

First, you must base64 encode the string, which becomes:

SGVyZSBpcyBzb21lIHRleHQgdGhhdCBJIHdvdWxkIGxpa2UgdG8gc2lnbi4=

Then you would post to the endpoint with the base64-encoded string in the body. For example, if your project was called my-project and you wanted to sign the blob with my App Engine default service account, you would do:

POST: https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/my-project@appspot.gserviceaccount.com:signBlob?key={YOUR_API_KEY}

BODY:

{
 "bytesToSign": "SGVyZSBpcyBzb21lIHRleHQgdGhhdCBJIHdvdWxkIGxpa2UgdG8gc2lnbi4="
}

If successful, it will return a response with the keyId that was used to sign the blob and the signature which is the signed blob.

Example:

{
 "keyId": "f123aa7016e4565e49a489357aa384fa25a9e789",
 "signature": "t7FT+3b0AUzqmGHofHIa8MDcfuBOKQa4/DtK6Ovel22Y9pa5G4PduW5iYY9EMQpyXW3sZEZiyFRs3M9nGkLt/DKXITCW9Ta4nvLZwNj1ahFjkujr12iUzyU+NR9/Db2LWoI/g4j1e27E9O8zqXdi+BQpKkOYHUcfbH3xcTbEJnmjU/1zEHztNRXlihNPyOjSWsKhPdVnVzxYmi6Y3Bmgb3kCZe5hhUhANo9gavsakSogi0y5z625vHiW3roQkH2fEktcDkf49GlLJEHqRu+FaCcAwgpsEs/Nm+llgfhSuHKx1tcvslmTWOGAnYDKVg74oqg4FgfhiLqBWJYRrFRwxQ=="
}

You can try it here with the API Explorer (but change the project name to your project and change the service account name to your service account).

This can also be done with gcloud, for example:

$ gcloud iam service-accounts sign-blob \
      --iam-account my-account@somedomain.com input.bin output.bin

For more information on how this command ties into the wider cloud infrastructure, please see:

You might use this to to assert your identity to non-Google services. If you want to assert that some text provided by you to an external application is in fact coming from you, then you can sign the text with the signBlob method to sign the text with your private key, and then you can use the get_public_certificates() method to obtain a list of certificates which can be used to validate that the signature.

More: Asserting identity to third-party services

lukwam
  • 574
  • 4
  • 17
  • 1
    Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/183810/discussion-on-answer-by-lukwam-what-is-bytestosign-in-google-cloud-security-pr). – Samuel Liew Nov 17 '18 at 06:15
0

Thanks to @lukwam and @John Hanley, the answer was that I didn't need to use projects.serviceAccounts.signBlob, i.e., this was a rabbit hole I didn't need to go down. I was getting a SigningError message and I needed to assign roles to service accounts, as I have detailed in this question and answer.

Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100