Search code examples
pythongoogle-cloud-platformgcloudgoogle-iamgoogle-cloud-iam

GCP: Impersonate Service Account with python from local creds. IAM Service Account Credentials API disabled


In python code, I want to impersonate a service account to perform some action. I do it as follows:

request = google.auth.transport.requests.Request()
    credentials, _ = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"],
    )

    if not credentials.valid:
        try:
            credentials.refresh(request)
        except google.auth.exceptions.RefreshError:
            raise PermissionError(
                "GCP default credentials could not be refreshed. Verify your default configuration is correct.",
            )

    target_credentials = impersonated_credentials.Credentials(
        source_credentials=credentials,
        target_principal="my-service-account@company.iam.gserviceaccount.com",
        target_scopes=scopes,
    )

This gives me the following error: 'Unable to acquire impersonated credentials', '{\n "error": {\n "code": 403,\n "message": "IAM Service Account Credentials API has not been used in project my_project_id before or it is disabled.'

my_project_id here is the defaut project set in my gcloud CLI. The API is indeed not activated, but I want that code to be able to run on any env, regardless of the local default project.

I saw in the documentation a parameter called 'iam_endpoint_override' which I think might help, but I have no idea what "The full IAM endpoint override with the target_principal embedded" could mean.


Solution

  • In your code, you can specify the project to use to perform the request. It's named the "quota project". If there is a quotas or a cost associated to the API request, the quota project will be used (for the billing or the rate limiting (i.e. the quota limits))

    In your code, you can specify the quota project like that

    request = google.auth.transport.requests.Request()
        credentials, _ = google.auth.default(
            quota_project_id=<YOUR QUOTA PROJECT>,
            scopes=["https://www.googleapis.com/auth/cloud-platform"],
        )
    

    If you use the API, you can add the header x-goog-user-project to specify the quota project

    curl -H "x-goog-user-project: <YOUR QUOTA PROJECT>" .....