Home > Mobile >  Authenticating function to function calls for firebase functions on server side
Authenticating function to function calls for firebase functions on server side

Time:10-09

We are using firebase cloud functions in our application. We have 2 firebase functions: 1. A regular firebase cloud function that runs at regular intervals, 2. A firebase http function that is invoked by function #1 and can also be invoked from outside the application environment (in future). We have a use case where we have #1 firebase cloud function processes thousands of user records and performs some specific operations by invoking the #2 firebase http function. Our requirement now is to authenticate the invocation of the firebase http function. Both the firebase functions are in the same service account.

Following the steps in the documentation : https://cloud.google.com/functions/docs/securing/authenticating#authenticating_function_to_function_calls we tried to create an Id token in the calling function and included the ID token in an Authorization: Bearer ID_TOKEN header in the request to the http function.

Our code to obtain the id token. We tried using the firebase receiving function url, our firebase project url

const { URL } = require('url')
const targetAudience = new URL(url)
const client = await auth.getIdTokenClient(targetAudience)
const idToken = await client.request({ url })

Our code to verify the token

 const tokenId = request.get('Authorization').split('Bearer ')[1]
 const decodedIdToken = await admin.auth().verifyIdToken(tokenId)

We get back an idToken correctly, but when that token is verified, we always get this error :

Error while verifying Firebase ID token: { Error: Firebase ID token has incorrect "aud" (audience) claim. Expected "<firebase-project-name>" but got "https://<cloud-function-endpoint>". Make sure the ID token comes from the same Firebase project as the service account used to authenticate this SDK. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.

const targetAudience = new URL(url) - for the target audience we tried the firebase function URL of the http function, the name of the project, adding https to the name of the project, but we always keep getting the same error Firebase ID token has an incorrect "aud" claim

Any pointers on what we could we doing wrong? Has anyone tried to authenticate invocation to one cloud function when the calling function is another cloud function in the same service account.

CodePudding user response:

try to generate the idToken this way

const serviceAccountEmail = '...';
const generateIdToken = async () => {
    const tokens = await admin.options.credential?.getAccessToken();
    const projectId = 
    const res = await fetch(`https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${serviceAccountEmail}:generateIdToken`, {
        method: 'POST',
        headers: {
            authorization: `Bearer ${tokens?.access_token}`,
            'content-type': 'application/json',
        },
        body: JSON.stringify({
            delegates: [
            ],
            audience: projectId,
            includeEmail: true
        }),
    });
    return res.json();
}

Roles needed on the service account

  • Service Account Token Creator
  • Service Account User

Google APIs enable on the project

  • IAM Service Account Credentials API

CodePudding user response:

it seems the admin.auth().verifyToken is expecting the audience to be the projectId instead of the url of the function endpoint.

normally what I do when I want a function to be private(only invoke from other functions) I make it "require authentication(Manage authorized users with Cloud IAM.)" then I don't even have to verify the id token in my implementation.

  • Related