Project Id in error message is not the one set in `gcloud config set` when use Google API Client Library

Viewed 373

I call the Storage Transfer API following the documentation. https://cloud.google.com/storage-transfer/docs/reference/rest/v1/transferJobs/patch

This is my code.

from pprint import pprint
from googleapiclient import discovery
import google.auth
credentials, project = google.auth.default()

service = discovery.build("storagetransfer", "v1", credentials=credentials)
job_name = "transferJobs/XXXXXXXXXXXXXXXX"

update_transfer_job_request_body = {
    "transferJob": {"description": "xxxxxxxxxxx"},
    "projectId": project,
}

request = service.transferJobs().patch(
    jobName=job_name, body=update_transfer_job_request_body
)
response = request.execute()

pprint(response)

Before executing this script, I ran the gcloud config list to make sure the project id was correct and that the environment variable GOOGLE_APPLICATION_CREDENTIALS was not set.

But I see another project id(aaaaaaaaaaa) in the next returned error message.

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://storagetransfer.googleapis.com/v1/transferJobs/XXXXXXXXXXXXXXXX?alt=json returned "Caller does not have required permission to use project aaaaaaaaaaa. Grant the caller the roles/serviceusage.serviceUsageConsumer role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=aaaaaaaaaaa and then retry. Propagation of the new permission may take a few minutes.". Details: "[{'@type': 'type.googleapis.com/google.rpc.Help', 'links': [{'description': 'Google developer console IAM admin', 'url': 'https://console.developers.google.com/iam-admin/iam/project?project=aaaaaaaaaaa'}]}, {'@type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'USER_PROJECT_DENIED', 'domain': 'googleapis.com', 'metadata': {'service': 'storagetransfer.googleapis.com', 'consumer': 'projects/aaaaaaaaaaa'}}]

2 Answers

I assume Project ID aaaaaaaaaaadoes not correspond to the ID of one your projects.

I'm not on a device where I can easily use gcloud but, when I get to one, I'll add the Project ID used by gcloud to synthesize Service Accounts from user accounts with gcloud auth application-default credentials.

I think you should not use gcloud auth application-default credentials but should create a Service Account in your project, grant it suitable permissions and authenticate with it .

If your code is running off GCP, you'll need to export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key before running the code.

Using gcloud auth application-default can be useful for testing code but it's increasingly discouraged in favor of using a proper Service Account. One problem with it is that the synthetic Service Account is owned by a Google-owned project (aaaaaaaaaaa) not a user-owned project and the Google-owned project does not have every Google API enabled.

I think this is the problem you're experiencing.

As @DazWilkin said using a service account will be more appropriate, In addition to this by adding the Cloud IAM permission serviceusage.services.enable to enable services. Depending on what features you require, such as listing services, you need serviceusage.services.list can resolve the error.

Typically you can add the role roles/serviceusage.serviceUsageAdmin which includes the following permissions:

  • serviceusage.services.get
  • serviceusage.services.list
  • serviceusage.services.enable
  • serviceusage.services.disable

Refer this documentation for more information on Service Usage uses IAM to control access to services and Refer this documentation for adding roles to a service account.

Related