4

I've given the service account for the functions the necessary permissions ('Secret Manager Secret Accessor') and when deployed, the firebase functions are able to access the secrets without any problems.

However, when using firebase serve or firebase emulators:start --only functions in local development, I'm getting the following error

Unhandled error Error: 7 PERMISSION_DENIED: Permission 'secretmanager.versions.access' denied for resource

I've found in the documentation that setting export GOOGLE_APPLICATION_CREDENTIALS=pathtoserviceaccount.json is needed to be entered in the terminal, though this did also not work for me.

I would be thankful for all pointers. Cheers.

seveneights
  • 425
  • 5
  • 15

4 Answers4

6

I had the same problem and tried the solution from pureth's answer to adding local overrides, but it didn't work. What did work for me was to create the .secret.local file in the functions directory, not in the project root.

My project structure is as follows:

/
|- .firebaserc
|- firebase.json
|- package.json
|- /* ... */
|- functions/
   |- .secret.local
   |- package.json
   |- /* ... */

So the .secret.local file needs to be placed in the directory where your functions reside and not where the .firebaserc file is.

Also, please note that the file name starts with a dot.

5

I've found the answer myself: When the functions are emulated locally, they do not get run by the App Engine default service account per default, this needs to be enabled as well. So I had to follow this tutorial https://firebase.google.com/docs/functions/local-shell

The App Engine default service account needs a key which can be created in the Service Accounts settings in the Google Cloud, and then I had to enter

export GOOGLE_APPLICATION_CREDENTIALS="path/to/key.json"

in the terminal. By running then firebase emulators:start they also got permission to access the Secret Manager.

So while I was on the right track, I was exporting the wrong Service Account key, and not the one that was allowed to run access the Secret Manager.

seveneights
  • 425
  • 5
  • 15
  • thanks fro the tip! I found similar instructions in the [functions emulator docs](https://firebase.google.com/docs/functions/local-emulator#set_up_admin_credentials_optional) – chantey Apr 29 '23 at 04:52
3

"[...] you can override secrets values by setting up a .secret.local file. This makes it easy for you to test your functions locally, especially if you don't have access to the secret value."

https://firebase.google.com/docs/functions/config-env#secrets_and_credentials_in_the_emulator

Step by step:

  1. make sure you have the latest version of firebase-tools installed, as this feature is relatively new.
  2. Create a file named secret.local in the root of your firebase project (along side the .firebaserc and firebase.json
  3. add your secrets to the file, formatted the same as way as a regular .env file. e.g.
MY_SECRET_1=foo
MY_SECRET_2=bar
  1. run the emulator firebase emulators:start
  2. within your firebase functions, access the secrets on the process object. e.g. process.env.MY_SECRET_1

note, as far as I can tell, the secrets are only available inside the block scope of a function handler. you can't access them in the root scope of your functions JS code (if somebody finds a way to do that, please comment here as I'd love to know too)

pureth
  • 680
  • 6
  • 9
2

In order to access Secret Manager from your Firebase application running with local emulator you need to add role of:

  • "Secret Manager Secret Accessor" to YOUR account used to authenticate with Firebase

You can verify it by running: firebase login in local CLI.

If you're already logged in, it should respond with Already logged in as [email address].

This email address is the Principal account you need to add the role to.

As you've mentioned in your question the "firebase-adminsdk" service account permissions are used on the production deployment, but not on local, unless you specify it with: export GOOGLE_APPLICATION_CREDENTIALS="path/to/key.json"

mal
  • 1,755
  • 13
  • 12