Last updated: April 29, 2026
Why this module exists. Every Indian SaaS that adopted GCP after 2022 inherited an IAM model fundamentally different from AWS. The pieces look similar — IAM, service accounts, roles — but the wiring is different and the attack paths are different. If you bring AWS muscle memory to GCP, you’ll either over-permission everything or miss the GCP-specific privilege-escalation paths.
How GCP IAM differs from AWS IAM
| AWS | GCP | |
|---|---|---|
| Identity primitive | IAM user, IAM role | Google account, service account |
| Permission model | Identity-based + resource-based policies | IAM policy bound to a resource (project/folder/org) |
| Cross-account / cross-project access | Trust policies + assume-role | Direct grants — add a member to a project’s IAM |
| Inheritance | None at the account level | Org → Folder → Project → Resource (top inherits down) |
| Workload identity | IAM role for service / IRSA | Workload Identity / WIF — federated tokens |
The GCP role hierarchy
Three role types:
- Basic roles — Owner, Editor, Viewer. Project-wide. Wildly over-permissioned. Avoid in production.
- Predefined roles — granular per-service (e.g.,
roles/storage.objectViewer). Use these. - Custom roles — pick exactly the permissions you need. Most secure; most operational overhead.
Service accounts — where most breaches live
A service account is both an identity and a resource. You grant roles to it (so it can do things), and you grant roles on it (so principals can use it).
The “use it” roles matter:
roles/iam.serviceAccountUser— attach this SA to a VM, GKE pod, Cloud Run service.roles/iam.serviceAccountTokenCreator— generate access tokens AS this SA. This is the privilege-escalation primitive.roles/iam.serviceAccountKeyAdmin— create persistent JSON keys. Long-lived credentials.
The classic GCP privilege-escalation chain
- Attacker compromises a low-priv user with
roles/iam.serviceAccountTokenCreatoron some service account. - That service account has
roles/owneron the project (common: an old “deploy bot” SA created in haste). - Attacker generates an access token AS the SA:
gcloud auth print-access-token --impersonate-service-account=deploy-bot@proj.iam.gserviceaccount.com - Now operating as Owner. Game over.
Defender’s question: which low-priv users have iam.serviceAccountTokenCreator on which highly-privileged service accounts? Almost no enterprise has audited this.
Workload Identity Federation — the modern pattern
WIF lets external identities (GitHub Actions, AWS roles, OIDC providers) impersonate GCP service accounts without long-lived keys. The flow:
- External system (GitHub Actions runner) has an OIDC token.
- It exchanges the OIDC token at GCP’s STS for a short-lived GCP access token.
- The token impersonates a designated service account scoped to specific permissions.
Benefit: no JSON keys in CI, no rotation pain, scope tied to the OIDC claim (repository:owner/repo).
Risk: misconfigured WIF accepts overly broad OIDC claims. attribute_condition: assertion.repository_owner == 'mycompany' means any repo in the org can impersonate. attribute_condition: assertion.repository == 'mycompany/specific-repo' is what you actually want.
Try this yourself
# Audit who can impersonate what (run as a GCP admin)
gcloud asset search-iam-policy --scope=projects/MY-PROJECT
--query="policy:iam.serviceAccountTokenCreator"
# What roles does each SA have on the project?
gcloud projects get-iam-policy MY-PROJECT --format=json |
jq '.bindings[] | select(.members[] | startswith("serviceAccount:"))'
# Try impersonation
gcloud auth print-access-token
--impersonate-service-account=target-sa@MY-PROJECT.iam.gserviceaccount.com
# Use it
TOKEN=$(gcloud auth print-access-token --impersonate-service-account=...)
curl -H "Authorization: Bearer $TOKEN"
https://storage.googleapis.com/storage/v1/b/MY-BUCKET
Defender’s checklist
- Eliminate basic roles. Especially Owner and Editor at project level. Replace with predefined or custom roles.
- Disable service account key creation via Org Policy:
iam.disableServiceAccountKeyCreation. Use WIF instead. - Audit serviceAccountTokenCreator across all SAs. Each grant is a privilege-escalation pivot.
- WIF attribute conditions — pin to specific repos, branches, IdP subjects. Never blanket “trust this OIDC issuer.”
- Detection: Cloud Audit Logs
generateAccessTokenentries — alert on impersonation chains where the principal isn’t expected. - Org-level constraints: use Organization Policy Service to enforce boundaries that no project admin can override.
Module Quiz · 6 questions
Pass with 80%+ to mark this module complete. Unlimited retries. Each question shows an explanation.
Custom team training + practitioner advisory
Beyond the free academy — we run private workshops, vCISO advisory, and red-team exercises tailored to your stack. For Indian SMBs scaling past their first hire.