I'm writing some Firebase Cloud Functions but I have need to hide a private key, including from Firebase project admins.
If I embedded this key into my source code and uploaded the code myself, would it be possible for anyone to retrieve the source code and thus the key? Either via Firebase or Google?
Many thanks
The code for your Cloud Functions is never accessible to users of your app.
It is however accessible for the collaborators on your Firebase project. See Get code from firebase console which I deployed earlier
I don't think there's any way to hide such configuration values from collaborators. Since they can see/deploy code, and the code needs access to this private key, they by definition have access to the key too.
Answering precisely to your question: Yes, they can.
The step by step to achieve that is relatively simple
Go into the GCP Functions page
Select the function you want to inspect
Click on source (From there you should be able to see all the files and the code used by that function), or;
Click on variables (From there you should see all environment variables used by your function)
If people being able to see env variables is problematic to you, here's a way to make things more secure:
You can build on what you already and start encrypting those keys before adding them to the codebase or the environment variables. After that, you can use an encryption service such as KMS to decrypt those keys at runtime. In KMS itself you can have a stricter policy in there, only allowing yourself and the function to access that service.
Another great service from GCP is Google's Secret Manager
Maybe setting an environmental variable:
Oficial Doc
Related
As the title states, I've gotten this email for both projects I've made public on Github. One is a landing page for a local business and the other is a CRUD app I have on the App Store; both of which are using Firebase as the backend.
Is the API key being visible on Github such a security risk?
I've done some research after following the instructions in the email to restrict my API and have heard that you cannot make web service requests with a restricted API key.
I just want to show my repos for the projects for the application process and obviously don't want anything bad to happen with them by doing so.
Aren't Firebase APIs meant to be public?
If so, is it just my database rules that need to be stronger/more verbose?
If any more context is needed, please let me know!
Cheers!
NOTE: I'm still very new to programming so a lot of this is over my head
For Firebase apiKey in a web app you are intended to make this key public, so you should ignore this email -- see: https://stackoverflow.com/a/37484053/771768
Hopefully Best practices for securely using API keys helps.
I'm uncertain as to what you're doing specifically that's resulting in the email but it is warranted.
Please be very careful with API keys.
As the name suggests, these are like keys in that they unlock access to stuff. With digital keys, the additional challenge is that, once obtained, infinite copies of the key may be distributed (and these are usable until the API key is revoked).
There are (often) other (complementary|alternative) ways to authenticate APIs but, as I think you've discovered, sometimes you are required to use API keys.
In the case where they're required, you should endeavor to use complementary authentication mechanisms too in order to try to mitigate overuse and you should continue to be very judicious in your publication of these keys.
I suspect you should not be including (any) keys (ever) in your GitHub repos.
One rule of thumb is that vendors (like Google) use API keys as a way to limit access to (often paid) resources. If the vendor is giving you a key, they're often (not always) using the key as a way to determine how to charge you for an API too. If you're giving the key to others, you're giving other people the possibility of potentially incurring charges on your behalf.
I don't wish to scare you but I would like you to leave this question being very cautious when using keys even if only this causes you to read up more on the consequences of using them.
When I use googlesheets4 in R, I use sheets_auth() in the console and it works fine. But when I try to run it in R markdown, and when I try to knit, I cannot seem to get the credentials. Can someone walk me through the process? I've gone to the vignettes for googlesheets4 but cannot seem to understand it.
This is working for me
gs4_auth(path = "xxxxxxxxxxxxxxxx.json")
It doesn't return anything, but after that I'm able to write data in my sheet with sheet_write()
To get the credentials in a json file you have to follow these steps:
From the Developers Console, in the target GCP Project, go to IAM & Admin > Service accounts.
Give it a decent name and description.
For example, the service account used to create the googledrive docs has name “googledrive-docs” and description “Used when generating
googledrive documentation”.
Service account permissions. Whether you need to do anything here depends on the API(s) you are targetting. You can also modify roles
later and iteratively sort this out.
For example, the service account used to create the googledrive docs does not have any explicit roles.
The service account used to test bigrquery has roles BigQuery Admin and Storage Admin.
Grant users access to this service account? So far, I have not done this, so feel free to do nothing here. Or if you know this is useful
to you, then by all means do so.
Do Create key and download as JSON. This file is what we mean when we talk about a “service account token” in the documentation of gargle
and packages that use gargle. gargle::credentials_service_account()
expects the path to this file.
Appreciate that this JSON file holds sensitive information. Treat it like a username & password combo! This file holds credentials that
potentially have a lot of power and that don’t expire.
Consider storing this file in such a way that it will be automatically discovered by the Application Default Credentials search
strategy. See credentials_app_default() for details.
You will notice the downloaded JSON file has an awful name, so sometimes I create a symlink that uses the service account’s name, to
make it easier to tell what this file is.
Remember to grant this service account the necessary permissions on any resources you plan to access, e.g., read or write permission on a
specific Google Sheet. The service account has no formal relationship
to you as a Google user and won’t automatically inherit permissions.
(copied from here https://gargle.r-lib.org/articles/get-api-credentials.html#service-account-token)
At first, I thought the advantage was being able to call HttpsCallables, but now I know that you can call these with some special format and parameters from Postman (and it is also possible using UnityWebRequest, and if not, could just change them from onCall to onRequest).
Then, I thought that it might include some special authorization info from the client to the server. But context.auth (from https.onCall(data, context)) appears to be undefined. Plus, I can still call the functions from Postman.
Important note: I am not registering users, so I don't need Firebase Auth specifically. But I imagined Firebase added something to verify that the function call was coming from an authorized client (e.g. the app).
I am still using the Functions SDK, but I am wondering, what are the advantages of using this SDK for Unity, when UnityWebRequest exists? Why should I have an package when I can perform the same call using a UnityWebRequest? Am I missing something too obvious?
Additional information of how I am using Firebase Functions:
I have a level editor where people can contribute with levels. I use a function to add these levels to Firestore.
When these levels are created, a database trigger runs and checks if that level was already created.
Getting levels from the database to replay.
Finally, in the future I plan to create a voting system to help me curate the levels.
Auth state should be passed along from the Firebase Functions client to your callable Cloud Functions automatically. If that is not the case, I'd report that as a bug.
But outside of that: there's indeed nothing the SDK does that you can't also do yourself. Using it is a matter of choosing between greater convenience and more fine grained control.
If you use the Firebase-provided SDK, you won't have to build anything yourself. But on the other hand, if you build your own client-side implementation of the wire protocols, you have full control over what you do, and don't, implement.
Let's say I'm developing app like Instagram: for iOS, Android and Web. I decided to use Google Firebase as it really seems to simplify the work.
The features user needs in the app are:
Authorization/Registration
Uploading photos
Searching for other people, following them and see their photos
I come from traditional "own-backend" development where I do need to setup a server, create database and finally write the API to let the frontend retrieve the data from the server. That's the reason why it's unclear to me how it all works in Firebase.
So the question is how can I create such app:
Should I create my own API with cloud functions? Or it's ok to work with the database directly from the client-side?
If I work with the database directly why do I need cloud functions? Should I use them?
Sorry for such silly questions, but it is really hard to get from scratch.
The main difference between Firebase and the traditional setup you describe is that with Firebase, as far as the app developer is concerned, the client has direct access to the database, without the need for an intermediate custom API layer. Firebase provides SDKs in various languages that you would typically use to fetch the data you need / commit data updates.
You also have admin SDKs that you can use server-side, but these are meant for you to run some custom business logic - such as analytics, caching in an external service, for exemple - not for you to implement a data fetching API layer.
This has 2 important consequences:
You must define security rules to control who is allowed to read/write at what paths in your database. These security rules are defined at the project level, and rely on the authenticated user (using Firebase Authentication). Typically, if you store the user profile at the path users/$userId, you would define a rule saying that this node can be written to only if the authenticated user has an id of $userId.
You must structure your data in a way that makes it easily readable - without the need for complex database operations such as JOINs that are not supported by Firebase (you do have some limited querying options tough).
These 2 points allow you to skip the 2 main roles of traditional APIs: validating access and fetching/formatting the data.
Cloud functions allow you to react to data changes. Let's say everytime a new user is created, you want to send him a Welcome email: you could define a cloud function sending this email everytime a new node is appended to the users path. They allow you to run the code you would typically run server-side when writes happen, so they can have a very broad range of use-cases: side-effects (such as sending an email), caching data in an external service, caching data within Firebase for easier reads, analytics, etc..
You don't really need a server, you can access the database directly from the client, as long as your users are authenticated and you have defined reasonable security rules on Firebase.
In your use case you could, for example, use cloud functions to create a thumbnail when someone uploads a photo (Firebase Cloud Functions has ImageMagick included for that), or to denormalize your data so your application is faster, or to generate logs. So, basically you can use them whenever you need to do some server side processing when something changes on your database or storage. But I find cloud functions hard to develop and debug, and there are alternatives such as creating a Node application that subscribes to real time changes in your data and processes it. The downside is that you need to host it outside Firebase.
My answer is definitely NOT complete or professional, but here are the reasons why I choose Cloud Functions
Performance
You mentioned that you're writing an instagram-like mobile device app, then I assume that people can comment on others' pictures, as well as view those comments. How would you like to download comments from database and display them on users' devices? I mean, there could be hundreds, maybe thousands of comments on 1 post, you'll need to paginate your results. Why not let the server do all the hard work, free up users' devices and wait for the results? This doesn't seem like a lot better, but let's face it, if your app is incredibly successful, you'll have millions of users, millions of comments that you need to deal with, server will do those hard jobs way better than a mobile phone.
Security
If your project is small, then it's true that you won't worry about performance, but what about security? If you do everything on client side, you're basically allowing every device to connect to your database, meaning that every device can read from/write into your database. Once a malicious user have found out your database url, all he has to do is to
firebase.database().ref(...).remove();
With 1 line of code, you'll lose all your data. Okay, if you say, then I'll just come up with some good security rules like the one below:
This means that for each post, only the owner of that post can make any changes to it or read from it, other people are forbidden to do anything. It's good, but not realistic. People are supposed to be able to comment on the post, that's modifying the post, this rule will not apply to the situation. But again, if you let everybody read/write, it's not safe again. Then, why not just make .read and .write false, like this:
It's 100% safe, because nobody can do anything about anything in your database. Then, you write an API to do all the operations to your database. API limits the operations that can be done to your database. And you have experience in writing APIs, I'm sure you can do something to make your API strong in terms of security, for example, if a user wants to delete a post that he created, in your deletePost API, you're supposed to authenticate the user first. This way, 'nobody' can cause any damage to your database.
I was wondering if it is possible to export firebase data (perhaps as a JSON object) in frequent "cycles". The main reason I'm asking this is because I would like to capture the data at specific points of time in order to perform a range of analytics upon them / identify specific patterns. I'm interested in any operations / methods that are part of the Firebase API - maybe some kind of web hook, or other workarounds that would enable me to do this!
Any suggestions would be greatly appreciated as I could not find anything on the web / docs (maybe I've over read it?).
Firebase has a full-featured REST API, so the simplest thing to do is just poll the REST API on a regular basis. REST API docs are here: https://www.firebase.com/docs/rest-api-quickstart.html
You can also get full access to your Firebase data using the Node.js client. This allows you to attach callbacks to your data and act on changes immediately when they occur from your own server: https://www.firebase.com/docs/nodejs-quickstart.html
Firebase now provides private backup option. For more information checkout private backup for Firebase data.
You can export firebase data in Json object, just make a curl request like below:
curl 'https://MyBase.firebaseio.com/MyPoint.json?auth=MyAuth&print=pretty'
in linux terminal and you get all your child structure