33

I have created a custom service account travisci-deployer@PROJECT_ID.iam.gserviceaccount.com on my project and gave it the Cloud Run Admin role:

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
   --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
   --role="roles/run.admin"

Then I set this service account as the identity for my gcloud commands:

gcloud auth activate-service-account --key-file=google-key.json

But when I ran gcloud beta run deploy command, I got an error about the "Compute Engine default service account" not having iam.serviceAccounts.actAs permission:

gcloud beta run deploy -q "${SERVICE_NAME}" \
  --image="${CONTAINER_IMAGE}" \
  --allow-unauthenticated
Deploying container to Cloud Run service [$APP_NAME] in project [$PROJECT_ID] region [us-central1]
Deploying...
Deployment failed
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: Permission 'iam.serviceaccounts.actAs'
denied on service account 1075231960084-compute@developer.gserviceaccount.com

This seems weird to me (because I'm not using the GCE default service account identity, although it's used by Cloud Run app once the app is deployed).

So the 1075231960084-compute@developer.gserviceaccount.com account is being used for the API call, and not my travisci-deployer@PROJECT_ID.iam.gserviceacount service account configured on gcloud?

How can I address this?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214

5 Answers5

48

TLDR: Add Cloud Run Admin and Service Account User roles to your service account.

If we read the docs in detail for the IAM Reference page for Cloud Run which is found here, we find the following text:

A user needs the following permissions to deploy new Cloud Run services or revisions:

  • run.services.create and run.services.update on the project level. Typically assigned through the roles/run.admin role. It can be changed in the project permissions admin page.
  • iam.serviceAccounts.actAs for the Cloud Run runtime service account. By default, this is PROJECT_NUMBER-compute@developer.gserviceaccount.com. The permission is typically assigned through the roles/iam.serviceAccountUser role.

I think these extra steps explain the story as you see it.

Laurent
  • 14,122
  • 13
  • 57
  • 89
Kolban
  • 13,794
  • 3
  • 38
  • 60
  • 2
    In particular, if `roles/iam.serviceAccountUser` were not checked, it would be possible for a user with either of the `run.*` permissions to do anything that the service account running the service can do (by holding code to do the thing for them, possibly including starting a compute VM with known login credentials). Requiring permission to `actAs` the service account for the Service closes this loophole by making the required permission explicit. – E. Anderson Apr 22 '19 at 05:12
  • This makes sense now, thanks! I was looking at deploying to GAE with Travis CI tutorial https://cloud.google.com/solutions/continuous-delivery-with-travis-ci and couldn't see something similar to this, which got me confused. – ahmet alp balkan Apr 22 '19 at 05:37
  • 13
    FYI: Having the role `Cloud Run Admin` is not enough to deploy, you'll need to also have the role `Cloud Run Service Agent` as well. – CenterOrbit Feb 15 '20 at 18:33
14

Adding Cloud Run Admin and Service Account User roles to my own service account fixed this for me. See step 2 in the docs here: https://cloud.google.com/run/docs/continuous-deployment#continuous

Tobi
  • 1,492
  • 1
  • 13
  • 20
  • This is literally what the answer accepted above says. – ahmet alp balkan Aug 28 '19 at 20:12
  • 1
    You are right, but I found it much easier to follow the instructions provided in the link in my answer (and maybe also for anyone else not so familiar with configuring IAM permissions). – Tobi Aug 29 '19 at 06:45
  • @ahmet, no it isn't. This gives a link to explicit steps, instead of a general explanation. Both are useful, but not the same. – thclark Sep 21 '22 at 16:28
1

For the best practice, you should only allow specific permission for the cloud run instance.

Reference: https://cloud.google.com/run/docs/reference/iam/roles#additional-configuration

Assuming you have two service accounts in your GCP.

One is the Clound Run identity service account/runtime service account.

Let it as identity-cloudrun@project-id.iam.gserviceaccount.com and this service account doesn't need to assign any permission to it because it is just as a identiy for the cloud run. If you need this cloud run instance access other GCP resource, you may add some permission for this service account.

Another one is the Deployment Service account which is used to deploy your Cloud Run.

Let it as deploy-cloudrun@project-id.iam.gserviceaccount.com

For the Deployment Service account, you need to grant Cloud Run Admin permissions to it specific to your-cloudrun-instance. So, it cannot access other cloud run instance.

gcloud run services add-iam-policy-binding your-cloudrun-instance \
--member="serviceAccount:deploy-cloudrun@project-id.iam.gserviceaccount.com" \
--role="roles/run.admin" \
--region=europe-west1

Also, you need to grant iam.serviceAccounts.actAs permission of identity service account to your deployment service account. This is mentioned by the documentation.

gcloud iam service-accounts add-iam-policy-binding \
identity-cloudrun@project-id.iam.gserviceaccount.com \
--member="serviceAccount:deploy-cloudrun@project-id.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"

So, you can deploy your cloud run like below by your deployment service account.

Note: In practice, you should use workload identity federation instead using your deployment service account directly.

gcloud run deploy your-cloudrun-instance \
--image="us-docker.pkg.dev/cloudrun/container/hello" \
--service-account="identity-cloudrun@project-id.iam.gserviceaccount.com"
ikhvjs
  • 5,316
  • 2
  • 13
  • 36
-2

Though you can resolve this particular error by granting the account permission to act as the Compute Engine default service account, it goes against the "best practices" advice:

By default, Cloud Run services run as the default Compute Engine service account. However, Google recommends using a user-managed service account with the most minimal set of permissions. Learn how to deploy Cloud Run services with user-managed service accounts in the Cloud Run service identity documentation.

You can indicate which service account identity the Cloud Run deployment will assume like so:

gcloud run deploy -q "${SERVICE_NAME}" \
  --image="${CONTAINER_IMAGE}" \
  --allow-unauthenticated \
  --service-account "${SERVICE_ACCOUNT_EMAIL}"
DragonBobZ
  • 2,194
  • 18
  • 31
-4

Currently, in beta, all Cloud Run services run as the default compute account (The same as the Google Compute Engine default service account).

The ability to run services as a different service account will be available in a future release.

ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214