google cloud storage node client - credentials not working as expected

Viewed 738

I'm working on a project where I need to access some objects in a gcloud bucket

It work fine with the GOOGLE_APPLICATION_CREDENTIALS env variable, but not when I try using the keyfilename option of the Storage constructor. Here is a minimal example that shows what is going on:

const {Storage, File} = require('@google-cloud/storage');
const path = require("path");

// Fake bucket and file names
const bucketname = "my-bucket";
const filename = "test-file.txt";
// Points to a valid key file for a service account with read & write access to the bucket
const keyPath = path.resolve("./key.json");

const storage = new Storage({keyFile: keyPath}); // note that I'm providing a keyFile here
const bucket = storage.bucket(bucketname);
const file = new File(bucket, filename);

async function main() {
  console.log("try without GOOGLE_APPLICATION_CREDENTIALS");
  try {
    await file.download({ destination: "./test.txt" });
    console.log("ok");
    return;
  } catch (e) {
    console.log(e.message);
  }

  console.log("try with GOOGLE_APPLICATION_CREDENTIALS");
  try {
    process.env["GOOGLE_APPLICATION_CREDENTIALS"] = keyPath;
    await file.download({ destination: "./test.txt" });
    console.log("ok");
    return;
  } catch (e) {
    console.log("failed with GOOGLE_APPLICATION_CREDENTIALS");
    console.log(e.message);
  }
}
main();

I would expect the output for this to be:

try without GOOGLE_APPLICATION_CREDENTIALS
ok

but instead I get

try without GOOGLE_APPLICATION_CREDENTIALS
Anonymous caller does not have storage.objects.get access to my-bucket/test-file.txt.
try with GOOGLE_APPLICATION_CREDENTIALS
ok

What is going on here ?

1 Answers

Well, this is dumb but it might help somebody:

the Storage constructor options object has both a KeyFile and a keyFilename option, with the exact same description. (to be precise, StorageOptions inherits those from GoogleAuthOptions)

The documentation only talks about the keyFilename option, but my editor was also showing me KeyFile as an autocomplete option, and I used it without thinking too much about it.

keyFilename is the one you want to use, not keyFile (what is this one for ? No idea)

In short:

new Storage({keyFilename: "/path/to/key.json"}); // this works
new Storage({keyFile: "/path/to/key.json"}); // this doesn't
Related