2
votes

I've deployed a small HTTP endpoint via Google Cloud Run. It is working fine when I turn off the authentication.

I now want to turn it on so that it is only callable by my Firebase Cloud Function. If I understand it right, I just have to add the correct service account mail address in the IAM settings of the Cloud Run as "Cloud Run invoker". But which address is the correct one?

I've tried all addresses that I have found in Firebase Console -> Project Settings -> Service Accounts.

2

2 Answers

4
votes

I think you can check the specific firebase function. In the UI, the service account used should be listed.

By default, GCF functions all use <project_id>@appspot.gserviceaccount.com

1
votes

Thanks to @AhmetB - Google and @whlee's answer I got it working. Basically it is enough adding an Authorization Bearer token to the request, which you can get from a special endpoint: https://cloud.google.com/run/docs/authenticating/service-to-service#nodejs

Then you just have to add the service account of the function to the IAM list of the Cloud Run container: <project_id>@appspot.gserviceaccount.com

The nodejs example is using the deprecated request library, so here is my version using axios:

    const getOAuthToken = async (receivingServiceURL: string): Promise<string> => {

      // Set up metadata server request
      const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
      const uri = metadataServerTokenURL + receivingServiceURL;
      const options = {
        headers: {
          'Metadata-Flavor': 'Google'
        }
      };

      return axios.get(uri, options)
        .then((res) => res.data)
        .catch((error) => Promise.reject(error));
    }

Then you can just use the token in the actual request:

    const url = `...`;
    const token = await getOAuthToken(url);

    axios.post(url, formData, {
        headers: {
            Authorization: `Bearer ${token}`,
        }
    }).then(...).catch(...);