Set Firebase Functions Security Level From Command Line - firebase

I'm deploying a firebase HTTP function using the command line and would like to change the security-level to 'secure-always' like you can do in the gcloud deploy command:
gcloud functions deploy FUNCTION_NAME --trigger-http --security-level=secure-always
I cannot use the UI to deploy this function (I do not store my source code on source repos), and am in a Firebase functions directory so I cannot use gcloud to deploy. Is there a gcloud command I can use to edit the function's security-level after deployment similar to:
gcloud functions remove-iam-policy-binding
or a way to specify the security-level pre-deployment? For reference I am deploying a NodeJS Cloud Function and using firebase deploy --only functions:FUNCTION_NAME. My current fallback option is manually examining the headers in the function, as it is the only option described in this docs page available in my situation: https://cloud.google.com/functions/docs/writing/http#security_levels

So far, there's no gcloud command to update the Cloud Function's security level from HTTP to HTTPS. For now, you can only update the Cloud Function's security level by re-deploying the function or edit the function through Google Cloud Function Console:
Click the prefer Function
Click Edit button
At the bottom of Trigger title, click the edit button
Check or tick the check box of Require HTTPS and click Save button
Click the Next button at the bottom of screen and deploy.

Related

If I already have Cloud Functions Admin role, why do I need Cloud Functions Invoker role to run cloud functions?

I have been assigned Cloud Functions Admin role in the IAM permissions settings. I have created a cloud function callable by HTTP. When I make the request it throws
Error: Forbidden
Your client does not have permission to get URL /<function name> from this server.
Apparently I have to add the Cloud Functions Invoker role to be able to call cloud functions, but this seems unnecessary since I'm already a Cloud Functions Admin, whose permissions surely encompass any held within Cloud Functions Invoker.
Is this strange behavior correct or have I taken a wrong turn?
I have now added Owner role aswell as Cloud Functions Admin and it still throws the same 403.
I have updated my CLI using npm install -g firebase-tools - now on v11.8.0.
I have added allUsers principal to have Cloud Functions Invoker.
I have checked any errors logged in the console and gcf-artifacts has failed as the Artifact Registry API is not active. Please enable the API and try again. - however when I check if the Artifact Registry API is enabled, it is.
I am now attempting to enable unauthenticated HTTP function invocation using this article however I can't find the Configuration panel within the google cloud console.
If you are experiencing the same issue and have already completed all of my troubleshooting above, delete your cloud function and redeploy it.
It's that simple.

What causes typescript compile error when deploying

I roughly following this tutorial to make a cloud function with typescript. It works fine in development, but when I try to deploy it (firebase deploy --only functions), I get A LOT of typescript errors. I have no idea why. It works in dev, why can't I push the same set up to Firebase?
Follow the below steps for a successful cloud functions deployment:
After you have created a Firebase project using this step, install
the Firebase CLI using : npm install -g firebase-tools.
Run firebase login to log in via the browser and authenticate the
firebase tool.
Run firebase init firestore
Run firebase init functions
When you run firebase init functions, there will be prompts, 1st
prompt : “What language would you like to use to write Cloud
Functions?” -> Choose Typescript. 2nd prompt : Do you want to use
ESlint to catch probable bugs and enforce style (y/n)? -> Choose n.
By selecting no you will be saving yourself from the typescript
compile errors.
Once initialization is complete, uncomment the sample in index.ts and
run npm run serve to see a "Hello World" function in action. Once you
can see the output in Firebase emulator, you will know the functions
executed properly.
Now, before you deploy the functions, assign the Cloud Functions
Invoker, Cloud Functions Admin and Cloud Functions Developer role to
project-id#appspot.gserviceaccount.com
Now run firebase deploy –only functions. The deployment will be
successful but the browser might show 403 errors ( Client does not
have permission..) For that, select your cloud function (check box)
click "Add members" under the Permissions tab in the right side,
enter "allUsers" under "New members", select Role as Cloud Functions -> Cloud Functions Invoker and then save the configuration.
If you do not want to give public access to your cloud functions, you
can set up authentication, by skipping the previous step. In Cloud
Shell, run gcloud auth print-identity-token. This outputs a token
which you will be authenticating your cloud function with. Now
provide authentication credentials in your request as a
Google-generated ID token stored in an Authorization header with this
command :
curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME \ -H "Authorization: bearer $(gcloud auth print-identity-token)"

How to avoid "401 Unauthorized" when invoking Firebase callable HTTP Function under GCP organization?

I have a Firebase project under a GCP organization. I have NodeJS 10 callable functions which work fine with Firebase local emulator and in in GCP functions test page, but when attempting to call them in production using httpsCallable in a webapp, I get 401 Unauthorized - Your client does not have permission to the requested URL
There is practically nothing my test function - it just returns a hardcoded string. There is nothing in the logs after the call attempts.
The function call attempt is done after passing Firebase authentication in the webapp, and in development I see that the user is indeed passed to the context parameter.
I use Firebase Tools 8.0.2 to deploy.
In GCP console function details I see "Ingress settings - Allow all traffic", and as I wrote above, it runs successfully from the test tab there.
I tried to make the function public but I can't set permissions in the console or gcloud. When I try to run the following command with gcloud:
gcloud functions add-iam-policy-binding my-function-name \
--member="allUsers" \
--role="roles/cloudfunctions.invoker"
I get:
ERROR: (gcloud.functions.add-iam-policy-binding) ResponseError: status=[403], code=[Forbidden], message=[Permission 'cloudfunctions.functions.setIamPolicy' denied on resource 'projects/my-project-name/locations/us-central1/functions/my-function-name' (or resource may not exist).]
even though my account has the following roles: Project Owner, Cloud Functions Admin, Security Admin, IAP Policy Admin, Organization Administrator
Any guidance will be appreciated.
Per John's instructions, it turned out gcloud was set to an incorrect active account, so I set it to the correct account that had the required permissions using gcloud config set account my-email#my-domain.com and then I was able to make the function publicly invokable using
gcloud functions add-iam-policy-binding my-function-name \
--member="allUsers" \
--role="roles/cloudfunctions.invoker"

Delete all firebase functions

I have a firebase project with multiple functions deployed. Is it possible to remove all the functions in a single go through the CLI?
I tried the command firebase functions:delete --region us-central1
and the error output was Error: Must supply at least function or group name.
As of right now, I deleted all of them specifying each of their names as such:
firebase functions:delete function1 function2 ...functionN but this is very cumbersome.
The version of firebase-tools installed is v4.0.0
Sign in to your Google Cloud Console at https://console.cloud.google.com, select your project, then from the list on the left pick Cloud Functions. When you get the list of functions, click the check box on the header line to select all, then the Delete button in the tool bar.
Update for comment:
I don't know what the product strategy for Firebase Console is with regard to Cloud Functions. My guess is that it is intended to provide a simplified, more convenient interface for managing Firebase related cloud functions. The Google Cloud Console provides a richer set of capabilities for managing functions and viewing logs. You could submit a feature request to Firebase to get those capabilities added to the Firebase console. Some details on the Firebase/Google Cloud relationship are provided at these links:
https://stackoverflow.com/a/42859932/4815718
https://cloud.google.com/functions/docs/concepts/functions-and-firebase
Just comment (or delete) all the functions in your index.js file and redeploy it through the CLI.
Adding other deletion options. For more information, checkout Firebase official documentation.
Now you can simply delete a function from the function dashboard as follows. Click on the three dots mark of relevant function in the right side corner.

Firebase cloud function "Your client does not have permission to get URL /200 from this server"

I just made a firebase cloud function :
exports.deleteAfterSevenDays = functions.https.onRequest((req, res) => {...
I deployed the function and got a function URL. When I request this url from my browser I get the following message :
"Error: Forbidden Your client does not have permission to get URL /200
from this server."
I have just updated to firebase Blaze plan because I thought there were limitations with Spark plan, but it still doesn't work.
In my firebase cloud function logs it is written "Function execution took 572 ms, finished with status code: 302".
My cron job "has been disabled automatically because of too many failed executions".
Do you see what's wrong?
Cloud function should have a role with member called "All users" to invoke this function from anywhere/anyone irrespective of an authorization.
Without Authorization:
Go to the cloud function tab
Select your cloud function (check box)
Click "Add members" under Permissions tab in the right side
Enter "allUsers" under "New memebers"
Select Role as "Cloud Functions -> Cloud Functions Invoker"
Save
Test your cloud function by just pasting it in the browser
With Authorization:
It's always a good practice to set authorization on your cloud functions
Note: Cloud functions throwing error with "403 Forbidden - Your client does not have permission to get URL" should be called by authorized users.
Simple test:
Click on Cloud shell(icon) terminal in the top
type - gcloud auth print-identity-token
copy the generated token
forming Authorization key to be passed while calling cloud function
4.1 Authorization: bearer generated_token
Use above Authorization key while calling your cloud function
Note:
Never make a cloud function available to allUsers
From Cloud Function docs:
Caution: New HTTP and HTTP callable functions deployed with any
Firebase CLI lower than version 7.7.0 are private by default and throw
HTTP 403 errors when invoked. Either explicitly make these functions
public, or update your Firebase CLI before you deploy any new
functions.
In my case the CLI version was out of date. If you currently get the 403 error, try this:
Delete your Cloud Functions
Update Firebase CLI npm install -g firebase-tools
Re-deploy your functions
To be clear:
Go to your function (make sure your project is selected):
https://console.cloud.google.com/functions/details/us-central1/ssr
Click Permissions Tab
Click Add Permissions
New Principals: allUsers
Role: Cloud Functions Invoker
Done.
J
Changing the IAM role(Cloud Functions Invoker) for targeted cloud function to allUsers should solve this issue. https://console.cloud.google.com/functions
If you face this in 2020 it might also be due to a different access behaviour:
Note: As of January 15, 2020, HTTP functions require authentication by
default. You can specify whether a function allows unauthenticated
invocation at or after deployment.
https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation
Here are the steps
Go the Google Cloud Console(Not Firebase Console) -> Search For Cloud Functions to see the list of functions
Click the checkbox next to the function to which you want to grant
access.
Click Permissions at the top of the screen. The Permissions panel
opens.
Click Add principal.
In the New principals field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the
Select a role drop-down menu.
Click Save.
Enable access from Postman project:
Open https://console.cloud.google.com/functions
Open cloud shell (right top terminal icon)
Write: gcloud auth print-identity-token
Copy your token and open your Posman
Right click on your collection -> Edit
Authorization -> Choose type OAuth 2.0
Paste your token in the Access Token
Note: You can do the same for a single request or folder.
This might be far fetched but if you have interrupted a cloud function deployment, then redeployed the function (which lead to an error), and after that you redeployed the function successfully this could have caused the issue.
I am trying to reproduce, but simple deleting the function in the firebase console and redeploying worked for me.
it happens to me after i upgraded all NPM packages and then deployed...
i delete all the functions from the cloude and re-deplyed them. it solve me this error immediately. without change permisions or any other cahnge
I know this doesn't make sense, or not a real solution but I solved it by making my account an Owner of the Firebase project. It was working nice while I was Editor but stopped working suddenly and setting my account as Owner solved it for now.
I guess it has to do with certain account having proper access to the Service Account which is the actual interface with Firebase Functions and Google Cloud API.
In my case, I made error in Postman
when I typed Body of Request, I didn't switched format from Text to JSON.
Check that part.

Resources