firebase-admin-node icon indicating copy to clipboard operation
firebase-admin-node copied to clipboard

[FR] Allow credential file type "external_account" when calling `admin.credential.applicationDefault()`

Open thomasmburke opened this issue 3 years ago • 42 comments

Is your feature request related to a problem? Please describe.

Developers would like the ability to initialize a Firebase app instance with a credential file type "external_account". An example of when credential file of type "external_account" is used is when following the instructions listed in the GCP public docs for using AWS Identify Federated Credentials. This credential file type is supported by other Google APIs (e.g. @google-cloud/storage, @google-cloud/firestore, etc...) and is also supported by the Firebase Admin SDK in other languages (e.g. Java)

Describe the solution you'd like

Allow the initialization of a Firebase app instance using credential file type "external_account". This will likely require an update to the credentialFromFile function

Describe alternatives you've considered

Developers are currently limited to:

  • Leveraging the Firebase Java Admin SDK instead
  • Using Secrets Manager/environment variables to store a service account key outside of code
  • Calling a corresponding RESTful endpoint from within node.js via something like http.request

Additional context

When a developer has configured GOOGLE_APPLICATION_CREDENTIALS to point to a credential file type of "external_account" (e.g. a AWS Identity Federation Credentials Config file) the below are the differences between the implementations for the Firebase Java Admin SDK and the Firebase Node.js Admin SDK:

Node.js Details: Developer initializes Firebase app instance with code similar to the below:

const fbApp = admin.initializeApp({
        credential: admin.credential.applicationDefault(),
        projectId: 'GCP_PROJECT_ID',
        databaseURL: 'https://GCP_PROJECT_ID.firebaseio.com'
    });

Which in turn calls the credentialFromFile function and returns the following error: 'Invalid contents in the credentials file'

Java Details: Developer initializes Firebase app instance with code similar to the below:

        GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();

        FirebaseOptions options = FirebaseOptions.builder()
                .setCredentials(credentials)
                .setProjectId(GCP_PROJECT_ID)
                .setDatabaseUrl(FIREBASE_DB_URL)
                .build();

        FirebaseApp app = FirebaseApp.initializeApp(options);

Which in turn calls this function that has support for credential file type of "external_account"

thomasmburke avatar Jul 15 '21 18:07 thomasmburke

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

google-oss-bot avatar Jul 15 '21 18:07 google-oss-bot

Thanks for reporting this. We can try to prioritize this for in the coming months. You can also help speed things up by sending a PR if you have the time.

hiranya911 avatar Jul 16 '21 20:07 hiranya911

Had a quick look at the external_account (federated authorization) support in GCP, and how libraries like https://github.com/googleapis/google-auth-library-nodejs have implemented it. Turns out it's actually quite a bit of code. Personally, I don't think we should duplicate this feature in the Admin Node.js SDK. Rather we should migrate all our credentials implementation to use google-auth-library-nodejs (we have already done similar migrations in other languages, which is why you can already use external_account support in Java Admin SDK).

I think doing this migration is going to be somewhat tricky. A rough plan would look something like:

  1. Support https_proxy environment variable for proxy settings.
  2. Update existing credentials to use google-auth-library-nodejs.
  3. Add a new admin.credential.externalAccount() API.
  4. Remove the token management logic currently in FirebaseApp.
  5. Tie RTDB code to the tokens events fired by google-auth-library-nodejs.

hiranya911 avatar Jul 29 '21 20:07 hiranya911

lol

ghost avatar Jan 04 '22 23:01 ghost

Any movement on this issue? Currently not possible to use https://github.com/google-github-actions/auth as this is blocking it

andrewmclagan avatar Nov 30 '22 10:11 andrewmclagan

I spend hours trying to figure out why it's not working until I encounter this issue, I am very disappointed that this is not even documented, there is a service (workload identity federation) that is supposed to be the best practice and it is not supported by other GCP services :/

I give up, it's impossible to deal with Google's libraries :/

Burekasim avatar Dec 14 '22 18:12 Burekasim

I had the same experience as @Burekasim. I am trying to follow best practice and then find out that the lack of support is not documented.

Thank you @thomasmburke for this excellent and detailed issue.

Please Google Team, treat this issue as a priority so Firebase can be used with Github Actions in the recommended way.

lhermann avatar Feb 16 '23 05:02 lhermann

This just ate a few hours of my life. The documentation is misleading when it says:

create_credentials_file: (Optional) If true, the action will securely generate a credentials file which can be used for authentication via gcloud and Google Cloud SDKs in other steps in the workflow. The default is true.

It should indicate that it doesn't work with the Firestore Node.js SDK.

Is there a work around?

erik-induro avatar Feb 28 '23 18:02 erik-induro

I understand your frustration. Firebase Admin Node.js SDK uses a custom credentials implementation and does not currently support many features that are already supported in google-auth-library-nodejs including external accounts.

Migrating to https://github.com/googleapis/google-auth-library-nodejs is not a simple task, but we have started the process. Stay tuned! In the meantime, we will see what we can do to improve the docs. Thank you for your patience!

lahirumaramba avatar Feb 28 '23 21:02 lahirumaramba

How Workload Identity Federation can be not supported by GCP product. What is the roadmap to enable use of WIF?

Mistic92 avatar Mar 13 '23 13:03 Mistic92

+1, how can an important feature like this be delayed/ not implemented for so long...

enchorb avatar Apr 30 '23 17:04 enchorb

+1 seems like I was an other one of the chosen one selected for losing a couple hours on this while setuping my ci/cd. I get that it's now mentioned in the docu for google github action auth, but when you are doing this process you often end up with 50 different tabs of documentation open at once making the note easy to miss.

jordanebelanger avatar Jun 12 '23 20:06 jordanebelanger

Ok, I will stay tuned on this issue.

gkawin avatar Jun 23 '23 19:06 gkawin

I urgently need to emphasize the severity of this particular issue. It presents itself when utilizing tools like Terraform, Pulumi, or when attempting to run local Firebase CLIs under application default credentials. Currently, the only feasible workaround is to employ a service account (SA) key.

This SA key has to be duplicated among the engineering team, and anyone who needs to operate one of the CLIs or any affected tool. Consequently, this poses a significant challenge for the CISO, necessitating the implementation of stringent processes - something that wouldn't be necessary if WIF was supported.

Furthermore, people are wasting innumerable hours attempting to decipher an issue that fundamentally stems from AdminSDK's neglect in using the most updated Google auth packages. There are numerous perplexing forum responses to odd errors like "missing quota project" or SERVICE_DISABLED (I mention these to potentially guide others in the right direction).

In spite of the complexity tied to integrating auth-library-nodejs, a span of two years ought to have been ample time. While I comprehend that @hiranya911 might no longer be a part of the team, this issue must be promptly assigned to a new lead.

erlichmen avatar Jul 03 '23 07:07 erlichmen

I wrote a script that works around this issue for our deployment pipeline by generating an expiring service account key (using the workload identity federation credentials) before it runs the node scripts. The key expires after a day, but the script also tries to delete it if everything goes right.

https://gist.github.com/dylanenabled/5fd0128afe362343cf2a8e9628c4218e

dylanenabled avatar Jul 04 '23 04:07 dylanenabled

Folks, any updates on this? This is also blocking the use of service impersonation (e.g. https://github.com/firebase/firebase-admin-node/issues/2169).

lox avatar Aug 31 '23 07:08 lox

This is an important topic for me. I would like to be provided with a solution that does not require this workaround.

k2wanko avatar Sep 17 '23 21:09 k2wanko

We are also awaiting an update on this issue. It's not apparent if this issue is being prioritized or even worked on.

theunlitshadow avatar Oct 10 '23 23:10 theunlitshadow

One could say that about almost all Firebase development work from what I can tell @theunlitshadow.

lox avatar Oct 10 '23 23:10 lox

Hey folks, thanks again for your patience! We are actively working on this feature! Stay tuned for updates.

lahirumaramba avatar Oct 12 '23 14:10 lahirumaramba

We are also facing the same issue

josekasna avatar Oct 24 '23 07:10 josekasna

Also ran into this issue ... Strugglefest!

In my case I'm deploying a nextjs firebase webapp which needs to use the firebase-admin sdk at build time within ci ... We only needed/wanted to use external account auth when running in ci so I ended up modifying one of the prior mentioned workarounds to get firebase-admin sdk auth to happen against external account only when in ci -- and otherwise follow a normal path ...

Workaround snippets for anyone else who comes into this pain ... https://gist.github.com/breathe/5b73c82f3ef3564b8b8f0641bf3e0a11

The error that tells you you need this workaround is that you get FirebaseAppError: Invalid contents in the credentials file when running the firebase deploy from a github action during the portion of the process that builds the nextjs cloud-functions/client-side bundles ...

Could be some dragons as should be aware of two levels of authz that exist here -- the identity to use to actually deploy the firebase project via the firebase cli -- and then the identity to use when running the nextjs build during that process ... (ideally you would have a way to communicate these two authz contexts to the firebase cli tooling directly ...)

breathe avatar Oct 26 '23 18:10 breathe

I have a more generic workaround that I am using for service account impersonation, should work for external_account without needing to import the internal credential classes (which is hard with ESModules).

https://gist.github.com/lox/8bff5607c3e713c92a03a631796ab3f3

lox avatar Nov 10 '23 00:11 lox

Any... progress?

rapuckett avatar Dec 23 '23 23:12 rapuckett

Also awaiting an update on this.

mitchkoby avatar Feb 06 '24 04:02 mitchkoby

Would be great to see some progress on this issue :pray:

hdpz avatar Feb 08 '24 15:02 hdpz

In case anyone is using Firebase resources in Terraform with Github Actions google-github-actions/auth then you will also get strange unknown authentication errors because of this bug.

You have to use the Service Account JSON method as described in the docs instead of the Workload Identity Federation methods and that will avoid the strange errors.

To be fair the docs do warn about this error when working with Firebase Admin SDK but I didn't realise that also means Terraform resources will fail, which I assume is because the Terraform resources are interacting with the Firebase Admin SDK.

BenJackGill avatar Feb 11 '24 07:02 BenJackGill

In another 20 or so years, in some documentary that will review why Google collapsed. They will present this GitHub Issue, to demonstrate Google's behavior towards paying users who just want to be treated.

In the meantime, they only have 10 more years left until this issue celebrates Bar Mitzvah.

Burekasim avatar Feb 11 '24 07:02 Burekasim

Hey folks, thanks again for your patience! We are actively working on this feature! Stay tuned for updates.

Can we get an update on this? Maybe a separate issues at least with required steps that this change might need so at least we have an idea where to start, if one would want to implement this themselves.

A good documented workaround would also be nice in the meantime.

lebenitza avatar Feb 19 '24 14:02 lebenitza

Hey folks, thank you again for your patience on this!

We have made progress on the credentials migration work and we have a custom build to share with you for testing purposes.

If you are interested in trying out the custom build and give us some feedback, please find the steps below!

Download the custom build from here (link updated)

You can use npm install to install the custom module

npm install path/to/firebase-admin-12.0.0.tgz

Or upload the custom build along with your test code and add the following in the package.json

  "dependencies": {
    "firebase-admin": "file:firebase-admin-12.0.0.tgz"
  }

NOTE: Use this custom build for testing purposes only! Do not use in production.

lahirumaramba avatar Feb 29 '24 17:02 lahirumaramba