Google cloud tasks fails to invoke cloud function: PERMISSION_DENIED(7): HTTP status code 403

166 views Asked by At

I'm struggling triggering a cloud function (gen2) with a google cloud task.

The error: PERMISSION_DENIED(7): HTTP status code 403

The cloud function log has warnings:

The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client

this.client = new v2beta3.CloudTasksClient();

    this.queuePath = this.client.queuePath(
      this.envService.gcp.project,
      this.envService.gcp.queue.region,
      this.envService.gcp.queue.name,
    );
 
const body = Buffer.from(JSON.stringify(payload)).toString('base64');

      const task = {
        httpRequest: {
          httpMethod: 'POST' as const,
          url: this.envService.gcp.functions.myFunction,
          headers: {
            'Content-Type': 'application/json',
          },
          body,
        },
      };

      task.httpRequest['oidcToken'] = {
        serviceAccountEmail: this.envService.gcp.serviceAccountEmail,
        audience: this.envService.gcp.functions.myFunction,
      };

      await this.client
        .createTask({
          parent: this.queuePath,
          task,
        })
        .catch((e: Error) => {
          console.log(e, e.stack);
          this.logger.error(e.message, null, QueueService.name);
          throw new InternalServerErrorException();
        });

I checked the conf variables, they contain the correct info for the project, function, service account, region and queue name.

And I can see the tasks in the cloud console.

---------

Regarding the service account in the code above:

The service account has the Cloud Function Invoker role for the cloud function.

The service account has the Cloud Task Admin & Cloud Task Enqueuer roles for the queue.

When I log the task registered, I see:

    authorizationHeader: 'oidcToken'

Not sure if it's helpful but I would expect an actual token here instead of oidcToken?

--------

Note: The nodejs server runs locally.

But I activated the service account (I can see it activated when I run gcloud auth list)

And I also set the environment variable:

GOOGLE_APPLICATION_CREDENTIALS

to the path of the service account key.json file.

Any idea of what I could be doing wrong?

Not sure if the error comes from lack of credentials when registering the task, or missing creds when the task tries to invoke the function. Not sure if these two things happen in different requests.

I tried several things:

  • add Invoke Cloud Function to allUsers and remove oidcToken from task.
  • login in gcloud with my own email (and adding role Service Account User role to my email on the service account).

Thanks for your help! And have a great day!

(Let me know if you need more info).

1

There are 1 answers

0
Loïc Combis On BEST ANSWER

Found the solution:

When deploying the cloud function, gcloud automatically generates a service account. We need to use this service account when registering the task (oidcToken --> serviceAccountEmail property).