How to impersonate a service account from a differnet project when creating a cloudrun in a workflow?

Viewed 45

A workflow fails to start due to permission denied error when trying to impersonate a service account from different project

given:

Projects:

  • project1
  • project2

Service Accounts:

  • sa1@project1 with roles:

    • Workflows Admin
    • Cloudrun Admin
    • Service Account Token Creator
    • Service Account User
  • sa2@project2

Workflows:

A workflow1 in project1 (creates a cloudrun instance with serviceAccountName=sa2@project2)

Result:

{
  "body": {
    "error": {
      "code": 403,
      "message": "Permission 'iam.serviceaccounts.actAs' denied on service account sa2@project2 (or it may not exist).",
      "status": "PERMISSION_DENIED"
    }
  },
  "code": 403,
  "headers": {
    "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
    "Cache-Control": "private",
    "Content-Length": "244",
    "Content-Type": "application/json; charset=UTF-8",
    "Date": "Wed, 14 Sep 2022 10:53:24 GMT",
    "Server": "ESF",
    "Vary": "Origin",
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "SAMEORIGIN",
    "X-Xss-Protection": "0"
  },
  "message": "HTTP server responded with error code 403",
  "tags": [
    "HttpError"
  ]
}

2 Answers

The error message "Permission 'iam.serviceaccounts.actAs' denied on service account sa2@project2 indicates that users need permission to impersonate a service account in order to attach that service account to a resource. This means that the user needs the iam.serviceAccounts.actAs permission on the service account.

There are several predefined roles that allow a principal to impersonate a service account:

Service Account User

Service Account Token Creator

Workload Identity User

Alternatively, you can grant a different predefined role, or a custom role, that includes permissions to impersonate service accounts.

Service Account User (roles/iam.serviceAccountUser): This role includes the iam.serviceAccounts.actAs permission, which allows principals to indirectly access all the resources that the service account can access. For example, if a principal has the Service Account User role on a service account, and the service account has the Cloud SQL Admin role (roles/cloudsql.admin) on the project, then the principal can impersonate the service account to create a Cloud SQL instance.

You can try giving a service account User role on the service account which is trying to create a cloud run instance.

Refer to the link for more information on impersonating service accounts.

My client is a huge corporate. Therefore the project level configuration to switch service accounts across projects is disabled (iam.disableCrossProjectServiceAccountUsage is enforced )

This is the root cause of my problem and I cannot change it. More information is available here: https://cloud.google.com/iam/docs/impersonating-service-accounts#attaching-different-project

My work around:

I needed this this as it seemed the simplest way to access external BigQuery Dataset & Project.

Solution: Export private key for sa2@project2 and pass it as a secret to application layer. Use the key file to imperosnatesa2@project2 service account.

example:

engine = create_engine('bigquery://project2', location="asia-northeast1")

Related