Topic 2 of 3
Exam section 4.2 covers managing service accounts: creating them, giving them minimal permissions, attaching them to resources, controlling who can use them, and avoiding keys. Impersonation and Workload Identity Federation are in the next article.
Contents
A special account used by an application or workload, not a person. It's identified by its email, in the format NAME@PROJECT_ID.iam.gserviceaccount.com. The most common approach is to attach it to the resource that runs the app (for example, a VM): the code gets short-lived credentials automatically through Application Default Credentials.
| Type | Detail |
|---|---|
| User-managed | You create and manage them. These are the ones used as workload identities |
| Default | User-managed but created automatically when you enable certain services: Compute Engine (PROJECT_NUMBER-compute@developer.gserviceaccount.com) and App Engine (PROJECT_ID@appspot.gserviceaccount.com). Managing them is your responsibility |
| Service agents | Created and managed by Google so a service can act on your behalf. They aren't in your project and you don't use them directly. On the IAM page, check Include Google-provided role grants to see them |
The Compute Engine default service account
It's attached by default to VMs created with the console or gcloud and, depending on organization policy, can receive the Editor role on the project. Google strongly recommends enforcing the iam.automaticIamGrantsForDefaultServiceAccounts constraint (enforced by default in organizations created on or after May 3, 2024) and replacing Editor with less permissive roles, using Policy Simulator to check the impact.
As a principal
You grant it roles on resources, like any principal: serviceAccount:SA_EMAIL. You can also use principal sets for all service accounts in a project, folder, or organization.
As a resource
It has its own allow policy, which decides who can use, impersonate, or manage it. Anyone who can act as it can access everything it can access.
# The account as a principal: it can read objects in the bucket gcloud storage buckets add-iam-policy-binding gs://app-data \ --member=serviceAccount:app-sa@my-project.iam.gserviceaccount.com \ --role=roles/storage.objectViewer # The account as a resource: a user can attach it to resources gcloud iam service-accounts add-iam-policy-binding \ app-sa@my-project.iam.gserviceaccount.com \ --member=user:dev@example.com --role=roles/iam.serviceAccountUser
| Role | What it allows |
|---|---|
Service Account Userroles/iam.serviceAccountUser | Attach the account to resources (VMs, Cloud Run services…). Includes iam.serviceAccounts.actAs |
Service Account Token Creatorroles/iam.serviceAccountTokenCreator | Impersonate the account: create short-lived tokens on its behalf |
Service Account Adminroles/iam.serviceAccountAdmin | View, edit, disable, and delete the service account |
Create Service Accountsroles/iam.serviceAccountCreator | Create service accounts |
Google recommends granting these roles on the specific service account, not on the project or folder: Token Creator on the project would let someone impersonate every account in it.
gcloud iam service-accounts create app-sa \ --description="Orders API" --display-name="orders-api" gcloud iam service-accounts disable app-sa@my-project.iam.gserviceaccount.com gcloud iam service-accounts enable app-sa@my-project.iam.gserviceaccount.com gcloud iam service-accounts delete app-sa@my-project.iam.gserviceaccount.com gcloud beta iam service-accounts undelete ACCOUNT_ID
iam.disableServiceAccountCreation constraint prevents creating service accounts in an organization, folder, or project.Google recommends creating a user-managed account with only the roles it needs and attaching it to the VM. A VM can have only one account. To change it, the VM must be stopped.
gcloud compute instances stop app-vm --zone=europe-west1-b gcloud compute instances set-service-account app-vm --zone=europe-west1-b \ --service-account=app-sa@my-project.iam.gserviceaccount.com \ --scopes=cloud-platform gcloud compute instances start app-vm --zone=europe-west1-b
Access scopes
They are the legacy authorization method for a VM. Actual access is limited by both the account's roles and the scopes. The default scopes give, among others, read-only access to Cloud Storage and write access for logs and metrics. The recommended practice is to set the full cloud-platform scope and control access with IAM roles.
To attach an account from another project, the iam.disableCrossProjectServiceAccountUsage constraint must not be enforced in the account's project.
A key lets anyone authenticate as the account from anywhere, so it's a security risk if not managed correctly. Google says to choose a more secure alternative whenever possible.
gcloud iam service-accounts keys create key.json \ --iam-account=app-sa@my-project.iam.gserviceaccount.com gcloud iam service-accounts keys delete KEY_ID \ --iam-account=app-sa@my-project.iam.gserviceaccount.com
iam.disableServiceAccountKeyCreation blocks key creation; it's enforced by default in organizations created on or after May 3, 2024.DISABLE_KEY, Google automatically disables leaked keys it detects.| Where the code runs | Recommended method |
|---|---|
| Your workstation or Cloud Shell | Your user credentials, or impersonate a service account if you need one |
| Google Cloud (VM, Cloud Run…) | Attach a service account to the resource |
| GKE | Workload Identity Federation for GKE |
| On-premises or another cloud with a supported IdP | Workload Identity Federation |
| None of the above | Service account key (last resort) |
| Situation | Answer | Why |
|---|---|---|
| An app on a VM must read objects from a bucket | A dedicated service account with roles/storage.objectViewer attached to the VM | Least privilege; no keys. |
| A developer must be able to create VMs that use a specific service account | roles/iam.serviceAccountUser on that service account | Includes iam.serviceAccounts.actAs. |
| Change the service account of an existing VM | Stop the VM and use gcloud compute instances set-service-account | Only one account per VM. |
| The Compute Engine default service account has Editor | Replace Editor with minimal roles and enforce iam.automaticIamGrantsForDefaultServiceAccounts | Strongly recommended by Google. |
| Retire a service account that looks unused | Disable it first and delete it once confirmed | A disabled account can be re-enabled. |
| You deleted a service account by mistake 10 days ago | Recover it with undelete | Up to 30 days; recreating it with the same name doesn't restore its permissions. |
| Prevent service account key creation across the organization | iam.disableServiceAccountKeyCreation constraint | Enforced by default in organizations created on or after May 3, 2024. |
| A GKE pod must call Google APIs | Workload Identity Federation for GKE | No keys needed. |
❓ Service Account User or Token Creator to let someone attach an account to a VM?
Service Account User (actAs). Token Creator is for impersonating it and getting tokens.
❓ Can you change the service account of a running VM?
No. Stop it, run set-service-account, and start it again.
❓ Does recreating a deleted account with the same email restore its permissions?
No. It has a different unique ID and the old bindings don't apply. Use undelete within 30 days.
❓ Are access scopes enough to restrict what a VM can do?
They are the legacy method. Google recommends the cloud-platform scope and controlling access with IAM roles.
❓ Do service account keys expire on their own?
Not by default. You must rotate or delete them; better to avoid them.
❓ Can you move a service account to another project?
No. To use it from another project, attach it across projects or impersonate it.
Did you get this topic?
Test what you just learned
An app on Compute Engine must publish messages to a Pub/Sub topic. It currently uses the Compute Engine default service account, which has the Editor role. What is the most secure option?