I have a firebase function which I want to permit write access to cloud storage. I believe I need to setup a service account with those permissions, and then grant them programmatically inside my function, but I'm confused how to do this.
The firebase function writes a file to a bucket on a trigger. The storage settings for the firebase storage are set to the default, which means they require the client to be authenticated:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
In this document (https://cloud.google.com/functions/docs/concepts/iam), under "Runtime service account", I see this:
At runtime, Cloud Functions uses the service account [email protected], which has the Editor role on the project. You can change the roles of this service account to limit or extend the permissions for your running functions.
When it says "runtime," I'm assuming this means the firebase function runs within a context of that service account and the permissions granted to it. As such, I'm assuming I need to make sure the permissions of that service account have write access, as I see from this link (https://console.cloud.google.com/iam-admin/roles?authuser=0&consoleUI=FIREBASE&project=blahblah-2312312).
I see the permission named storage.objects.create
and would assume I need to add this to the service account.
To investigate the service account current settings, I ran these commands:
$ gcloud iam service-accounts describe [email protected]
displayName: App Engine default service account
email: [email protected]
etag: BwVwvSpcGy0=
name: projects/blahblah-2312312/serviceAccounts/[email protected]
oauth2ClientId: '98989898989898'
projectId: blahblah-2312312
uniqueId: '12312312312312'
$ gcloud iam service-accounts get-iam-policy [email protected]
etag: ACAB
I'm not sure if there is a way to get more details from this, and unsure what etag ACAB indicates.
After reviewing this document (https://cloud.google.com/iam/docs/granting-roles-to-service-accounts) I believe that I need to grant the permissions. But, I'm not entirely sure how to go from the JSON example and what structure it should be and then associate the policy, or if that is even the correct path.
{
"bindings": [
{
"role": "roles/iam.serviceAccountUser",
"members": [
"user:[email protected]"
]
},
{
"role": "roles/owner",
"members": [
"user:[email protected]"
]
}
],
"etag": "BwUqLaVeua8=",
}
For example, my questions would be:
- Do I need to make up my own etag?
- What email address do I use inside the members array?
I see this command listed as an example
gcloud iam service-accounts add-iam-policy-binding \
[email protected] \
--member='user:[email protected]' --role='roles/editor'
What I don't understand is why I have to specify two quasi-email addresses. One is the service account, and one is the user associated with the service account. Does this mean that user [email protected]
can operate under the credentials of the service account? Can I just have the service account on its own have permissions which I use in my cloud function?
Is there a simpler way to do this using only the command line, without manually editing JSON?
And, then once I have my credentials properly established, do I need to use a JSON service account file as many examples show:
var admin = require('firebase-admin');
var serviceAccount = require('path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
Or, can I just make a call to admin.initializeApp()
and since "... at runtime, Cloud Functions uses the service account [email protected]..." the function will automatically get those permissions?
require('firebase-admin').initializeApp();
right before my call tofunctions.firestore.document(...)
and I'm still getting thisApiError: [email protected] does not have storage.objects.create access to signatures/98989123KJLKJAS-KJLJLKJL8722.png
– xrdupload
call. – xrd