Google Cloud Vision ML via REST - firebase

I'm taking my first steps with Vision ML and using the REST interface. (https://vision.googleapis.com/v1/files:annotate). As API key I provide the key from the Firebase project settings. In the Authorization Bearer, I supply the token from Firebase-Auth after sign-in.
When accessing Annotate I get a 403 (Permission_Denied) error message back:
Error opening file: gs://######.appspot.com/MyFile.tiff.
The object is available in the corresponding bucket and it is not blocked due to the Firebase Storage rules.
Can I pass a Firebase token in this REST interface at all?
How do I make sure that the service account can access the storage?
Thank you for any hint

Related

Using Firebase Auth Credentials to Access FirebaseStorage REST API

I am trying to use Firebase Auth credentials to access FirebaseStorage bucket. I have been successful in using the REST API https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o/ to perform uploads and downloads; even though the official documentation requires to use https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=media&name=OBJECT_NAME for uploads and https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME?alt=media for downloads, I am unable to use Firebase Auth credentials for them.
I am trying to implement resumable uploads and initiating it using https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME but there is no SESSION-URI that is returned. I tried to create my own URI using the id from the X-GUploader-UploadID header to create the URI in the format https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME&upload_id=UPLOAD_ID to start a single chunk upload but I got a Not Found error.
I need help on either rectifying that or using Firebase Auth to access the https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME REST API

Firebase (Flutter) - App Check fails when trying to access resource on Cloud Storage through getDownloadUrl()

I am using getDownloadUrl() to get the download URL for a Cloud Storage resource. Recently, I just enabled AppCheck on my Firebase app, and this download URL is requiring a AppCheck token to access. This behavior makes sense, but I was wondering if there is a built in way to do this? For most Firebase SDKs, the AppCheck token is passed automatically, but there does not seem to be a built in method to get that same automatic behavior with a download URL.
I have a theoretical solution in mind, and this is to pass the AppCheck token as a header in the request for the URL, but there's no documenation on this and I have no idea what header to pass this token in. I am using Flutter, and I am accessing an image resource through a CachedNetworkImage. Any insight in how I could pass AppCheck without using a Firebase SDK would be greatly appreciated.
You're supposed to be able to use getBlob or getBytes but I can't get it to work. CORS fails for me.
https://firebase.google.com/docs/storage/web/download-files#download_data_directly_from_the_sdk

firestore security rules for server side requests

i'm flutter-fire user since last fall
Note: The server client libraries bypass all Cloud Firestore Security
Rules and instead authenticate through Google Application Default
Credentials. If you are using the server client libraries or the REST
or RPC APIs, make sure to set up Identity and Access Management (IAM)
for Cloud Firestore.
Comment above is from link by firebase team. It sounds like 'server client libraries' or apis in the comment mean the requests from outside of my mobile apps, and they gon bypassing cloud firestore security rules. But when i tried the same get request with Postman with just same request from the one in my app without permission, the response in Postman console was fine, which means that there came a permission denied error.
So, here comes my question. I hope to know what types of requests exactly are equivalent to these 'server client libraries' or 'the REST or RPC APIs' mentioned in the official reference that bypass all the security rules. Postman is exactly 'the REST', and firebase worked as i wanted(produced permission denial) perfectly in this case. So there must be some specific types that firebase team actually intended to refer to be careful of.
I understand that firebase-admin sdk is one of the possible server side libraries, but exactly the same permission or auth procedures should be required when we tried to access firebase admin sdk which can control firebase data above the security rules just like firebase team commented. So the question is focusing on possible attackers' solutions to maliciously manipulate our firebase without the proper security procedures.
Hope some firebase gurus would give cool answers for the question with awesome knowledge and experiences! Thank you in advance [:
As their name indicate, the server client libraries are to be used from a server or from a "trusted environment" like Cloud Functions.
When interacting from your server (or your trusted environment) with the Firebase server APIs you don't authenticate as you would authenticate from a client application. Instead of using user accounts created through the Firebase Authentication service (e.g. email/password account) your server should use Google service accounts. More details here in the Firebase doc.
Note that for Cloud Functions, you initialize the Admin SDK with no parameters. In this case, the SDK uses Google Application Default Credentials (exactly as indicated in the documentation excerpt you mentioned in your question).
So, when your server (or your Cloud Function) interacts with the Firebase server APIs, since it is authenticated with a service account, the requests bypass all Cloud Firestore Security Rules. In other words, if you want to implement some check to allow/forbid specific operations based on specific parameters/values, you have to implement them in your code.
For the REST API, it is the same. The REST API can be used from a client application (a web app, a Flutter app, ...) or from a server.
Depending if it is a client or a server, you should authenticate by using a Firebase Authentication ID token or a service account (together with Google Identity OAuth 2.0 token), as explained in detail in the documentation.
So, when you make a request to the API with Postman without permission, as you did, the API detects that there is no Google Identity OAuth 2.0 token or Firebase Authentication ID token associated with the request and then the Security Rules are enforced => you get a "permission denied error".
In conclusion, if you correctly define your Security Rules you should not encounter any problem with "attackers maliciously manipulating" your database.
Note however that Security Rules only based on auth != null may not be sufficient to protect your data, as explained in this answer.

Does Authenticated Cloud Run instance natively support Firebase Authentication?

I have read this page a few times it implies and does not imply that if I enable authentication when deploying a Cloud Run instance I can use Firebase Auth to get through to the service.
I tried passing in a valid Firebase user idToken and did not get through. Was I doing something wrong or is the only way to get through to Cloud Run when Authentication is enabled to use google sign in?
Steps to reproduce:
When deploying to Cloud Run select Yes for authenticated
Generate a firebase auth token using REST call from here
make api call to Cloud run instance using header bellow and ID_TOKEN from step 2 above
Authorization: Bearer ID_TOKEN
According with the comment, the use case is to authorize only the registered, and the authenticated user (with Firebase auth), to use a Cloud Run endpoint deployed privately.
You can't do it directly, you need to use an additional layer. Here I propose to use Cloud Endpoint. I wrote an article on this to set up an authentication with API Key.
You have the principles of Cloud Endpoint there. You simply have to change the security definition from API Key to Firebase auth. You can found documentation here
Note: The authentication methods can evolved the next quarters. Stay tuned

What is the difference between Firebase API key (a.k.a Server Key) and the Web API Key?

In Firebase console under Project Settings/General beneath the Project ID field there is a Web API key :
Where is this used? I know that the Server key found under Project Settings/Cloud Messaging is used as Authorization key to make calls to the firebase console:
I have also noticed that in google-services.json ther is an "api_key" property that has a "current_key" value which is different from both keys that I have mentioned. What is that key?
From my answer here:
current key - nothing is explicitly stated anywhere in the docs where it is used, however, among the 3 services where the google-services.json was originally used for before Firebase (Google Sign-in, Analytics, GCM), I'm guessing it would be between Google Sign-in and Analytics. As also mentioned by #DiegoGiorgini here:
The api_key value in google-services.json is not used by FCM. (it is used by other Firebase libraries)
So it can be for a separate Google non-Firebase or Firebase service.
Web API Key - this one I haven't had a chance to use before. However, I've seen other posts wherein this specific API key is used often on Web apps related to Firebase (possibly also for Auth purposes?), but I'm not entirely sure.
Server Key - as per the docs:
A server key that authorizes your app server for access to Google services, including sending messages via Firebase Cloud Messaging.
current_key (as per the docs) is the Android key auto-created by Firebase when creating a Firebase Android App. It's NOT used to control access to backend resources. Instead, it's used to identify your Firebase project when interacting with Firebase/Google services. Specifically, it's used to associate API requests with your project for quota and billing.
Web API Key (as per the docs): can be used to authenticate users by passing its value to the key query parameter in several API endpoints, e.g., sign up or sign in using email & password, generate refresh token, etc.
Server Key (as per the docs): is a server key that authorizes your app server for access to Google services, including sending messages via the Firebase Cloud Messaging legacy protocols.

Resources