Service identity & authentication
A Cloud Run service has two IAM-related sides. Access & networking covered the inbound side - who may invoke the service. This page is the outbound side: the identity your code runs as when it calls other Google Cloud services (Pub/Sub, Cloud SQL, Cloud Storage, ...).
Google client libraries running in your container automatically use this service identity to authenticate their API calls, and IAM authorizes each call against it.
The default service account is a risk
If you deploy a service (or job) without specifying a service account, Cloud Run runs it as the Compute Engine default service account, which carries the broad Editor basic role on the project.
Because of policy-binding inheritance, that identity has read/write access to most resources in the project - it can create, modify, or delete them.
Convenient, but an inherent security risk: any code (or dependency) running in your container inherits Editor across the whole project. Newer orgs disable the automatic Editor grant via the iam.automaticIamGrantsForDefaultServiceAccounts org policy. See Service accounts.
Use the principle of least privilege
In production, replace the default identity with a dedicated, user-managed service account granted only the roles it needs:
- Create a new user-managed service account for the service (console or
gcloud). - Configure it as the Cloud Run service's identity - set at create, update, or new-revision deploy time (console, gcloud CLI, YAML, or Terraform).
- Grant it predefined or custom roles, bound on the specific resources the service must reach. A brand-new SA appears in no policy binding, so every API call it makes is rejected by IAM until you add one.
That command is the third step drawn out: the service account is the member, roles/pubsub.publisher is the role, and the binding lives in the IAM policy attached to the topic - so the service is authorized to publish.
The role kinds (basic vs predefined vs custom) and the policy-binding model (member + role + permissions, attached to a resource) are the generic IAM machinery - see Roles and Members & Policies.
Calling Google Cloud APIs
When your application code uses a client library to call a Google API (say, publishing to a Pub/Sub topic), the library automatically acquires a token using the runtime service account - no keys in your code. For most Google APIs this is an OAuth 2.0 access token.
The access token travels with the API call. IAM verifies the token, reads the identity it carries, and checks whether the IAM policy on the target resource grants that identity the required role - the same authorization model as any other caller.
Service-to-service communication
When an architecture uses multiple Cloud Run services, they often call one another, and private services need credentials.
Give the calling service its own service account with the minimal roles required.
For a synchronous call, make the calling service's service account a principal on the receiving service and grant it the Cloud Run Invoker (roles/run.invoker) role:
The request must prove that identity with a Google-signed OpenID Connect (OIDC) ID token. OIDC is an identity protocol built on OAuth 2.0 that lets one service verify another's identity. The calling service's code acquires the ID token via Google's auth client libraries; the receiving service uses the same libraries to parse the request and verify the token.
Calling a Google API (Pub/Sub, Storage, ...) uses an OAuth 2.0 access token. Invoking another Cloud Run service over HTTP uses a Google-signed OIDC ID token - and the caller still needs roles/run.invoker on the receiving service. Don't mix them up.
Recap
- A Cloud Run service always has access to a default service account.
- Google client libraries use that identity to call Google Cloud APIs.
- The default (Compute Engine) SA has the Editor basic role - broad permissions across all services.
- In production, replace it with a user-managed, per-service account holding only predefined/custom roles on the resources it needs.
- Outbound calls to a Google API use an OAuth 2.0 access token; a synchronous service-to-service call uses a Google-signed OIDC ID token plus
roles/run.invokeron the receiver. - For async service-to-service, use Cloud Tasks, Pub/Sub, Cloud Scheduler, or Eventarc.