3
votes

I am struggling to enable deploying to cloud run for a service account. My logic looks something like:

gcloud auth activate-service-account \
  [email protected] \
  --key-file=my-project-123123213.json

gcloud run deploy my-project-action \
  --image "gcr.io/my-project/my-project-action:dev" \
  --project my-project \
  --verbosity debug \
  --region us-central1 \
  --allow-unauthenticated \
  --platform managed

This fails with:

HttpForbiddenError: HttpError accessing <https://us-central1-run.googleapis.com/apis/serving.knative.dev/v1/namespaces/my-project/services/my-project-action?alt=json>: response: <{'status': '403', 'content-length': '126', 'x-xss-protection': '0', 'x-content-type-options': 'nosniff', 'transfer-encoding': 'chunked', 'vary': 'Origin, X-Origin, Referer', 'server': 'ESF', '-content-encoding': 'gzip', 'cache-control': 'private', 'date': 'Wed, 01 Jan 2020 23:08:29 GMT', 'x-frame-options': 'SAMEORIGIN', 'alt-svc': 'quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000', 'content-type': 'application/json; charset=UTF-8'}>, content <{
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}
>
ERROR: (gcloud.run.deploy) PERMISSION_DENIED: The caller does not have permission

I have followed the steps https://cloud.google.com/run/docs/reference/iam/roles#additional-configuration for my service account. eg. it has project level roles/run.admin and roles/iam.serviceAccountUser. I have also tried giving it roles/editor or roles/owner for the project, but same result. I can see on my [email protected] user that [email protected] is a service account user.

I can deploy with the same deploy command if I authenticate as myself with gcloud auth login.

Using [email protected] and the same auth method, I am able to push new docker images to the container registry, so I think the auth process works, but I am missing some permission or something for cloud run deploy.

BTW I am deploying from cloud-sdk docker image.

3
What roles are assigned to [email protected]John Hanley
Did you check if the authentication works well? Try a gcloud run services list for example.guillaume blaquiere
Sorry, I've been sidetracked with other things, but I will come back to this. I'm now trying to use terraform to manage my gcp resources, so we will see if that helps.AlistairB

3 Answers

4
votes

I tried to reproduce the issue, and I can say that is working for me. The problem with Google Cloud Run, as with other services in Google Cloud, is that they use service identity.

During its execution, a Cloud Run revision uses a service account as its identity. This means that when your code uses Google Cloud client libraries, it automatically obtains and uses credentials from the runtime service account of the current Cloud Run revision. This strategy is called "Application Default Credentials".

As stated here, by default:

Cloud Run revisions are using the Compute Engine default service account ([email protected]), which has the Project > Editor IAM role. This means that by default, your Cloud Run revisions have read and write access to all resources in your Google Cloud project.

This means that you could use the compute Engine default service account in order to make the deploy if you would like to. It is also recommended granting more granular permissions to each of your Cloud Run services by assigning dedicated service accounts with more restricted IAM roles.

If you would like to create a new service account and used it as your account for deploying containers to Google Cloud Run, you will need to:

  1. Create a service account with the permissions necessary to do deployments, that you mentioned in the question. In general you will need:

    • roles/run.admin which gives run.services.create and run.services.update.
    • roles/iam.serviceAccountUser which gives iam.serviceAccounts.actAs

This last one is the most important. Since you would like to use non-default services identities, the account or deployer must have the iam.serviceAccounts.actAs permission on the service account being deployed, as you can see here.

  1. Once your service account has this permissions, you could deploy a new service with the service account (a non-default identity) using the command you provided, but adding the --service-account flag, as shown here:

  gcloud run deploy my-project-action \
  --image "gcr.io/my-project/my-project-action:dev" \
  --project my-project \
  --verbosity debug \
  --region us-central1 \
  --allow-unauthenticated \
  --platform managed \
  --service-account [SERVICE_ACCOUNT]

It should work with gcloud run deploy, but in case not, you can also try gcloud beta run deploy.

You could see further information about the --service-account flag here, but in summary:

Email address of the IAM service account associated with the revision of the service. The service account represents the identity of the running revision, and determines what permissions the revision has. If not provided, the revision will use the project's default service account.

I hope it helps.

0
votes

I would like to summarize my struggle on the same topic.

In my case, it's a little difference as I also use Cloud SQL too. The point is the error is the same.

The service account used for deployment need to have all required permissions.

The most fundamental ones are in the document, Cloud Run Admin and Service Account User.

However, in my case using Cloud SQL, the Cloud SQL Viewer role is required too.

The hard thing about this story is that, it always shows as missing gcloud.run.deploy

0
votes

Cloud SQL on Cloud Run insufficient permissions

I experienced this error during my build process, immediately after migrating our Postgres databases to Google. Herein is my specific solution to the issue, given the excellent suggestions from @spicydog's answer.

This happened because I had yet to grant the correct permission roles for using our new Postgres databases at Google to our cloud build and cloud run service accounts.

Steps to grant the correct IAM roles

The gist of the solution is that you'll need to add roles to at least two service accounts, if you're using the defaults suggested by the documentation.

1. Add Cloud SQL Client roles to your default cloud run service account

My issue was that I was missing appropriate permissions on my default cloud run service account. From the docs:

Cloud Run (fully managed) uses a service account to authorize your connections to Cloud SQL. This service account must have the correct IAM permissions to successfully connect. Unless otherwise configured, the default service account is in the format [email protected].

When connecting resources in two different projects, make sure that both projects have enabled the correct IAM roles and have given the service account the correct permissions.

Ensure that the service account for your service has one of the following IAM roles:

  • Cloud SQL Client (preferred)
  • Cloud SQL Editor
  • Cloud SQL Admin

So I followed their instructions and added the Cloud SQL Client role to my ${PROJECT_NUMBER}[email protected] service account.

2. Add Cloud SQL Admin roles to your cloud build service account

Fingers crossed, builds going, No está bien! Since @spicydog seemed to indicate two service accounts requiring roles, I added the Cloud SQL Admin role to my cloud build service account, ${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com

References

Here are docs on how to add a role to a user. Their frontend is excellend, IMHO.

Others utilized: