A service account is an identity for code, not for a person. It is both a principal (it can be granted roles) and a resource (people can be granted roles on it).
flowchart LR D["Developer alice"] -- "Token Creator" --> SA["Service account<br/>deployer-sa"] VM["VM web-1"] -- "attached" --> SA2["Service account<br/>web-sa"] SA2 --> GCS["Cloud Storage bucket"] SA --> RUN["Cloud Run deploy"] %% step D: Alice has roles/iam.serviceAccountTokenCreator on deployer-sa, so she can impersonate it. %% step SA: Impersonation returns a short-lived token (1 hour by default); no key file is downloaded. %% step RUN: With that token, gcloud deploys to Cloud Run with only the deployer’s roles. %% step VM: A VM runs as its attached service account and gets tokens from the metadata server. %% step SA2: web-sa has only roles/storage.objectViewer on one bucket. %% step GCS: Code on the VM reads the bucket without any secret in its configuration.
Three kinds
| Kind | Example | Notes |
|---|---|---|
| User-managed | web-sa@dl-lab-dev.iam.gserviceaccount.com |
You create it, you grant it roles |
| Default | PROJECT_NUMBER-compute@developer.gserviceaccount.com |
Created when you enable some APIs; may get Editor automatically in older setups. Do not use it for production workloads |
| Service agents | service-PROJECT_NUMBER@gcp-sa-run.iam.gserviceaccount.com |
Google-managed, used by a service to act in your project |
Attaching a service account
When you create a VM, Cloud Run service or GKE workload, you choose the service account it runs as. Code then uses Application Default Credentials and gets short-lived tokens automatically. To attach a service account you need iam.serviceAccounts.actAs, usually from Service Account User (roles/iam.serviceAccountUser) on that service account.
Impersonation instead of keys
gcloud iam service-accounts add-iam-policy-binding deployer-sa@dl-lab-dev.iam.gserviceaccount.com --member="user:alice@example.com" --role="roles/iam.serviceAccountTokenCreator"
gcloud run deploy web --image=… --impersonate-service-account=deployer-sa@dl-lab-dev.iam.gserviceaccount.com
Impersonation produces tokens that expire (one hour by default) and every use is in the audit logs.
Keys: the last resort
A service account key is a long-lived private key in a JSON file. If it leaks, anyone can use it until it is deleted. Many organizations enforce the org policy iam.disableServiceAccountKeyCreation (enforced by default for new organizations). Alternatives:
- Code on Google Cloud → attached service account.
- Code on GitHub, AWS, Azure, on-premises → Workload Identity Federation (next lesson).
- People → impersonation.
| Role | What it allows |
|---|---|
roles/iam.serviceAccountUser |
Attach the SA to resources (actAs) |
roles/iam.serviceAccountTokenCreator |
Create tokens for the SA (impersonate) |
roles/iam.serviceAccountAdmin |
Create and manage SAs |
| Command | Meaning |
|---|---|
gcloud iam service-accounts create web-sa --display-name="Web app" |
Create |
gcloud iam service-accounts list |
List in the project |
gcloud compute instances create web-1 --service-account=web-sa@… --scopes=cloud-platform |
Attach to a VM |
Traps: Service Account User on a project lets someone act as every SA in it; deleting and recreating an SA with the same name does not restore its old bindings; access scopes on VMs are a legacy limit, IAM roles are what matter.