nodejs-storage: "Cannot sign data without `client_email`" for getSignedUrl
I’m trying to get a signed url from a storage bucket, but am getting a signing error. I have permission to read from the bucket, and have been able to stream its contents fine.
Code:
...
const expires = new Date()
expires.setSeconds(expires.getSeconds() + 30)
const storage = new Storage({ projectId });
storage
.bucket(bucketName)
.file(`${directory}/${packageName}`)
.getSignedUrl({
expires,
action: 'read',
})
.then(url => {
res.send(url)
console.log(url)
})
.catch(console.log)
Error:
{ SigningError: Cannot sign data without `client_email`.
at /Users/pikelnys/Desktop/code/gcs-project/api/node_modules/@google-cloud/storage/src/file.js:1784:16
at Auth._signWithApi (/Users/pikelnys/Desktop/code/gcs-project/api/node_modules/google-auto-auth/index.js:331:7)
at getCredentials (/Users/pikelnys/Desktop/code/gcs-project/api/node_modules/google-auto-auth/index.js:316:14)
at googleAuthClient.getCredentials (/Users/pikelnys/Desktop/code/gcs-project/api/node_modules/google-auto-auth/index.js:194:9)
at /Users/pikelnys/Desktop/code/gcs-project/api/node_modules/google-auth-library/build/src/auth/googleauth.js:602:67
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7) message: 'Cannot sign data without `client_email`.' }
Environment details
- OS: macOS 10.13.4
- Node.js version: 8.11.2
- npm version: 6.4.1
@google-cloud/storage
version: 1.7.0
Edit: I’m getting this in both a local environment (where I authenticate with gcloud auth application-default login
) and while the code is deployed to cloud functions.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 12
- Comments: 24 (7 by maintainers)
Is this possible to authenticate without a keyfile?
Service account isn’t good for multi-stage environments and security. This should be reopened. You should be using the exposed environment that has the same values.
Hi @pikelnys.
You will have to specify keyFilename while creating the Storage object if you are deploying locally.
keyFilename is not required if you have deployed your code under the same project your Google Cloud Bucket was created. You just have to ensure you have the right access by having a look at your service-account-key.
This is well explained here
The error says cannot sign without client_email. client_email is available inside the service-account-key.json but was not provided while creating the object hence the error. This error would not have arrived had you deployed your code inside the same project as your Cloud Bucket was.
Here is a sample service-account-key.json file. Look for client_email in the file.
Steps to Follow.
Download the service account key in JSON format and specify its path inside keyFilename. Default service-account-key provided by Google has read-only access. So make sure if you want to write to your bucket you would have to change the permissions inside the service-account.
Here is the Google Codelab link for reference
Hope this resolves your issue.
For anyone else that comes across this issue, here is a bit more info for posterity.
The GCP client libraries docs use the Storage libary as the example when leveraging ADC locally. The same docs also call out the fact that using service accounts locally is bad practice (see the Note in this section).
However, for some reason Google seems to contradict itself with the implementation of the
getSignedUrl
method and its corresponding endpoint. After a couple hours of debugging and re-reading the disparate and disconnected docs scattered all over the place, I found the source of the issue as documented here. V4 (and the legacy V2) signing requires usage of a service account.It would be nice if Google would have bothered to call this out in the ADC docs where they use Storage as an example, or better yet, return the relevant instructions in the SigningError message, especially because they seemingly contradict themselves within the different docs on related topics.
Hope this helps someone!
I was getting “Cannot sign data without
client_email
” error when runningfirebase emulators:start
.I fixed it by setting up a service account and downloading the service account .json credentials file as
service_account.json
, then runningGOOGLE_APPLICATION_CREDENTIALS="service_account.json" firebase emulators:start
BUMP as there isn’t seem to be a way to deal with it via
emulator
without exposingdev
/prod
configs.Got the issue and solved it thanks to this solution firebase-adminsdk-ov3eh@staging-louve.iam.gserviceaccount.com thanks @christiangenco
Bump. Firebase emulator should emulate the environment, this appears to be a failure state
I recently wrote a Medium article describing a workaround I created for local development. There is also a git repo with my solution. Article | Repo I use IAM Credentials API coupled with a cloud function. Hope this helps someone.
Thanks @tritone, appreciate the response!
Hey @timbuckiii and @ollyde , just wanted to note a couple things:
Also, in the future, if you could open a new issue for any problems rather than commenting on a closed one, that would help us respond faster. Thanks!