Deploying to Cloud Run with a custom service account failed with iam.serviceaccounts.actAs error
Asked Answered
W

5

43

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 [email protected]

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 [email protected] 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?

Wolter answered 22/4, 2019 at 3:12 Comment(0)
C
68

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 [email protected]. The permission is typically assigned through the roles/iam.serviceAccountUser role.

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

Contrabass answered 22/4, 2019 at 3:48 Comment(5)
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.Amandine
This makes sense now, thanks! I was looking at deploying to GAE with Travis CI tutorial cloud.google.com/solutions/continuous-delivery-with-travis-ci and couldn't see something similar to this, which got me confused.Wolter
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.Jugurtha
What I regret with GCP, in particular in IAM, is that the technical name of the privilege in question is not directly searchable in the list when adding a role. How can you quickly figure out that iam.serviceAccounts.actAs is equivalent to Service Account User? If you quickly type "service accounts" in the textarea, it won't come up... because it's plural.... The search engine should allow both technical name and human name.Hannie
@FabienHaddadi go to IAM & Admin -> Roles -> filter box -> enter permission (iam.serviceAccounts.actAs). You'll see the number of roles go down drastically (eg from 1500 to 30). If you still have many (like 30!), you can add filters, eg add Title:run to filter on just the cloud run related roles that have that permission.Spleen
Y
15

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

Yuki answered 28/8, 2019 at 9:37 Comment(3)
This is literally what the answer accepted above says.Wolter
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).Yuki
@ahmet, no it isn't. This gives a link to explicit steps, instead of a general explanation. Both are useful, but not the same.Catalonia
V
4

For the best practice, you should only allow lowest permission possible 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 [email protected] 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 [email protected]

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:[email protected]" \
--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 \
[email protected] \
--member="serviceAccount:[email protected]" \
--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="[email protected]"
Verena answered 22/9, 2022 at 7:40 Comment(0)
P
-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}"
Pola answered 15/11, 2021 at 19:24 Comment(1)
I assume this is down-voted due to the fact that although you have created a user-managed service account, it doesn't use that for deployment - it uses the [projectno]-compute@[projectid] account. You have no control over this.Giraffe
T
-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.

Tenterhook answered 22/4, 2019 at 3:47 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.