Firebase Cloud Functions setting environment configuration within a cloud function - firebase

I'm using cloud functions that call an external service that uses OAuth2 Security. Each invocation of my cloud function first, authenticates and gets an access token for the subsequent API call to the external service.
The access token expires in 30 mins, so to avoid token expiration, each invocation I get a new token.
I'd like to use the cloud function scheduler to get the access token and save it to the cloud function config, I can schedule this to happen every 25 mins. This would avoid each invocation requiring to first get an access token.
It does not look like the cloud function environment config allows programmatic updating of config within a cloud function.
https://firebase.google.com/docs/cli/#functions-commands
Anyone solved something similar?
UPDATE: As following further docs, the cloud function needs to be deployed again for the configuration update to occur. I think the solution to this question is likely a CI cronjob, that gets an access token, updates firebase cloud function configuration and redeploys the cloud functions.

I think that trying to update the configuration of the function, or redeploying the function altogether, isn't really the best idea here. You're probably better off just storing the information in a database or some other shared location, then each function can query that to get a hold of the token and its metadata as needed. The function can store the token in memory for as long as its known to be valid so that it doesn't have to be fetched for each invocation.

Related

Is it possible to only allow authenticated users to use callable function, without getting billed for invalid invocations?

I have a callable function that gets users auth data and validates it (inside the function), if user is not authenticated or allowed to do a certain action I throw respective error.
However nothing stops malicious actors to run a loop that constantly pings such function and rack up cost in terms of invocations / little bit of time those functions run.
Cloud providers like AWS have systems in place where this auth check is set up on an api gateway / loadbalancer level and users are not billed if someone calls functions with unexpected headers / payload or without authentication.
Does something like this exist for firebase, perhaps via google cloud?
No, it's not possible. The callable function must execute in order for the firebase-functions SDK to verify the user's ID token via the Firebase Admin SDK. It's not a "free" operation in any way. No matter how you write or deploy it, something is going to have to invoke the Firebase Admin SDK to verify the token - it's not part of any unbilled cloud infrastructure.

Firebase Callable Function, restrict invoke to APP [duplicate]

Firebase callable cloud functions can be accessed via client sdks, which requires a valid auth context for authentication and authorization. But and at the same time it is exposed as an HTTP endpoint, thus can be called but will receive an unauthorized response.
My questions is, is there a way to completely restrict public access for a callable cloud functions? since firebase will charge cloud functions based on function executions. Even to return an unauthorized response, the request has already gone through to the function, thus during a DDoS attack this could be problematic.
There is no built-in support for rejecting a request to a Cloud Function before it reaches your code. If you want such functionality consider setting up Cloud Endpoints in front of your Cloud Functions.
The best you can with just Cloud Functions do is check whether the caller is authorized as the first thing in your function code, so that you reduce the amount of time the function is active. You'll still be charged for the invocation in that case, but you'll minimize the GB-seconds and CPU-seconds.
I tried out as #Frank suggested using google cloud run to deploy and ESP container which can by used to invoke private cloud functions. A detailed overview is described in the documentations itself.
https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions#deploy_endpoints_proxy
Above given answer by #Frank van Puffelen is perfect but you can utilize a trik to restrict the access by securing that route. Here is the example,
const functions = require('firebase-functions');
exports.scheduleSampleJob = functions.https.onRequest((req , res) => {
let auth = req.header('Authorization');
if(auth == 'YOUR_API_AUTHORIZATION_KEY'){
// valid Authorization key, process the call
}else{
//send forbidden if Authorization key not valid
return res.status(403).send('Access is Forbidden');
}
});
Now, if you want to call the endpoint, It will require a Authorization header in request having value your secret key.
As firebase cloud function can also be used with firebase-auth, you can create custom logic to allow access to users having auth only and restrict the access for public excluding your app's authentic users.

How to securely pass time based credentials to google cloud functions?

I'm searching for an efficient way to store credentials inside google cloud functions that are only valid for 30 days.
My current approach is to set the username and password with firebase functions:config:set service.username="username" service.password="password" and sign the service in and write the response with credentials to the os.tmpdir()/creds.json.
The problem with this approach is that the os.tmpdir()/creds.json is deleted every x seconds (maybe due to cold starts). Is there a more efficient approach then just signing in the service every time or making a additional request to the cloud firestore to retrieve/store the credentials?
Cloud Functions server instances are short-lived, as you have observed. I wouldn't store anything in those instances, other than what you might use temporarily as an optimization.
Instead, you will need to use some persistent storage, such as a database or Cloud Storage. You don't have to make a request to it every time, just as often as a new server instance is allocated to handle load.

Firebase - Cloud Functions : Always running functions

I am new on firebase cloud functions. I would like to ask a question about always running or self-triggering functions. How can we handle these things? How can we implement always running functions or self-triggering?
Google Cloud Functions are snippets of code that run in response to events that happen somewhere else. Some example events:
a HTTPS URL is accessed, either from application code, or in some other way
a User account is created on Firebase Authentication
a node is written in the Firebase Realtime Database
a message is sent to a Cloud PubSub topic
There is no concept on a forever-running function on Cloud Functions (nor on other, similar Functions-as-a-Service offerings), although it's definitely possible to create a function that gets triggered every minute or so (like a cron job).

Cloud Functions: where to keep access token for API calls

I have created a Cloud Function which:
Receives some data
Calls a google API to verify the data are correct
Now, to call the google API I need to authenticate first. This will give me an access token (that expires) that can be used for subsequent calls.
I'm wondering where can I save this access token so that other invocations of the function can "see" it and use it. I know I cannot use a "global variable" as the function may run on different machines.
The obvious solution is to write it in Realtime Database... But I don't really like it, as someone could get access to it... Does Cloud Functions provide an object or something where I can write data into?
Cloud Functions are intended to be stateless, and there is no persistent storage it provides. Also, Cloud Functions could start up many server instances to handle your functions, so you will have to find a way to share data between those instances as they come and go.
Storing your token in the Realtime Database is probably your best option. As long as you're using security rules correctly, no one will be able to read it.

Resources