cloudtasks.CreateTask fails: `lacks IAM permission "cloudtasks.tasks.create"` even though my account has that permission
Asked Answered
T

2

1

I'm following the Creating HTTP Target tasks guide. When I run the code posted below I get this error:

cloudtasks.CreateTask: rpc error: code = PermissionDenied 
desc = The principal (user or service account)
lacks IAM permission "cloudtasks.tasks.create" for the resource
 "projects/my_project/locations/europe-west1/queues/my_queue" 
(or the resource may not exist).

I have signed in with gcloud auth login [email protected]. [email protected] has the following permissions set by my custom cloud task role:

  • cloudtasks.locations.get
  • cloudtasks.locations.list
  • cloudtasks.queues.get
  • cloudtasks.queues.list
  • cloudtasks.tasks.create
  • cloudtasks.tasks.delete
  • cloudtasks.tasks.fullView
  • cloudtasks.tasks.get
  • cloudtasks.tasks.list
  • cloudtasks.tasks.run

I don't get it. What more should I check?

main.go

// Run `PROJECT_ID=my_project QUEUE_ID=my_queue go run main.go`
package main

import (
  "context"
  "fmt"
  "os"

  cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
  taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2"
)

var (
  locationID = "europe-west1"
  url        = "example.com/callback"
  message    = "testing"
)

func main() {
  projectID := os.Getenv("PROJECT_ID")
  queueID := os.Getenv("QUEUE_ID")

  task, err := createHTTPTask(projectID, locationID, queueID, url, message)
  if err != nil {
    fmt.Println(err)
  }
  fmt.Println(task)
}

// createHTTPTask creates a new task with a HTTP target then adds it to a Queue.
func createHTTPTask(projectID, locationID, queueID, url, message string) (*taskspb.Task, error) {
  // Create a new Cloud Tasks client instance.
  // See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
  ctx := context.Background()
  client, err := cloudtasks.NewClient(ctx)
  if err != nil {
    return nil, fmt.Errorf("NewClient: %v", err)
  }
  // Build the Task queue path.
  queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)
  // Build the Task payload.
  // https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
  req := &taskspb.CreateTaskRequest{
    Parent: queuePath,
    Task: &taskspb.Task{
      // https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
      MessageType: &taskspb.Task_HttpRequest{
        HttpRequest: &taskspb.HttpRequest{
          HttpMethod: taskspb.HttpMethod_POST,
          Url:        url,
        },
      },
    },
  }
  // Add a payload message if one is present.
  req.Task.GetHttpRequest().Body = []byte(message)
  createdTask, err := client.CreateTask(ctx, req)
  if err != nil {
    return nil, fmt.Errorf("cloudtasks.CreateTask: %v", err)
  }
  return createdTask, nil
}

The Cloud Tasks API is enabled.

Trichinopoly answered 25/2, 2020 at 12:39 Comment(4)
Did you delete and re-create your service account with the same name?Jarnagin
you can check the document on Troubleshooting accessCleland
Having the same issue as well. I also tried adding an iam policy binding between the service account and the task queue itself, but that didn't help. Using the Policy Troubleshooter confirms that my service account contains roles with the "cloudtasks.tasks.create" permission. I'm inclined to think this is on Google's end at this pointEustasius
Interesting: when I call the Cloud Tasks api through the API Explorer (cloud.google.com/tasks/docs/reference/rest/v2beta3/…), it works just fine. Task gets created in the queueEustasius
E
2

I've been having the same issue for the past couple of days and figured it out. The library I was using to create the API client and create a task was using different credentials than I expected.

For those that are using "application default credentials", or at least letting the client find credentials automatically, take a look at this page: https://cloud.google.com/docs/authentication/production#finding_credentials_automatically

I had created a service account with all the right roles and was assuming the API client was using the service account. Turns out I wasn't passing in the key file and thus it was using the "application default credentials". For my use case, "application default credentials" referred to the App Engine default service account. When I supplied the API client with a key file for my custom service account, it worked.

Eustasius answered 26/2, 2020 at 22:58 Comment(2)
That's correct. I fixed it by running this command before I ran the script: export GOOGLE_APPLICATION_CREDENTIALS=../path/to/credentials.jsonTrichinopoly
This is mentioned in the documentation too firebase.google.com/docs/admin/…Penurious
R
1

Application Default Credentials (ADC) provide a method to get credentials used in calling Google APIs. The gcloud auth application-default command group allows you to manage active credentials on your machine that are used for local application development.

Acquire new user credentials to use for ADC with the following command:

gcloud auth application-default login
Ruthannruthanne answered 10/2, 2021 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.