What do firebase cloud-storage read access rules apply to? SDK, URL http get, or both? - firebase

I'm new to firebase cloud storage. Quick question: Are firebase cloud-storage read rules meant to apply to SDK read access, or http (get) URL access (via the URL returned by the SDK after a write), or both?
May have followup questions depending on how this question is answered.
Thanks.

The Firebase security rules for Cloud Storage apply to users accessing Cloud Storage through the Firebase SDK.
The rules do not apply to users accessing Cloud Storage through a download URL, which is an unguessable URL that provides read-only access to files.
The rules also do not apply to users accessing Cloud Storage through one of the native Cloud Storage SDKs, which run with administrative permissions and are typically only run on app servers or otherwise trusted environments.

Related

How can I upload files to Cloud Storage through Cloud Functions and use Firestore to control access to Cloud Storage?

I'm trying to implement a system that allows react-native clients to upload files to a specific folder in Cloud Storage and allows clients to download from them. I can't do this directly from the client because I first need to query Firestore to validate that the user is 'friends' with the owner of the folder which will allow for read/write permissions.
I decided to use Cloud Functions as a middle layer to encapsulate this business logic and I expected to also be able to use it as a middle layer to upload the files. However, I feel like I may be misunderstanding how to best use these services together to solve this problem.
Current Plan:
Client uploads file to Cloud Function (assuming they are permitted after Cloud Function queries Firestore and validates)
Cloud Function uploads file to Cloud Storage
Client can then request file from Cloud Function, which validates permissions using Firestore and downloads file from CloudStorage
Cloud Function sends file to client
Questions:
Can/Should I use Cloud Functions in this way as a middle layer to upload files after validating permissions store in Firestore?
Is there an alternative solution using firebase that would mitigate the 10MB download limit with Cloud Functions but still allow me to authenticate uploads/downloads to and from Cloud Storage using my custom business logic on relationships in Firestore?
Any help or guidance here is appreciated! I'm very new to firebase, cloud architecture, and architecture in general.
This is definitely a valid and technically feasible approach. Whether you should do it, only you can determine of course.
An alternative is to use Firebase Storage's security rules to enforce the access control on the files. But you won't be able to read anything from Firestore in those rules, so you'll have to ensure everything needed to grant/deny access is in the path of the requested file, in the file's metadata, and/or in the user's token.
Even if you implement the download of files in Cloud Functions, you can still perform uploads through Firebase. You could in that case for example have the user write to a temporary location, which then triggers a Cloud Function that can do whatever additional checks you want on the file.

Getting a client URL to Firebase Cloud Storage that comply with storage rules

I have a web application on Firebase where I create a Firestore document with a reference to a Firebase Storage file.
I've setup rules on Firebase Storage to only allow read: if request.auth != null.
Since Firestore complies with similar rules I am able to ensure that access to my Firestore document is only possible, when a user is authenticated, but how do I best about enforcing the same rule in my web application to the Firebase Storage file?
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
I can create a Firebase Function that on each request checks authentication and if authenticated, generate a getSignedUrl() with an expiration of say 5 minutes and then do a 302 redirect to the temp public URL - but that does not comply with Firebase Storage rules so I need to replicate any new rulesets in the function
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
Am I totally missing a 3) and better option to make sure a user is logged in before accessing a file from storage?
According to the Cloud Storage for Firebase Documentation you can now access files through the Web SDK.
From version 9.5 and higher, the SDK provides these functions for
direct download:
getBlob()
getBytes()
getStream()
Using these functions, you can bypass
downloading from a URL, and instead return data in your code. This
allows for finer-grained access control via Firebase Security Rules.
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
It may not be very clear from the documentation, but that's exactly the way download URLs were designed to work.
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
It behaves like that when you use the provided client SDK to download files (not using download URLs). Unfortunately, the web SDK doesn't have a file download API (while Android and iOS do).
If you would like to file a feature request for the web SDK, that should go to Firebase support. For now, you have to use download URLs, which are publicly accessible. Or you can create your own backend endpoint that verifies an auth token provided by the client using the Firebase Admin SDK. The backend code can decide if the user should get be able to get the file contents.

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

Can cloud functions bypass firestore security rules

I recently developed with the implementation of firestore and firestore security rules.
Certain authenticated users can grab data if they are created by them, was one of the feature of the app.
i.e,
A creates X
B creates Y
A can't access Y and B can't access X.
This is ensured using security rules.
I deployed the app with cloud functions, and this acts as an api.
Simulating the security rules passes without failure, but when called the api for accessing via tool like postman,
A can access Y and X
and B can access X and Y.
I read this stack overflow question that talks about overwriting the security rule if used by firebase-admin sdk, which is what I am using.
But i am just curious, is there any other ways to restrict outside api tools to fetch data like this?
Here is the link
All access to Firebase and Cloud products (Realtime Database, Cloud Firestore, Cloud Functions) coming from any backend SDK will bypass security rules entirely. This includes the Firebase Admin SDK and any other Cloud SDKs. Security rules only apply to web and mobile client access.
YES, It Will
I enabled the following rule!
still, I was able to fetch data with
help of cloud function via Created API
/* The following code blocks whole database access*/
match /databases/{database}/documents{
match /{document=**}{
allow read, write:if false;
}}

How to upload the files to firebase storage with uid using Post Url?

I found one solution to upload the file to firebase storage without any authentication using this link How to upload objects to Firebase Storage using Postman for testing?
The above-mentioned case works only when my firebase storage looks like this, (Without any security restriction)
allow read, write;
But, Now I want to achieve this with some security restrictions.
Is there any way to upload the files to firebase storage by POST URL (Postman) with some security restriction.
I tried to achieve this by
https://firebasestorage.googleapis.com/v0/b/projectName.bucketName.com/o?uploadType=media&name=picture2&auth=uid
But it shows 403 - forbidden error.
There is no public REST API for uploading file to Cloud Storage for Firebase. The end point you're trying to reach is meant for use by the Firebase SDK only, and is neither documented, nor supported for use beyond that.
That said, you may be able to mint a token using the Firebase Authentication REST API, and pass that along to the request you have. But as said, it won't be supported and may change without warning.
The most common approach for REST uploads is through the Google Cloud Storage API, around which the Firebase APIs are a friendly wrapper. But these APIs are meant for access from trusted code, so wouldn't be using the Firebase Authentication UID of your users. The best I can think of is to write a Cloud Function that handles the user authentication and authorization, and then use the Google Cloud Storage Node.js or REST API to upload the file.
I use this endpoint on my project
https://firebasestorage.googleapis.com/v0/b/YOUR_BUCKET/o?uploadType=media&name=YOUR_FILE_PATH_AND_NAME
and add headers on your post
headers.Add("Authorization", "Bearer " + FirebaseAuthIDToken);
headers.Add("Content-Type", "application/octet-stream");

Resources