Google Cloud's defining design choice was a strict hierarchy: every resource belongs to a project, every project belongs to (optionally) a folder, every folder belongs to an organization. IAM bindings can attach at any level and they inherit downward. This is mostly an asset; it can also produce surprising effective-permissions outcomes if you don't pay attention to where bindings are set.
This page covers the hierarchy, the three role types (primitive/predefined/custom), service accounts as a first-class identity type, and IAM Conditions for ABAC-style scoping.
The hierarchy
prod/, nonprod/, sandbox/, shared-services/. Bindings at a folder apply to every project inside.Inheritance is additive. A binding at the org grants on every project below. A binding at a project grants on every resource within. You cannot remove an inherited permission at a lower level — you can only add more (or apply an organization policy that restricts the overall capabilities).
roles/editor by default on the entire project. That role is wildly permissive. Best practice (since 2024): create dedicated service accounts per workload with only the roles they need, and disable the default service account or strip its permissions.Three kinds of roles
Owner, Editor, Viewer
Legacy roles that pre-date the rest of GCP IAM. Apply to all services within a project. Extremely broad: Owner can do anything; Editor can modify most resources; Viewer can read everything.
Avoid in production. Granting roles/owner on a project to a human is a 2014 pattern.
Service-specific roles
Hundreds of pre-built roles maintained by Google. Named like roles/storage.objectViewer, roles/bigquery.dataEditor, roles/compute.networkAdmin. Each bundles a curated set of permissions for a specific job.
The default tool for most access grants. Pick the most specific predefined role available before reaching for custom.
Your own roles
Define a role with exactly the permissions you want. Created at the organization or project level. Useful when predefined roles include permissions you don't want, or when you need a permission set that doesn't match an existing role.
Maintenance overhead: Google adds new permissions to services regularly; custom roles need updating to keep pace.
Service accounts — identity for workloads
A service account is an identity owned by a project (not a user). Workloads authenticate as service accounts. Two operational facts worth memorizing:
- Service accounts are identities and resources. They can be granted roles (like any identity), and they can have IAM bindings on themselves (controlling who can impersonate them, who can manage them).
- Impersonation, not key sharing. Modern GCP guidance: instead of downloading a service account key, configure users to impersonate the service account using their own identity. The audit log records the human's identity along with the service account — key sprawl is eliminated.
- Workload Identity lets workloads (GKE pods, Cloud Run services, on-prem with Workload Identity Federation) act as service accounts without a downloaded key. This is the long-lived-key replacement story for GCP, equivalent to AWS IAM Roles or Azure Managed Identities.
IAM bindings, annotated
A GCP IAM policy is a list of bindings. Each binding is one role granted to one or more principals, optionally with a condition:
The principal prefix matters: user: for humans, group: for Google Groups, serviceAccount: for service accounts, domain: for everyone in a Workspace domain. Use Google Groups for almost everything — granting roles to groups (not to named users) is how you keep the policy auditable.
IAM Conditions are GCP's ABAC mechanism. The expression language (CEL — Common Expression Language) supports time-of-day, resource attributes, request attributes, and tags. The most common conditions in practice: restrict by time, restrict by request IP range, restrict by resource tag (e.g., "only the resources labeled env=prod").
Organization Policies — the guardrails
Organization Policies are constraints applied at the org, folder, or project level that override IAM-level grants. They are GCP's equivalent of AWS SCPs. Examples:
iam.allowedPolicyMemberDomains— restrict which identity domains can be added to IAM policies. Stops anyone from accidentally granting access touser:randomperson@gmail.com.storage.publicAccessPrevention— the GCP version of S3 Block Public Access. Prevents any Cloud Storage bucket from being granted public access, regardless of per-bucket IAM.compute.disableSerialPortAccess— block VM serial console access (used for forensic isolation).compute.restrictVpnPeerIPs,iam.disableServiceAccountKeyCreation— the long tail of "thing we never want anyone in this org to do."
GCP IAM rewards thinking about the hierarchy: which level should this binding live at? Org for organization-wide tools, folders for environment categories, projects for workload-specific access. The wrong level is the root of most "wait, why does this team have admin?" findings.
The modern shape: humans federate via Workspace or Cloud Identity, get access via groups, never get primitive roles. Workloads use service accounts via Workload Identity (no downloaded keys). Organization Policies enforce the guardrails that IAM can't be trusted to maintain by itself.
References
Formatted in APA 7. Alphabetized by first author's last name.
- Google Cloud. (n.d.-a). IAM overview. Google Cloud documentation. https://cloud.google.com/iam/docs/overview
- Google Cloud. (n.d.-b). Resource hierarchy. Google Cloud documentation. https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy
- Google Cloud. (n.d.-c). Organization policy service. Google Cloud documentation. https://cloud.google.com/resource-manager/docs/organization-policy/overview
- Google Cloud. (n.d.-d). Workload Identity Federation. Google Cloud documentation. https://cloud.google.com/iam/docs/workload-identity-federation