Service Accounts, Impersonation, and Workload Identity Federation
A service account is the identity your workloads use to call Google Cloud APIs — a special principal with an email like name@project.iam.gserviceaccount.com that holds IAM roles just as a user does, but authenticates as software instead of a person. Managing them well means four things: creating user-managed service accounts (and recognizing the Google-managed ones you do not control), granting each one the minimum roles its job requires, attaching them to resources such as Compute Engine VMs, GKE workloads, and Cloud Run services so code gets credentials automatically, and — above all — avoiding downloadable service account keys in favor of keyless alternatives: impersonation with short-lived credentials, Workload Identity for GKE, and Workload Identity Federation for workloads running outside Google Cloud entirely. This lesson covers the full lifecycle with gcloud commands, the dual resource-and-principal nature of service accounts, and a comparison table of every authentication option the exam expects you to rank.
On this page8 sections
- What service accounts are — and the three kinds you will meet
- Creating service accounts and granting minimum permissions
- Attaching service accounts to resources
- Managing the IAM permissions of a service account itself
- Why service account keys are dangerous
- Impersonation and short-lived credentials
- Workload Identity: service accounts for GKE applications
- Workload Identity Federation and the authentication options compared
- Distinguish Google-managed service agents, default service accounts, and user-managed service accounts
- Create service accounts with gcloud and grant them least-privilege roles in IAM policies
- Attach service accounts to Compute Engine VMs, Cloud Run services, and GKE workloads
- Manage the IAM policy of a service account itself, including serviceAccountUser and serviceAccountTokenCreator
- Configure impersonation and generate short-lived credentials instead of creating service account keys
- Set up Workload Identity for GKE applications and Workload Identity Federation for external workloads
What service accounts are — and the three kinds you will meet
A service account is a non-human identity that applications, VMs, and pipelines use to authenticate to Google Cloud APIs. It is a principal like any other — you bind roles to it with serviceAccount:EMAIL members — but it belongs to a project, is identified by an email address, and never signs in with a password. Three kinds appear in every project, and the exam expects you to tell them apart.
Google-managed service accounts (service agents) are created and controlled entirely by Google so that Google services can act inside your project — for example, the agents that Cloud Build or GKE use behind the scenes. You do not create them, you cannot delete them, and their credentials are never exposed to you; at most you will see role grants for them appear when you enable APIs. Leave them alone unless a service's documentation tells you to adjust their roles.
Default service accounts are created automatically in your project when you enable certain services — the best-known is the Compute Engine default service account, which new VMs attach when you specify nothing. They are technically user-managed (they live in your project and you can edit their grants), but historically they have come with over-broad access: the Compute Engine default service account has traditionally been granted the project-wide Editor basic role. That combination — attached by default, broadly privileged — is exactly what least privilege forbids, which is why best practice is to stop using them for real workloads.
User-managed service accounts are the ones you create deliberately, one per workload, with an email of the form NAME@PROJECT_ID.iam.gserviceaccount.com. These are the accounts the rest of this lesson is about: you decide their roles, what resources carry them, and who may act as them.
Creating service accounts and granting minimum permissions
Create a service account with gcloud iam service-accounts create app-backend --display-name=Backend-API; the account's email becomes app-backend@PROJECT_ID.iam.gserviceaccount.com. List accounts with gcloud iam service-accounts list, and disable one without deleting it using gcloud iam service-accounts disable — the safe first step when retiring an account, because a disabled account can be re-enabled if something breaks, while deletion can leave dangling bindings and is disruptive to undo.
Granting the account access works exactly like granting a user: bind a role with the service account as the member. gcloud projects add-iam-policy-binding PROJECT_ID --member=serviceAccount:app-backend@PROJECT_ID.iam.gserviceaccount.com --role=roles/pubsub.publisher lets the workload publish to Pub/Sub topics in the project. The least-privilege discipline is the same as for humans, but stricter in practice because workloads are predictable: an application that publishes to one topic and writes to one bucket needs roles/pubsub.publisher scoped as narrowly as possible and roles/storage.objectCreator on that bucket — bind at the topic and bucket level rather than the project when the services support resource-level policies. Never hand a workload Editor because enumerating its needs feels tedious; the enumeration is the security work.
Plan for one service account per workload, not one shared account for everything. Separate accounts keep blast radius small (a compromised frontend cannot suddenly read the billing exports), make audit logs attributable — Cloud Audit Logs record which service account performed each action — and let you revoke one workload's access without touching the others. A scenario that describes several applications sharing a single powerful service account is describing the problem, and splitting it per workload is the answer.
Attaching service accounts to resources
Attaching a service account to a resource is what gives the code running there credentials without any secret in your code. The attached account becomes the resource's identity: the metadata infrastructure issues short-lived access tokens for it on demand, client libraries pick them up automatically through Application Default Credentials, and nothing sensitive is ever written to disk.
On Compute Engine, attach at creation with gcloud compute instances create web-1 --service-account=app-backend@PROJECT_ID.iam.gserviceaccount.com --scopes=cloud-platform. The --scopes flag is the legacy access-scope mechanism from before IAM matured; the modern pattern is to set the broad cloud-platform scope and let IAM roles do the actual limiting, because scopes cap what a token can do per-VM while IAM governs what the account can do at all — effective access is the intersection of the two. Changing a VM's attached service account requires the VM to be stopped first. To attach an account, the caller must hold roles/iam.serviceAccountUser on that service account — the control that stops any VM admin from grabbing a privileged identity.
On Cloud Run, set the service identity per revision with gcloud run deploy my-service --service-account=app-backend@PROJECT_ID.iam.gserviceaccount.com; on Cloud Run functions the equivalent flag exists at deploy time. On GKE, you do not attach your workload's service account to nodes: the node pool has a node service account for the cluster's own operations (pulling images, writing logs), and giving it your application's powers would share them with every pod on the node. Per-workload identity on GKE goes through Workload Identity, covered in its own section below.
Managing the IAM permissions of a service account itself
A service account is unique in being both a principal and a resource, and keeping the two directions straight resolves half the confusing exam options. As a principal, the account appears as a serviceAccount: member in other resources' policies — that is what the account can do. As a resource, the account has its own IAM policy saying who can use, impersonate, or administer it — that is what can be done to the account. View the latter with gcloud iam service-accounts get-iam-policy EMAIL and edit it with gcloud iam service-accounts add-iam-policy-binding EMAIL --member=user:alice@example.com --role=roles/iam.serviceAccountUser.
Four roles on the service-account resource matter:
roles/iam.serviceAccountUser— permits acting as the account, most importantly attaching it to resources like VMs and Cloud Run services.roles/iam.serviceAccountTokenCreator— permits impersonation: minting short-lived access tokens and signing as the account.roles/iam.serviceAccountAdmin— permits managing the account itself: create, update, disable, delete, and editing its IAM policy.roles/iam.serviceAccountKeyAdmin— permits creating and deleting the account's keys, the capability you want to grant to almost nobody.
These roles follow normal IAM placement rules: grant them on the individual service account for least privilege, because granting serviceAccountUser at the project level lets the holder act as every service account in the project. Watch for privilege escalation in scenarios: a user with only roles/compute.instanceAdmin.v1 plus serviceAccountUser on a privileged account can launch a VM as that account and inherit all its powers. Whoever can act as an identity effectively holds that identity's access — grant these meta-roles as carefully as the roles they unlock.
Why service account keys are dangerous
A service account key is a downloadable JSON credential containing a private key that authenticates as the account from anywhere. It is the mechanism of last resort, and the exam wants you to treat it that way, because keys concentrate every classic secret-management failure: they are long-lived — a user-managed key never expires and stays valid until you delete it; they are bearer credentials — anyone holding the file is the service account, from any machine on the internet; they are easily leaked — committed to repositories, baked into container images, left in home directories and CI logs; and they are invisible in use — nothing distinguishes the legitimate holder from a thief until you study audit logs for anomalous behavior.
If you truly must create one — typically for third-party software that only accepts a key file — the commands are gcloud iam service-accounts keys create key.json --iam-account=EMAIL to mint, gcloud iam service-accounts keys list --iam-account=EMAIL to audit, and gcloud iam service-accounts keys delete to revoke. Deleting the key immediately invalidates it, which is the incident response for a leaked key; rotation means creating a new key, migrating the consumer, then deleting the old one. Creation rights are controlled by roles/iam.serviceAccountKeyAdmin, which should be granted rarely and narrowly.
Organizations enforce avoidance rather than trusting discipline: the organization policy constraint constraints/iam.disableServiceAccountKeyCreation blocks key creation outright across the organization, a folder, or a project, with exceptions granted only where a vendor genuinely requires a key. The decision rule to carry into the exam: workloads on Google Cloud need no keys because attached service accounts provide tokens automatically; humans and workloads that can reach IAM APIs use impersonation; external workloads use Workload Identity Federation. A key is only justified when none of those paths exist.
Impersonation and short-lived credentials
Service account impersonation lets an authenticated principal temporarily obtain credentials as a service account without any key existing. The caller must hold roles/iam.serviceAccountTokenCreator on the target account; they then ask the Service Account Credentials API to mint a short-lived credential for it — most commonly an OAuth 2.0 access token, with signed JWTs and OpenID Connect ID tokens available for service-to-service and identity-assertion use cases. Tokens are valid for one hour by default (extendable lifetimes exist but require an organization policy opt-in), and they cannot be revoked-in-place like a key because they simply expire — the security model is that stolen credentials die in minutes, not months.
In gcloud, impersonation is a flag: gcloud compute instances list --impersonate-service-account=deployer@PROJECT_ID.iam.gserviceaccount.com runs one command as the account, and gcloud config set auth/impersonate_service_account EMAIL makes it the session default. You can mint a raw token with gcloud auth print-access-token --impersonate-service-account=EMAIL for tools that take a bearer token. Client libraries support impersonated credentials natively, so applications can use the same pattern without shelling out to gcloud.
A concrete scenario shows why this replaces keys: your operations engineers occasionally need to run Terraform against production with the powers of deployer@prod-project. The key-based design downloads a JSON key to each engineer's laptop — five long-lived copies of production power waiting to leak. The impersonation design grants the ops@example.com group serviceAccountTokenCreator on that one service account: engineers authenticate as themselves, mint hour-long tokens on demand, every mint and every action is attributed in Cloud Audit Logs to the human who impersonated, and offboarding an engineer is a group-membership removal. Same power, no standing secret. Impersonation also enables safe delegation chains — a low-privilege automation account impersonating a higher-privilege one only for the step that needs it.
Workload Identity: service accounts for GKE applications
Workload Identity is the supported way for a GKE application to act as a service account without keys. The problem it solves: pods need Google Cloud access, but the node's service account is shared by every pod on the node (no per-workload identity), and mounting key files into pods revives every danger from the keys section. Workload Identity instead lets a Kubernetes service account (KSA) — the in-cluster identity a pod runs as — exchange its Kubernetes-issued token for Google Cloud credentials, scoped to that workload alone.
Setup is a chain of four links. First, enable Workload Identity on the cluster, which gives the cluster an identity pool named PROJECT_ID.svc.id.goog. Second, create the Kubernetes service account and the Google service account that will carry the IAM roles. Third, allow the KSA to act as the Google service account by granting roles/iam.workloadIdentityUser on it to the member serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME] — note the bracketed namespace/name pair identifying exactly one KSA. Fourth, annotate the KSA with iam.gke.io/gcp-service-account set to the Google service account's email, and set the pod spec to use that KSA. From then on, Application Default Credentials inside the pod transparently produce short-lived tokens for the Google service account; the application code is identical to code running on a VM.
The result matches every best practice at once: no keys exist, credentials are short-lived and issued per pod, each workload gets exactly its own identity and roles, and audit logs attribute actions to the right application. When a question describes a GKE app that needs to reach Cloud Storage or Pub/Sub and offers key files, node service account grants, or Workload Identity as options — Workload Identity is the answer, and the workloadIdentityUser binding plus the KSA annotation are the implementation details worth memorizing.
Workload Identity Federation and the authentication options compared
Workload Identity Federation extends the keyless model to workloads running outside Google Cloud — CI/CD pipelines, on-premises services, or applications on another cloud platform. Instead of exporting a key to the external environment, you configure Google Cloud to trust the tokens that environment already issues. You create a workload identity pool (gcloud iam workload-identity-pools create), add a provider to it describing the external OpenID Connect or SAML token issuer, and define attribute mappings and conditions that translate and filter the external token's claims — so trust can be limited to, say, one specific repository or one external account rather than anything the issuer signs. The external workload then exchanges its own token for short-lived Google Cloud credentials through the Security Token Service, either used directly as a federated identity granted roles via principalSet:// members or by impersonating a service account you designate.
With federation in place, every authentication option has a keyless story, and ranking them is a straight exam skill:
| Option | Where the workload runs | Credential lifetime | Standing secret? | Use when |
|---|---|---|---|---|
| Attached service account | On Google Cloud (Compute Engine, Cloud Run) | Short-lived tokens, auto-refreshed | No | Always, for workloads on Google Cloud compute |
| Workload Identity (GKE) | GKE pods | Short-lived, per-workload | No | Any GKE application needing Google Cloud APIs |
| Impersonation / short-lived credentials | Anywhere the caller already has a Google identity | One hour by default | No | Humans and automation temporarily acting as a service account |
| Workload Identity Federation | Outside Google Cloud (other clouds, CI/CD, on-premises) | Short-lived, exchanged per run | No | External workloads with an OIDC or SAML identity provider |
| Service account keys | Anywhere | Unlimited — valid until deleted | Yes | Last resort only, when no federation or impersonation path exists |
Scenario to cement it: your CI/CD system, hosted outside Google Cloud, must deploy to Cloud Run on every merge. The legacy answer was a service account key stored in the CI system's secret store — a long-lived production credential sitting in a third-party platform. The federated answer creates a pool and an OIDC provider for the CI platform's token issuer, maps claims so only your specific project's pipeline qualifies, and lets the pipeline impersonate the deployer service account for minutes at a time. Do not confuse this with Workforce Identity Federation, its sibling for human users — Workload Identity Federation is for software.
Tip. Expect ranking questions where service account keys are the wrong answer and the correct option is an attached service account, impersonation, Workload Identity, or Workload Identity Federation depending on where the workload runs. Know the exact roles by name — serviceAccountUser versus serviceAccountTokenCreator is a classic discriminator — and the GKE Workload Identity chain (pool, workloadIdentityUser binding with the bracketed KSA member, annotation). Scenarios also probe least privilege: one account per workload, resource-level bindings, and why the Compute Engine default service account should not run production workloads.
- Service accounts come in three kinds: Google-managed service agents (hands off), auto-created default service accounts (historically over-privileged — avoid for workloads), and user-managed accounts you create per workload
- Grant service accounts minimum roles exactly like users — one account per workload, resource-level bindings where possible, never Editor for convenience
- Attaching a service account to a VM, Cloud Run service, or GKE workload delivers auto-refreshed short-lived tokens with no secret in your code; attaching requires serviceAccountUser on the account
- A service account is both a principal (its roles on other resources) and a resource (its own IAM policy controlling who can use, impersonate, or administer it)
- serviceAccountUser lets a principal attach and act as the account; serviceAccountTokenCreator lets them impersonate it — both are escalation paths, so grant them per-account, not project-wide
- Service account keys never expire, travel anywhere, and leak easily — block them with constraints/iam.disableServiceAccountKeyCreation and treat creation as a last resort
- Impersonation mints one-hour credentials on demand with full audit attribution — the keyless replacement for handing humans key files
- Workload Identity links a Kubernetes service account to a Google service account via a workloadIdentityUser binding and a KSA annotation; Workload Identity Federation does the same trust exchange for workloads outside Google Cloud
Frequently asked questions
What is the difference between Google-managed and user-managed service accounts?
Google-managed service accounts (service agents) are created and controlled by Google so its services can operate inside your project — you cannot create, delete, or hold their credentials. User-managed service accounts are the ones you create with gcloud iam service-accounts create, plus the auto-created default service accounts like the Compute Engine default. You control user-managed accounts entirely: their roles, their attachments, and their keys if any exist.
Why are service account keys considered a security risk?
A key is a downloadable JSON file containing a private key that authenticates as the service account from any machine, and user-managed keys never expire — they stay valid until explicitly deleted. They leak through repositories, container images, and CI logs, and a stolen key is indistinguishable from legitimate use. Best practice is to block creation with the organization policy constraint iam.disableServiceAccountKeyCreation and use attached service accounts, impersonation, Workload Identity, or Workload Identity Federation instead.
What role do I need to impersonate a service account?
roles/iam.serviceAccountTokenCreator on the target service account. It allows minting short-lived access tokens, ID tokens, and signed JWTs as that account — for example with gcloud --impersonate-service-account or gcloud auth print-access-token. Grant it on the individual service account rather than the project, because a project-level grant allows impersonating every service account in the project. Note that roles/iam.serviceAccountUser is different: it permits attaching and acting as the account, such as deploying a VM with it.
How does Workload Identity work in GKE?
Workload Identity lets a pod's Kubernetes service account exchange its cluster-issued token for short-lived Google Cloud credentials of a Google service account — no key files. You enable it on the cluster (creating the PROJECT_ID.svc.id.goog pool), grant the KSA the roles/iam.workloadIdentityUser binding on the Google service account using the member format serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME], and annotate the KSA with the Google service account's email. Pods using that KSA then authenticate automatically via Application Default Credentials.
When should I use Workload Identity Federation instead of a service account key?
Whenever a workload outside Google Cloud — a CI/CD pipeline, an on-premises service, or an application on another cloud — has an identity provider that issues OIDC or SAML tokens. Federation configures a workload identity pool and provider that trust those tokens, with attribute mappings and conditions restricting exactly which external identities qualify, and the workload exchanges its token for short-lived Google Cloud credentials. Since the external platform already proves the workload's identity, no long-lived key ever needs to leave Google Cloud.
Can I restrict who is allowed to attach a service account to a VM?
Yes — attaching a service account to a resource requires the caller to hold roles/iam.serviceAccountUser on that specific service account, in addition to permission to create the resource itself. This is the guard against privilege escalation: without it, anyone who could create VMs could launch one as your most privileged service account and inherit its access. Grant serviceAccountUser on individual accounts to exactly the principals who deploy with them, and avoid project-level grants of it.
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.