Service identity

Every Cloud Run revision or job is linked to a service account. This service account is automatically used by the Google Cloud client libraries to authenticate with Google Cloud APIs. Examples of Google Cloud APIs your service's code can interface with include Cloud Storage, Firestore, Cloud SQL, Pub/Sub, or Cloud Tasks.

If you don't specify a service account, Cloud Run links a revision or job to the default service account which has broad permissions across all Google Cloud APIs. Google recommends using per-service identity and granting selective permissions instead.

About the default service account

By default, Cloud Run revisions and jobs execute as the Compute Engine default service account. The Compute Engine default service account has the Project Editor IAM role which grants read and write permissions on all resources in your Google Cloud project.

While this may be convenient, rather than use the default service account, Google recommends creating your own user-managed service account with the most granular permissions and assigning that service account as your Cloud Run service or job identity. This document describes how to configure per-service identities with Cloud Run.

Using per-service identity

Google recommends giving every Cloud Run service or job a dedicated identity by assigning it a user-managed service account instead of using the default service account. User-managed service accounts allow you to control access by granting a minimal set of permissions using Identity and Access Management.

The Google Cloud CLI and Google Cloud client libraries automatically detect when they are running on Google Cloud and use the runtime service account of the current Cloud Run revision. That means that if your code uses the gcloud CLI or an official Google Cloud client library, it will automatically detect and authenticate as the Cloud Run service's runtime service account. This strategy is called Application Default Credentials, and enables code portability across multiple environments.

There are two aspects to assigning per-service identity:

Permissions required to assign user-managed service accounts

To deploy a Cloud Run service using a user-managed service account, you must have permission to impersonate (iam.serviceAccounts.actAs) that service account. This permission can be granted via the roles/iam.serviceAccountUser IAM role. All principals (e.g. users, service accounts) must have this permission on the user-managed service account in order to deploy a Cloud Run service as the user-managed service account.

You can grant this permission using the Google Cloud console, via the API (YAML), or using the gcloud CLI as follows:

gcloud iam service-accounts add-iam-policy-binding "SERVICE_ACCOUNT_EMAIL" \
    --member "PRINCIPAL" \
    --role "roles/iam.serviceAccountUser"

Replace:

  • SERVICE_ACCOUNT_EMAIL with the service account email address, such as PROJECT_NUMBER-compute@developer.gserviceaccount.com.
  • PRINCIPAL with the principal you are adding the binding for. Use the format user:email, for example, user:test-user@gmail.com.

To learn how to grant permissions, refer to granting, changing, and revoking access to resources.

Deploying a new service with a user-managed service account

If you don't already have a user-managed service account, first create a service account.

You can set the Cloud Run service's service account using the Google Cloud console, the gcloud CLI, or the API (YAML) when you create a new service or deploy a new revision:

Console

  1. In the Google Cloud console, go to Cloud Run:

    Go to Cloud Run

  2. Click Create Service if you are configuring a new service you are deploying to. If you are configuring an existing service, click the service, then click Edit and deploy new revision.

  3. If you are configuring a new service, fill out the initial service settings page as desired, then click Container(s), volumes, networking, security to expand the service configuration page.

  4. Click the Security tab.

    image

    • Click the Service account dropdown and select the desired service account.
  5. Click Create or Deploy.

gcloud

You can update an existing service to have a new runtime service account by using the following command:

gcloud run services update SERVICE --service-account SERVICE_ACCOUNT

Replace:

  • SERVICE with the name of your service.
  • SERVICE_ACCOUNT with the service account associated with the new identity: this value is the email address for the service account, for example, example@myproject.iam.gserviceaccount.com.

You can also set a service account during deployment using the command:

gcloud run deploy --image IMAGE_URL --service-account SERVICE_ACCOUNT

Replace:

  • IMAGE_URL with a reference to the container image, for example, us-docker.pkg.dev/cloudrun/container/hello:latest. If you use Artifact Registry, the repository REPO_NAME must already be created. The URL has the shape REGION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG .
  • SERVICE_ACCOUNT with the service account associated with the new identity: this value is the email address for the service account, for example, example@myservice.iam.gserviceaccount.com.

YAML

You can download and view existing service configurations using the gcloud run services describe --format export command, which yields cleaned results in YAML format. You can then modify the fields described below and upload the modified YAML using the gcloud run services replace command. Make sure you only modify fields as documented.

  1. To view and download the configuration:

    gcloud run services describe SERVICE --format export > service.yaml
  2. Update the serviceAccountName: attribute:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
    spec:
      template:
        spec:
          serviceAccountName: SERVICE_ACCOUNT

    Replace

    • SERVICE with the name of your Cloud Run service.
    • SERVICE_ACCOUNT with the service account associated with the new identity: this value is the email address for the service account, for example, example@myproject.iam.gserviceaccount.com.
  3. Replace the service with its new configuration using the following command:

    gcloud run services replace service.yaml

Terraform

To learn how to apply or remove a Terraform configuration, see Basic Terraform commands.

To create a service account, add the following resource to your to your existing main.tf file:

resource "google_service_account" "cloudrun_service_identity" {
  account_id = "my-service-account"
}

Create or update a Cloud Run service and include your service account:

resource "google_cloud_run_v2_service" "default" {
  name     = "cloud-run-srv"
  location = "us-central1"

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello"
    }
    service_account = google_service_account.cloudrun_service_identity.email
  }
}

Using service accounts in other projects

You can also use a user-managed service account that resides in a different Google Cloud project than the Cloud Run service. If the service account and Cloud Run service are in different projects:

  • The project containing this service account requires the org-policy iam.disableCrossProjectServiceAccountUsage to be set to false/unenforced at the folder level or inherited from project-level settings. By default, this is set to true.

  • The service account requires a role membership for roles/iam.serviceAccountTokenCreator for the deploying-project's service agent:

    service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com
    

    where PROJECT_NUMBER is the project number for the project.

  • The service account requires a role membership for roles/iam.serviceAccountUser for the identity (user or automation) that is performing the deploy operation.

You can apply role memberships directly to the service account resource or inherit from higher levels in the resource hierarchy.

Permissions required by user-managed service accounts to operate Cloud Run

If a Cloud Run service does not access any other parts of Google Cloud, its service account does not need to be granted any roles or permissions.

When you create a new service account from the Google Cloud console, the optional step "Grant this service account access to the project" is for any additional access required. For example, one Cloud Run service might invoke another private Cloud Run service, or it might access a Cloud SQL database, both which require specific IAM roles. Refer to the documentation on managing access for more information.

Fetching ID and access tokens using the metadata server

If your Cloud Run service's code uses a Google Cloud client library, the library automatically acquires the access tokens to authenticate your code's requests using the service's runtime service account.

If you are instead using your own custom code, you can use the metadata server to fetch access tokens and ID tokens manually. Note that you cannot query this server directly from your local machine as the metadata server is only available for workloads running on Google Cloud.

The two types of tokens you can fetch with the metadata server are as follows:

To fetch a token, select one of these options:

Access tokens

For example, if you want to create a Pub/Sub topic, use the projects.topics.create method.

  1. Use the Compute Metadata Server to fetch an access token:

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
        --header "Metadata-Flavor: Google"
    

    This endpoint returns a JSON response with an access_token attribute.

  2. In your HTTP/protocol request, the request must be authenticated with an access token in the Authorization header:

    PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/topics/TOPIC_ID
    Authorization: Bearer ACCESS_TOKEN
    

    Where:

    • PROJECT_ID is your project ID.
    • TOPIC_ID is your topic ID.
    • ACCESS_TOKEN is the access token you fetched in the previous step.

    Response:

    {
        "name": "projects/PROJECT_ID/topics/TOPIC_ID"
    }
    

ID tokens

Use the Compute Metadata Server to fetch an identity token with a specific audience:

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE" \
    --header "Metadata-Flavor: Google"

Where AUDIENCE is the JWT Audience requested.

For Cloud Run services, the audience should be either the URL of the service you are invoking or a custom audience, such as a custom domain, configured for the service.

https://service.domain.com

For other resources, it is likely the OAuth Client ID of an IAP-protected resource:

1234567890.apps.googleusercontent.com

Getting recommendations to create dedicated service accounts

The Recommender service automatically supplies recommendations to create a dedicated service accounts with the minimal required set of permissions.

Next steps

Learn how to manage access to or securely authenticate developers, services, and end-users to your services.

For an end-to-end walkthrough of an application using service identity to minimize security risk, follow the securing Cloud Run services tutorial.