firebase / firebase-admin-node

Firebase Admin Node.js SDK
https://firebase.google.com/docs/admin/setup
Apache License 2.0
1.6k stars 358 forks source link

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

Open thomasmburke opened 2 years ago

thomasmburke commented 2 years ago

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:

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"

google-oss-bot commented 2 years ago

I found a few problems with this issue:

hiranya911 commented 2 years ago

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 commented 2 years ago

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.
ghost commented 2 years ago

lol

andrewmclagan commented 1 year ago

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

Burekasim commented 1 year ago

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 :/

lhermann commented 1 year ago

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.

erik-induro commented 1 year ago

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?

lahirumaramba commented 1 year ago

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!

Mistic92 commented 1 year ago

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

enchorb commented 1 year ago

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

jordanebelanger commented 1 year ago

+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.

gkawin commented 1 year ago

Ok, I will stay tuned on this issue.

erlichmen commented 1 year ago

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.

dylanenabled commented 1 year ago

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

lox commented 10 months ago

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).

k2wanko commented 9 months ago

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

theunlitshadow commented 8 months ago

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

lox commented 8 months ago

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

lahirumaramba commented 8 months ago

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

josekasna commented 8 months ago

We are also facing the same issue

breathe commented 8 months ago

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 ...)

lox commented 7 months ago

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

rapuckett commented 6 months ago

Any... progress?

mitchkoby commented 5 months ago

Also awaiting an update on this.

hdpz commented 4 months ago

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

BenJackGill commented 4 months ago

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.

Burekasim commented 4 months ago

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.

lebenitza commented 4 months ago

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.

lahirumaramba commented 4 months ago

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.

jars commented 3 months ago

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

It works for me, thanks for the patch and look forward to the release. :tada:

andrewmbenton commented 3 months ago

Hoping to see this resolved soon. Is there anything blocking merge and release for https://github.com/firebase/firebase-admin-node/pull/2466?

balloman commented 2 months ago

Is there anything blocking #2466 , it hasn't had any activity for almost two months now?

mitchkoby commented 2 months ago

Also hoping for the release soon. Please provide an update.

7Hazard commented 1 month ago

Why is this still an issue? This should be highly prioritized. Currently blocking us from deploying to Google Cloud through GitHub Actions.

nguyen-vo commented 1 month ago

Do we have an ETA on this issue? I see there are open MRs that were approved but they are also outdated