Firebase Storage Project Level Permissions - firebase

I store files in Firebase Storage as follows:
/{projectId}/{file}
Users have different permissions based on the projectId, and can easily have some level of permissions on tens (or even hundreds) of projects. For each project, he or she is assigned a role, which determines what operations are permitted.
I have these roles stored in Firestore by the user, but they are inaccessible in the Firebase Storage security rules.
Furthermore, setting custom claims with all project roles for each user will easily exceed the 1000 byte limit for custom claims. Is there any way to lookup permissions at the time of file access, i.e., update, delete, read/download?

There is currently no way to access documents in Firestore from security rules defined for Storage. Custom claims is the only common permissions system shared between the two products.
Consider routing access through Cloud Functions if you need more a more flexible logic, either before or after the fact.
Please feel free to file a feature request with Firebase support.

Related

Firebase - organizing shareable data?

I am trying to implement sharing model like in Google Docs. That is:
"Documents" are private by default.
Some documents are accessible to everybody.
Some documents are shared with users.
Right now my database stores document metadata in the database in per-user collections (${userid}/docs/${docid}) and Firebase Storage is used to store assets under similar paths. I set up trivial security rules to manage that.
Now I am trying to figure out sharing:
Should I move all documents into a global docs collection and have security rules check ACLs that are in the docs metadata?
Should I try to replicate shared documents in each user collection? Seems brittle but cloud functions should help with synchronizing data.
Keep documents under owning users and have security rules check permissions.
Is it even possible to have Firebase Storage security rules consult Firebase to fetch metadata?
Obviously, I am trying not to go overboard with database access, money is tight.
Should I move all documents into a global docs collection and have security rules check ACLs that are in the docs metadata?
The simplest solution would be to create a global collection, where each document should have an array-type field, that should contain the UIDs of the users that are allowed to read. The absence of the field should mean that the document is private. You should always check in your application code if a particular UID exists in the array, but the most important thing is to check that in your security rules. To be able to do that, you need to have to sign the user into Firebase Authentication. As soon as the user is authenticated the request.auth variable (including request.auth.uid) becomes available, meaning that their token is automatically passed with any calls to Firestore.
Should I try to replicate shared documents in each user collection? Seems brittle but cloud functions should help with synchronizing data.
This practice is called denormalization, and it's quite common practice when it comes to NoSQL databases like Firestore. But I cannot see any reasons why you would do that. It's not necessary in this case.
Keep documents under owning users and have security rules check permissions.
It doesn't really matter where the documents exist, you always use security rules against malicious users.

Role based rules in firebase storage

I have a database having multiple groups - each having their own roles (admins, mods, etc..)
I have rules setup on firestore.
How do I replicate that on storage rules ?
To put it briefly, you can't without serious modifications.
Storage rules can't access Firestore documents. So all of the relationship you have in Firestore can not be used in Storage.
You can use Firebase Auth custom claims to attach per-user data that can be used in both Firestore and Storage, but this means you will have to duplicate that relationship data into those claims and keep them in sync in backend code.
You can also duplicate data from Firestore into metadata attached to files in Storage, and use that metadata in security rules to determine who can read or write individual files.
These are your only viable options without creating your own backend API endpoints that enforce security.

authorization and authentication mechanism in GCP

I want to create a Udemy like video platform where a user can see all videos but can watch videos only that he has purchased.
I am making a rest call to get the videos from the storage bucket from an angular application, using Firebase authentication here. In my GET request to storage bucket I am passing the access token that I got from Firebase authn.
Does this access token can be used to determine scope of the user to access video in a bucket?
Assume if I have given read access for a video in a bucket for a specific user, using the access token can I get the video? But every time I tried it shows unauthorized. Is there any other way to verify users access to storage bucket object.
Google recommend to not use ACL because it's hard to manage and to have a global view on the authorization.
In most cases, Cloud Identity and Access Management (Cloud IAM) is the recommended method for controlling access to your resources.
Caution: Permissions can be granted either by ACLs or Cloud IAM policies. In general, permissions granted by Cloud IAM policies do not appear in ACLs, and permissions granted by ACLs do not appear in Cloud IAM policies. The only exception is for ACLs applied directly on a bucket and certain bucket-level Cloud IAM policies, as described in Cloud IAM relation to ACLs.
IMO, the best pattern is to have a database on your side with the file on GCS allowed per user. You can store these in Firestore: affordable, pay as you use, generous free tier. For downloading the video, you can generate a temporarily access to the user by generating a signedUrl.
As per mention Guillaume Cloud Storage use the ACL pattern in order to have a control to the access of the resources stored in their buckets.
Nevertheless, when you need to storage wide objects per user in this case a video, you can store these in Firestore: affordable, pay as you use, generous free tier. This is a very suitable option since Firestore can use as another resource
Is recommended for this scenario generate a signed URL

Firebase Storage allow write to folder to multiple users

I have created an app, that allows users to create a simple photo collection. All the data is stored in the Firebase Cloud Firestore. The images are uploaded to Firebase Storage.
The owner of a collection can invite any other user to access his collection and upload photos.
The sharing of data in Firestore works fine. But now I have problems with writing the security rules for Storage. Does anyone know, how I have to write the rules, so that any user added to the collection can access the images as well? The files for each collection are stored in separate folders.
Firebase security rules currently do not bridge between products. You can't use data in Cloud Firestore in security rules for Cloud Storage. The only things you have access to in security rules for Cloud Storage are object metadata and Firebase Authentication custom claims per user. You will have to figure out a way to make changes to either one of those things to implement your permissions.
Alternatively, you can direct all access through Cloud Functions to decide if the user should be able to access the content, but bear in mind that Cloud Functions responses can only be 10MB maximum.
You should look into creating a private group and authenticate the group with help of private token.
https://firebase.google.com/docs/storage/security/user-security#group_private

Firebase rules: is it possible to communicate between security rules of different products

I understand that I can specify rules for some features in firebase like real-time database and firebase storage.
Example:
I can specify a rule in real time database that allows only users to update their data under their specific UID.
Question:
Is it possible to specify a rule in firebase storage such that a user can download a file (ex: image) if and only if he exists under a certain node in the real time database?
Is this communication between security rules of different products possible?
If no, what can I do?
Thanks.
You can't communicate between products like this.
What you can do instead is use custom claims on authenticated user profiles to control who can access what locations in various products.
Read more about custom claims here.
Read more about realtime database rules with custom claims. Read about auth.token.
In Firestore, you can use request.auth.token to access custom claims.
In Cloud Storage, you can also use request.auth.token.

Resources