How to impersonate a Google cloud service account from another user account

Let’s say we’ve a cloud run function.

The service account joe-runner in a big corp project called big-corp should be allowed to invoke the cloud run function.

Our cloud run function is in a different project (mwco).

How can we test this from our user account?

First, we need to make sure that the service account has the roles/run.invoker role on the cloud run function.

Via terraform, we can do this:

resource "google_cloud_run_v2_service_iam_member" "big_corp_invoker" {
  location   = google_cloudfunctions2_function.default.location
  name       = google_cloudfunctions2_function.default.name
  role       = "roles/run.invoker"
  member     = "serviceAccount:joe-runner@big-corp.iam.gserviceaccount.com"
  depends_on = [google_cloudfunctions2_function.default]
}

Or via gcloud cli:

gcloud run services add-iam-policy-binding my-cloud-run-function --member="serviceAccount:serviceAccount:joe-runner@big-corp.iam.gserviceaccount.com" --role="roles/run.invoker" --region=eu-west3 --project=mwco

Make sure that the user account that wants to impersonate the service account has the roles/iam.serviceAccountTokenCreator role on the service account.

gcloud projects add-iam-policy-binding big-corp --member=user:gorilla.moe@mistweaverco.com --role='roles/iam.serviceAccountTokenCreator'

And now, you want to grant a specific service account access to invoke the cloud run.

gcloud iam service-accounts add-iam-policy-binding joe-runner@big-corp.iam.gserviceaccount.com --member=user:gorilla.moe@mistweaverco.com --role='roles/iam.serviceAccountTokenCreator' --project=big-corp

Finally, to get a token that impersonates the service account, and can be used to invoke the cloud run function:

gcloud auth print-access-token --impersonate-service-account=joe-runner@big-corp.iam.gserviceaccount.com

This will return an access token that you can use to invoke the cloud run function

export GCP_BEARER_TOKEN=$(gcloud auth print-access-token --impersonate-service-account=joe-runner@big-corp.iam.gserviceaccount.com)
if [ -z "$GCP_BEARER_TOKEN" ]; then
  echo "Failed to get GCP bearer token"
  exit 1
else
curl -H "Authorization: Bearer $GCP_BEARER_TOKEN" 
    https://my-cloud-run-function-eu-west3.a.run.app/
fi