Cloud Firestore Offline Encryption - firebase

Does anyone know if the local cache of the Firebase Cloud Firestore is encrypted at rest on the clients? I want to temporarily store sensitive details (think payment details) in the datastore until network connectivity becomes available and I can fire off some cloud functions and dispose of the data. I could go about encrypting the data before it is stored, but then that necessitates the need to rotate keys etc.

The google group responded, and the answer is no. The store is not encrypted on the device. This facilitated the need for encryption prior to storing the data.
https://groups.google.com/forum/m/#!topic/google-cloud-firestore-discuss/fa4RygAeFJg

Related

Google Firebase Realtime Database Encryption

I see in the docs that Firebase Realtime Database is encrypted.
But there are some terms I don't fully understand:
Firebase services encrypt data in transit using HTTPS and logically isolate customer data. What does logically isolate customer data. mean?
"In addition, several Firebase services also encrypt their data at rest: Firebase Realtime Database Firebase Test Lab" Can somebody explain this in layman's terms?
Firebase stores user's data on the same physical server, but the data is isolated by a computer program (computer logic). It's not physically isolated from one another.
When your data is not "in use" it's encrypted. So when you data is being worked on by a service it has to be not encrypted.

Firebase/Firestore Encryption Level at rest

I'm looking for documentation that says the level of encryption is used at rest for firebase auth and firestore data:
Firebase Authentication
Firestore
This stackoverflow question points to a link that says it is encrypted, here: https://firebase.google.com/support/privacy#data_encryption
However, it does not specify the encryption level.
Is the data encrypted at AES 256? If not, what level of encryption is used?
Firestore is a part of Google Cloud products and all user content stored in Google Cloud is encrypted at rest without additional action required.
As shown in the diagram, data chunks in storage systems are protected by AES256 encryption with integrity.
The same applies on Firebase Auth as the service run on Google infrastructure though it is exclusive on US datacenters.
https://cloud.google.com/security/encryption-at-rest/default-encryption

End to end encryption with Firestore

Is there any recommended way to encrypt data in Firestore? Even though Firestore, by default, encrypts data before it writes to the disk, admins still can read data in the console. I am looking to make the data readable only by users who are allowed decrypt it. So it will be unreadable in the console.
One way I think it may be possible is to use cloud functions but I can't find how to modify the data before it gets saved to the disk (beforeWrite hook).
The only way to control all access to all data in Firestore (or Realtime Database for that matter) is to perform encryption on the raw data itself before it's even passed to the client APIs or SDKs that perform the write.
It's not possible to hook writes before they actually commit to storage with Cloud Functions. A function will only receive an event after the data is successfully written.
Also, bear in mind that if you encrypt data before it reaches the API, you will be unable to search and sort using that data, because it will no longer represent the original data in any way. All you would be able to do is access a document/location by its unique key (assuming that key is also not encrypted, or the encrypted id is (cryptographically) shared between both parties through another secure channel.
You'll need to encrypt data on the client devices before you write them into Firestore. When the other device reads up the data, decrypt it.
Key management is what you'll need to spend some time with to implement: Users on both devices need to have private keys locally and public keys accessible to the other users to encrypt messages with. Then you'll need to create a data encryption key to encrypt/decrypt messages in the chat room. This data encryption key, you'll encrypt with the participating users' public keys. And all keys, store in Firebase, encrypted.
Check out these 2 sample apps for a Firestore chat app example:
iOS: https://github.com/VirgilSecurity/demo-firebase-ios
Android: https://github.com/VirgilSecurity/demo-firebase-android
David

Is it necessary to encrypt chat messages before storing it into firebase?

As far as I know, Firebase sends data over an HTTPS connection, so that the data is already being encrypted. Although Firebase provides security rules to protect my data structure, I can still be able to see the string messages in the database.
I'm just curious whether it is a good idea to encrypt messages before pushing the data to Firebase or not.
Should I just move on from this topic to something else?
Thank you.
You seem to have a good grasp of how Firebase Database works: the data is encrypted in transit, and it is stored on encrypted disks on the servers. If you enable local persistence on the device, the on device data is not encrypted.
But administrators of the app can see the data in the Firebase console. If it is a requirement of your app that administrators can't read this data, then you'll need to encrypt it on the client before sending it to Firebase. A while ago a developer explained their end-to-end encrypted chat on the firebase-talk mailing list.
Hey Jeff: you're right that when you write some data into Firebase/Firestore, the data:
Is protected over the wire using HTTPS.
Then, when it lands on the Firebase REST frontend server, HTTPS terminates and the server has access to the full payload
Then the REST server routes the data to the backend/database, which also has access to the data.
When the data is written into disk, it's encrypted at-rest, but the at-rest encryption keys are also available to Google and your administrators will also see the Firestore contents
Encrypting data client side (End-to-End Encryption) prohibits all these participants/roles seeing your data.
Encrypting data on client side is fairly simple (compatibility across mobile platforms and browsers is tricky). The other tricky part is the key management to enable one user access to the decryption key without the other user sending the key over in an unsecure channel.
The way you can implement this is:
Create private & public keys for your users when you sign them up
Encrypt data on user1's device with user2's public key
Write the encrypted data into Firestore
When user2 reads up the encrypted data, her private key will be able to decrypt it.
Check out this Firebase E2EE chat sample on GitHub for iOS: https://github.com/VirgilSecurity/demo-firebase-ios and Android: https://github.com/VirgilSecurity/demo-firebase-android
HTH,
David

Firestore pricing clarifications for offline cached data

It seems odd to me that Firestore would charge me for read queries to locally cached data, but I can't find any clarification to the contrary in the Firestore Pricing document. If I force Firebase into offline mode and then perform reads on my locally cached data, am I still charged for each individual entity that I retrieve?
Second, offline users in my app write many small updates to a single entity. I want the changes to persist locally each time (in case they quit the app), but I only need eventually consistent saves to the cloud. When a user reconnects to the internet and Firestore flushes the local changes, will I be charged a single write request for the entity or one per update call that I made while offline?
Firestore could potentially fit my use case very well, but if offline reads and writes are charged at the same rate as online ones it would not be an affordable option.
As the offical documentation says,
Cloud Firestore supports offline data persistence. This feature caches a copy of the Cloud Firestore data that your app is actively using, so your app can access the data when the device is offline. You can write, read, listen to, and query the cached data. When the device comes back online, Cloud Firestore synchronizes any local changes made by your app to the data stored remotely in Cloud Firestore.
So, every client that is using a Firestore database and sets PersistenceEnabled to true, maintains it's own internal (local) version of the database. When data is inserted/updated, it is first written to this local version of the database. As a result, all writes to the database are added to a queue. This means that all the operations that where stored there will be commited on Firebase servers once you are back online. This also means that those operations will be seen as independent operations and not as a whole.
But remeber, don't use Firestore as an offline-only database. It is really designed as an online database that came work for short to intermediate periods of being disconnected. While offline it will keep queue of write operations. As this queue grows, local operations and app startup will slow down. Nothing major, but over time these may add up.
If Google Cloud Firestore priceing model does not fit your use case very well then use Firebase Realtime Database. As mentioned also in this post from the Firebase offical blog, one the reasons you still might want to use the Realtime Database is:
As we noted above, Cloud Firestore's pricing model means that applications that perform very large numbers of small reads and writes per second per client could be significantly more expensive than a similarly performing app in the Realtime Database.
So it's up to you which option you choose.
According to this If you want to work completely offline with Cloud Firestore you can disable network by :
FirebaseFirestore.getInstance().disableNetwork()
but firestore will cause client offline error for first user get request, that you must consider this error as empty response.

Resources