This domain (20% in the catalog; Section 5 of the official guide, about 17.5%) is IAM and service accounts. It is the topic where wording matters most: the exam picks the least-privileged option that does the job, and prefers groups, predefined roles, service accounts attached to resources and short-lived credentials over broad roles and downloaded keys.
IAM model
An IAM policy is a list of bindings, each binding a role (a set of permissions) to members (principals), optionally with a condition. A policy is attached to a resource (organization, folder, project or a specific resource such as a bucket) and inherited by all descendants. The effective access is the union of the policy on the resource and on every ancestor; you cannot revoke an inherited grant from below (use a deny policy or remove it at the level where it was granted).
| Principal | Notes |
|---|---|
| Google Account / Cloud Identity user | user:ana@example.com |
| Google Group | group:devs@example.com: grant roles to groups |
| Service account | serviceAccount:sa@proj.iam.gserviceaccount.com for workloads |
| Domain | domain:example.com, every identity in the domain |
allUsers / allAuthenticatedUsers |
Anyone on the internet / anyone with a Google account. Dangerous: public access |
| Workload and workforce identity pool principals | Federated external identities (principalSet://...) |
A permission looks like compute.instances.start (service.resource.verb). You never grant permissions directly; you grant roles.
Viewing and editing policies
gcloud projects get-iam-policy my-proj --format=yaml
gcloud projects add-iam-policy-binding my-proj --member=group:devs@example.com --role=roles/compute.instanceAdmin.v1
gcloud projects remove-iam-policy-binding my-proj --member=group:devs@example.com --role=roles/compute.instanceAdmin.v1
gcloud projects set-iam-policy my-proj policy.yaml # REPLACES the whole policy; edit from get output, keep the etag
gcloud organizations add-iam-policy-binding ORG_ID --member=... --role=...
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID --member=... --role=...
gcloud storage buckets add-iam-policy-binding gs://bucket --member=... --role=roles/storage.objectViewer
gcloud compute instances add-iam-policy-binding web-1 --zone=us-central1-a --member=... --role=roles/compute.osLogin
add-iam-policy-bindingandremove-...change one binding atomically;set-iam-policyoverwrites the entire policy and can lock you out.- The etag in a policy guards concurrent edits (read-modify-write).
- To find who has access or why: Policy Troubleshooter (explains if a principal has a permission on a resource), Policy Analyzer (who can access what) and IAM Recommender (removes unused permissions).
gcloud asset analyze-iam-policy. - Find which role has a permission and what a role contains:
gcloud iam roles describe roles/storage.objectAdmin;gcloud iam list-testable-permissions. - A principal can be granted a role at the resource level (most specific, least privilege) rather than the project; not every resource supports resource-level IAM.
Role types
| Type | Example | Notes |
|---|---|---|
| Basic (primitive) | roles/owner, roles/editor, roles/viewer |
Cover almost every service. Owner also manages roles and billing association. Too broad for production. Editor can change most resources but not IAM |
| Predefined | roles/compute.instanceAdmin.v1, roles/storage.objectViewer, roles/bigquery.dataViewer |
Maintained by Google per service, fine-grained, recommended |
| Custom | projects/P/roles/myRole |
You pick the permissions. Created at organization or project level (not folder). Used by exactly the scope where it’s defined |
Basic role traps: roles/viewer lets you read most things; roles/editor is too much for developers; the Owner role at the organization is exceptionally powerful. Primitive roles give access to all services in the scope, so a small mistake spreads widely.
Custom roles
gcloud iam roles create vmOperator --project=my-proj --title="VM Operator" \
--description="Start and stop VMs" \
--permissions=compute.instances.get,compute.instances.list,compute.instances.start,compute.instances.stop \
--stage=GA
gcloud iam roles create fromFile --organization=ORG_ID --file=role.yaml
gcloud iam roles update vmOperator --project=my-proj --add-permissions=compute.instances.reset
gcloud iam roles update vmOperator --project=my-proj --remove-permissions=compute.instances.reset
gcloud iam roles describe vmOperator --project=my-proj
gcloud iam roles list --project=my-proj
gcloud iam roles delete vmOperator --project=my-proj # soft delete, 7 days to undelete (then permanently gone after 37 days)
gcloud iam roles undelete vmOperator --project=my-proj
- Use a custom role when no predefined role fits the exact permissions (for example “start/stop VMs but not create or delete”).
- Custom roles don’t update automatically when Google adds new permissions to a service; you maintain them. A role has a launch stage (ALPHA, BETA, GA, DEPRECATED, DISABLED).
- Not every permission is supported in custom roles. Up to 3,000 permissions per role; 300 custom roles per org and 300 per project.
- Start from a predefined role:
gcloud iam roles copy --source=roles/x --destination=myRole --dest-project=P. - Common predefined roles to recognise:
compute.admin,compute.instanceAdmin.v1,compute.networkAdmin,compute.securityAdmin,storage.admin,storage.objectAdmin,container.admin,container.developer,cloudsql.admin,cloudsql.client,bigquery.dataEditor,bigquery.jobUser,pubsub.publisher,pubsub.subscriber,logging.viewer,logging.logWriter,monitoring.viewer,iam.serviceAccountUser,iam.serviceAccountTokenCreator,iam.serviceAccountAdmin,resourcemanager.projectIamAdmin,billing.user.
Conditions, deny and boundaries
- IAM Conditions add attribute-based rules to a binding with CEL expressions: time of day or expiry (
request.time < timestamp("2027-01-01T00:00:00Z")), resource name or type, or tags. Use for temporary access (just-in-time).
gcloud projects add-iam-policy-binding my-proj --member=user:ana@example.com --role=roles/compute.admin \
--condition='expression=request.time < timestamp("2026-12-31T00:00:00Z"),title=temp-access'
- IAM deny policies block specific permissions for principals regardless of allow grants and are evaluated before allow. Created at org, folder or project.
- Principal access boundary policies limit which resources a principal can use.
- Privileged Access Manager (PAM) gives temporary, approved elevation.
- Organization policy (see the first domain) limits what can be configured; VPC Service Controls create a perimeter that stops data exfiltration from APIs even with valid IAM.
Best practices the exam rewards
- Least privilege: smallest role at the smallest scope.
- Groups over individual users; manage group membership in the directory.
- Predefined over basic; custom when needed.
- Separation of duties: for example, the person who manages IAM should not also administer the data.
- Service accounts per workload, not shared, with no keys.
- Review with Recommender and audit logs.
- Don’t use owner for automation; don’t grant
roles/ownerto service accounts. - Allow IAM Admin roles sparingly (
roles/resourcemanager.projectIamAdmin,roles/iam.securityAdmin): holding them lets a person grant themselves anything.
Service accounts
A service account (SA) is an identity for an application or VM, not a person. It is both a principal (given roles to access things) and a resource (others get roles on it to use or manage it).
| Type | Details |
|---|---|
| User-managed | You create it: NAME@PROJECT.iam.gserviceaccount.com. Recommended |
| Default service accounts | Compute Engine default (PROJECT_NUMBER-compute@developer.gserviceaccount.com) and App Engine default (PROJECT_ID@appspot.gserviceaccount.com). Historically get the Editor role automatically (too broad); modern orgs disable this by org policy. Avoid for production |
| Google-managed / service agents | Created and used by Google services (for example service-NUM@compute-system.iam.gserviceaccount.com). Don’t delete or edit |
gcloud iam service-accounts create app-sa --display-name="App SA"
gcloud iam service-accounts list
gcloud iam service-accounts describe app-sa@my-proj.iam.gserviceaccount.com
gcloud iam service-accounts disable|enable|delete app-sa@my-proj.iam.gserviceaccount.com
# Give the SA permissions (SA as a principal)
gcloud projects add-iam-policy-binding my-proj \
--member=serviceAccount:app-sa@my-proj.iam.gserviceaccount.com --role=roles/storage.objectViewer
# Give someone permission on the SA (SA as a resource)
gcloud iam service-accounts add-iam-policy-binding app-sa@my-proj.iam.gserviceaccount.com \
--member=user:ana@example.com --role=roles/iam.serviceAccountUser
Roles on a service account as a resource:
| Role | Allows |
|---|---|
roles/iam.serviceAccountUser |
Attach the SA to a resource (for example create a VM that runs as it) and act as it for that purpose (iam.serviceAccounts.actAs) |
roles/iam.serviceAccountTokenCreator |
Impersonate: create access tokens, ID tokens and sign blobs for the SA |
roles/iam.serviceAccountKeyAdmin |
Create and delete keys |
roles/iam.serviceAccountAdmin |
Create and manage service accounts |
roles/iam.workloadIdentityUser |
Let a Kubernetes service account (or external identity) act as the SA |
Common trap: to deploy a VM, Cloud Run service or function that runs as a service account, the deployer needs permission to create the resource and serviceAccountUser (actAs) on that SA. Without it deployment fails with a permission error on iam.serviceAccounts.actAs.
Assigning service accounts to resources
- Compute Engine: choose at creation (
--service-account=... --scopes=cloud-platform), change while stopped (gcloud compute instances set-service-account). Processes on the VM get tokens from the metadata server (http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token, headerMetadata-Flavor: Google); client libraries use Application Default Credentials (ADC) automatically. - Cloud Run / Cloud Run functions:
--service-account=...at deploy. - GKE: node service account per node pool, and Workload Identity Federation for GKE to map a Kubernetes service account to an IAM identity per Pod.
- Access scopes on VMs are a legacy filter on top of IAM. The effective access is the intersection of IAM roles and scopes; the easiest approach is
cloud-platformscope and control access with IAM. - A VM’s SA can be changed only while the VM is stopped; some services (Dataflow, Cloud Build) also take SA parameters.
Authentication options (strongest to weakest)
- Attached service account (no credentials to manage): for code on Google Cloud.
- Impersonation of an SA by a user or another SA for short-lived tokens.
- Workload Identity Federation for workloads outside Google Cloud (AWS, Azure, GitHub Actions, OIDC/SAML).
- Service account keys (JSON files): long-lived, risky; use only if nothing else works, rotate, and block creation with org policy
iam.disableServiceAccountKeyCreationwhere possible.
gcloud iam service-accounts keys create key.json --iam-account=app-sa@my-proj.iam.gserviceaccount.com
gcloud iam service-accounts keys list --iam-account=app-sa@my-proj.iam.gserviceaccount.com
gcloud iam service-accounts keys delete KEY_ID --iam-account=...
gcloud auth activate-service-account --key-file=key.json
gcloud auth application-default login # ADC for local development with your user
Keys are user-managed credentials with up to 10 per service account by default and no expiry unless you set an org policy to expire them.
Impersonation and short-lived credentials
Impersonation lets a principal act as a service account temporarily without a key, as long as it holds roles/iam.serviceAccountTokenCreator on that SA. The caller’s identity is recorded in audit logs.
# Run any gcloud command as the SA (no key, no activate)
gcloud storage ls gs://bucket --impersonate-service-account=app-sa@my-proj.iam.gserviceaccount.com
gcloud config set auth/impersonate_service_account app-sa@my-proj.iam.gserviceaccount.com
# Mint a short-lived access token (default 1 hour, up to 12 hours with org policy)
gcloud auth print-access-token --impersonate-service-account=app-sa@my-proj.iam.gserviceaccount.com
# ID token for calling a private Cloud Run service
gcloud auth print-identity-token --impersonate-service-account=... --audiences=https://api-xyz.a.run.app
| Credential | Lifetime | Use |
|---|---|---|
| OAuth 2.0 access token | Default 1 hour | Call Google APIs |
| ID token (OpenID Connect) | About 1 hour | Authenticate to Cloud Run, IAP, your own services |
| Self-signed JWT | Up to 1 hour | Some APIs, signed with an SA |
| Signed URL / blob | You set (up to 7 days with keys) | Time-limited object access (signBlob via TokenCreator) |
| Service account key | Until deleted | Last resort |
- Delegation chain: SA A impersonates B which impersonates C when each holds TokenCreator on the next.
- Cloud Shell and workstation developers should impersonate instead of downloading keys.
- Service account usage can be checked with Policy Intelligence (service account insights show unused accounts and keys) and cleaned up.
Managing IAM of a service account
- Control who can use (
serviceAccountUser), impersonate (TokenCreator) and administer (serviceAccountAdmin/keyAdmin) the SA; grant them on the SA itself, not the project, to limit blast radius. - A project-level
serviceAccountUserlets the holder act as every SA in the project; this is a classic privilege escalation path. Grant it on specific accounts. - Deleting an SA breaks anything depending on it; it can be undeleted within 30 days (
gcloud iam service-accounts undelete), and the disable action is a safer first step. - Cross-project: SAs can be granted roles in other projects; check the org policy
iam.disableCrossProjectServiceAccountUsagewhich controls attaching an SA from another project.
Other security controls
| Control | Use |
|---|---|
| Cloud KMS | Create and manage encryption keys (symmetric, asymmetric), key rings, rotation. CMEK for storage, disks, BigQuery and others. gcloud kms keyrings create, gcloud kms keys create --purpose=encryption --rotation-period=90d |
| Secret Manager | Store API keys and passwords with versions and IAM (roles/secretmanager.secretAccessor). Reference from Cloud Run (--set-secrets), GKE and functions. Don’t put secrets in code, env vars in plain text or metadata |
| Identity-Aware Proxy (IAP) | Authenticates users in front of apps and VMs by identity and context, replacing a VPN; roles/iap.httpsResourceAccessor, iap.tunnelResourceAccessor |
| Cloud Armor | WAF and DDoS protection on external Application LBs, with IP allow/deny and preconfigured rules |
| VPC Service Controls | Perimeter around Google APIs to limit data exfiltration |
| Shielded VMs, Confidential VMs | Verified boot, vTPM; memory encryption |
| Security Command Center | Posture, vulnerability and threat findings across the organization |
| Cloud Audit Logs | Who did what; see the operation notes |
| Binary Authorization | Only signed, attested images deploy to GKE or Cloud Run |
| Encryption at rest | All data is encrypted at rest by default (Google-managed keys), and in transit |
Exam checklist
- IAM binding = role + member + optional condition. Inheritance is additive;
set-iam-policyreplaces the whole policy,add-iam-policy-bindingadds one binding. - Predefined roles for least privilege; custom roles when nothing fits (org or project level, you maintain permissions); basic roles are too broad for production.
- Grant to groups. Never grant
allUsersunless intended to be public. - Conditions give temporary or attribute-based access; deny policies override allows.
- Service accounts are principals and resources.
serviceAccountUser= attach/act as;serviceAccountTokenCreator= impersonate and mint tokens; both are needed in different situations. - Prefer attached service accounts, then impersonation or Workload Identity Federation, over JSON keys.
- Avoid the default Compute Engine service account with Editor; use a dedicated SA with only needed roles.
- Short-lived access tokens last 1 hour by default; use
--impersonate-service-account. - A VM’s service account can only be changed while it is stopped; VM code gets credentials from the metadata server and ADC.
- Policy Troubleshooter explains why access works or fails; Recommender trims excess roles.