Service accounts

Google Cloud · Essentials · 11 min

Every VM, Cloud Run service and pipeline calls Google APIs as some service account; least privilege starts here.

A service account is an identity for software, not a person. Its email looks like app-sa@PROJECT_ID.iam.gserviceaccount.com. Like users, it receives IAM roles; unlike users, it has no password.

The safe way to use one is to attach it to a resource: a VM, a Cloud Run service, a function, a GKE workload, a Cloud Build trigger. Code running there gets short-lived tokens automatically from the metadata server; no secret ever touches disk.

Two separate permission questions:

  • What can the service account do? Grant roles to it (e.g. roles/pubsub.publisher on a topic).
  • Who may use it? To attach a service account to a resource you need roles/iam.serviceAccountUser on that service account. This stops someone who can deploy from borrowing a powerful identity.

Google also creates default service accounts (e.g. the Compute Engine default PROJECT_NUMBER-compute@developer.gserviceaccount.com), and service agents that Google services use internally. Prefer a dedicated, minimal service account per workload over the defaults.

Service account keys (JSON files) are long-lived credentials that leak easily. Avoid them: use attached accounts inside Google Cloud, impersonation for humans, and Workload Identity Federation for workloads outside. Many organizations block key creation with an org policy.

Example

PROJECT=shop-dev-4821
gcloud iam service-accounts create orders-api --display-name="Orders API"
SA=orders-api@$PROJECT.iam.gserviceaccount.com

# What the workload may do: publish to one topic
gcloud pubsub topics add-iam-policy-binding orders \
  --member="serviceAccount:$SA" --role="roles/pubsub.publisher"

# Who may deploy things that run as it
gcloud iam service-accounts add-iam-policy-binding $SA \
  --member="group:orders-devs@example.com" --role="roles/iam.serviceAccountUser"

# Attach it to a Cloud Run service
gcloud run deploy orders-api --image=us-docker.pkg.dev/cloudrun/container/hello \
  --region=europe-west1 --service-account=$SA

Remember

  • Attach service accounts to resources instead of using key files
  • One minimal service account per workload
  • serviceAccountUser on the SA controls who can run code as it

Watch out for

  • Downloading a JSON key to test locally and committing it to Git.
  • Leaving workloads on the default compute service account with broad roles.

Check yourself

  1. Bob can deploy Cloud Run services but gets a permission error when setting --service-account=admin-sa. What is missing?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: cloud.google.com/iam/docs/service-account-overview