Why doesn't Firebase admin auth in node.js use ADC?

2,091 views
Skip to first unread message

Gary Oberbrunner

unread,
Feb 9, 2021, 1:45:45 PM2/9/21
to Firebase Google Group
[Hope this group is OK with a cross-posting from SO where I haven't gotten any responses -- it's my first time posting here]

Does anyone know why Firebase admin auth in node.js doesn't use ADC (Application Default Credentials)? I always have to set GOOGLE_APPLICATION_CREDENTIALS to a credentials file to get auth to work. Everything else (firestore, compute, storage etc.) works fine with ADC.

For instance, this code works only when GOOGLE_APPLICATION_CREDENTIALS is set to a valid credentials file, even though I'm logged into my Firebase project and my gcloud project:

import * as admin from 'firebase-admin'
admin.initializeApp()
async function listAllUsers(users: any[], matchRegex: RegExp, nextPageToken?: string) {
  // List batch of users, 1000 at a time.
  const listUsersResult = await admin.auth().listUsers(1000, nextPageToken)
    .catch(function (error) {
      console.log('Error listing users:', error);
    });
  }
}

If that env var is not set, I get this error:

Error listing users: FirebaseAuthError: Failed to determine project ID for Auth. Initialize the SDK with service account credentials or set project ID as an app option. Alternatively set the GOOGLE_CLOUD_PROJECT environment variable.

But setting GOOGLE_CLOUD_PROJECT is not enough either. When I do that, I get:

Error listing users: FirebaseAuthError: //cloud.google.com/docs/authentication/. Raw server response: "{"error":{"code":403,"message":"Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the identitytoolkit.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.","errors":[{"message":"Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the identitytoolkit.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.","domain":"usageLimits","reason":"accessNotConfigured","extendedHelp":"https://console.developers.google.com"}],"status":"PERMISSION_DENIED"}}" at FirebaseAuthError.FirebaseError [as constructor] (/c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/utils/error.js:43:28) at FirebaseAuthError.PrefixedFirebaseError [as constructor] ...

As I said though, all other Firebase admin features seem to work fine with ADC; they automatically pick up the current project and my logged in account. 

Is it just me or is admin.auth() not able to pick up the default credentials?

Sam Stern

unread,
Feb 9, 2021, 1:54:40 PM2/9/21
to Firebase Google Group
Hey Gary,

There's some previous discussion of this issue here:
https://github.com/firebase/firebase-tools/issues/1371

The basic problem is that there are two kinds of credentials, although it's not very well documented that this is the case:
  • End User Credentials (EUC) - application default credentials etc authenticate you as a user who owns the project.
  • Service Account Credentials - a non-human role on a project.
Not all APIs accept EUC, and in fact Google Cloud in the long term would like to move away from them completely as they are very hard to scope and use securely. Your EUC can access any project and act as you, there's no way to scope them down to a certain role or project.

So the Firebase Auth API does not accept EUC at all, and I don't think there are plans to change that.  That's why you're seeing the behavior you're seeing, where the API calls only work with GOOGLE_APPLICATION_CREDENTIALS.

- Sam

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/965fa5cd-dd5f-44bc-84b3-3c089cb2bdd7n%40googlegroups.com.

Gary Oberbrunner

unread,
Feb 9, 2021, 3:15:41 PM2/9/21
to Firebase Google Group
Thanks for the link, Sam. I posted a comment there about how annoying and possibly dangerous this is if that var gets out of sync with `gcloud config get-value project` as I switch between projects. I hope Google will reconsider that decision. (If `gcloud config get-value project` were only reasonably quick, I could run it in my shell's precmd hook and set the var there... but it's really slow. Anyone know how to get the google project ID quickly?)

Gary Oberbrunner

unread,
Feb 9, 2021, 3:15:51 PM2/9/21
to Firebase Google Group
One other thought/question: what about `gcloud config set auth/impersonate_service_account`? Could this work?

On Tuesday, February 9, 2021 at 1:54:40 PM UTC-5 sams...@google.com wrote:

Sam Stern

unread,
Feb 10, 2021, 5:53:11 AM2/10/21
to Firebase Google Group
Hey Gary,

Thanks for your thoughts. A few things:
  • Can you explain your use case to me a bit more? Why do you need to fetch the project ID? I've personally never used that command so I'm a bit surprised that it's a core part of your flow.
  • Yes I believe that impersonating a service account locally can achieve what you're looking for: the development experience of ADC combined with the access controls of SAC.
- Sam

Gary Oberbrunner

unread,
Feb 10, 2021, 1:12:10 PM2/10/21
to fireba...@googlegroups.com
Sure, Sam. As for the project ID, my app is a SaaS product based around Google tech (Firebase, GCE, etc.). I typically have three Google projects for the main product: dev, staging, and production. Each is a separate Google project (separate db, auth, storage buckets, etc.)
In addition to builds and deploys, I have quite a few command-line tools to administer things: generate coupon codes, extract user statistics, hydrate/update databases, etc. Each of those, naturally, has to work with the current project (dev, staging, production).
To switch projects, I have a simple script that does
gcloud config set project $fb_project
firebase use $fb_project
because for some unknown reason they don't automatically sync. Oh well.
All my CLI tools expect to use ADC to pick up the current project and credentials, and normally that works fine. If I'm logged into the staging project, my db hydrater updates the staging db, my user stats come from staging, my deploy goes to staging, and so on. But then I may switch to production, or back to dev. (I have my shell prompt set up to remind me which project I'm in!)
In many of my tools, for logging purposes and to avoid errors, I print the current project, using gcloud config get-value project (that's the only way to do it reliably, isn't it?)

The fly in the ointment is the failure of admin.auth to accept ADC. So any of my tools that use auth, like giving a particular user admin rights, or even counting total users over time, fails unless I set GOOGLE_APPLICATION_CREDENTIALS. in my shell. But it had better be in sync with the ADC credentials (same project) or I could end up talking to two different projects at the same time! An environment var is just a worse solution for me than switching projects (which is recorded in the filesystem). And I'm pretty sure I've run into some problems where having GOOGLE_APPLICATION_CREDENTIALS set has caused some things to fail -- probably because those credentials don't have enough permissions set. But if I open that up all the way, it's no different from just using my ADC credentials...

Is that helpful?

I tried using gcloud config set auth/impersonate_service_account to impersonate the account that I normally set with GOOGLE_APPLICATION_CREDENTIALS but I still got the same auth failures. So I'm not sure whether I just didn't do it right, or admin/auth just isn't listening to the gcloud config.

-- Gary

You received this message because you are subscribed to a topic in the Google Groups "Firebase Google Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/firebase-talk/fUB2m4UYG8s/unsubscribe.
To unsubscribe from this group and all its topics, send an email to firebase-tal...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/CAHafJBo7V7csPp6fTRBsYRJMB-a5v2pe13WvANuvN1PAFiRexA%40mail.gmail.com.


--
Gary Oberbrunner
Founder & CEO
LinkedIn      

Sam Stern

unread,
Feb 11, 2021, 6:41:14 AM2/11/21
to Firebase Google Group
Thanks Gary for explaining your workflow. I copy-pasted this whole thread and added it to the internal ticket tracking this feature request, I totally agree with your sentiments on this topic and I'll try and nag some people and see if they can raise the priority of this request.

- Sam

Reply all
Reply to author
Forward
0 new messages