IAM answers who (principal) can do what (role) on which resource. The answer is stored in an allow policy attached to an organization, folder, project or individual resource.
flowchart LR P["Principal<br/>group:devops@example.com"] --> B["Binding"] R["Role<br/>roles/compute.instanceAdmin.v1"] --> B B --> AP["Allow policy on project dl-lab-dev"] AP --> RES["VMs in dl-lab-dev"] %% step P: A principal is a Google account, group, service account, domain or federated identity. %% step R: A role is a named set of permissions such as compute.instances.start. %% step B: A binding joins one role to one or more principals, optionally with a condition. %% step AP: The allow policy on the project holds all its bindings and is inherited by its resources. %% step RES: When a call arrives, IAM checks the policies on the resource and every ancestor.
Principals
| Prefix | Example |
|---|---|
user: |
user:alice@example.com |
group: |
group:devops@example.com (preferred: manage people in groups) |
serviceAccount: |
serviceAccount:web-sa@dl-lab-dev.iam.gserviceaccount.com |
domain: |
domain:example.com |
principal:// / principalSet:// |
federated identities (Workload / Workforce Identity Federation) |
allUsers, allAuthenticatedUsers |
public access: avoid except for truly public content |
Three kinds of roles
| Kind | Example | Use |
|---|---|---|
| Basic | roles/owner, roles/editor, roles/viewer |
Very broad, thousands of permissions; avoid in production |
| Predefined | roles/storage.objectViewer, roles/run.developer |
Managed by Google per service; the normal choice |
| Custom | projects/dl-lab-dev/roles/vmOperator |
Your own permission list, at project or organization level (not folder) |
Permissions look like service.resource.verb, for example compute.instances.start. Use the Policy Analyzer and IAM Recommender to find over-granted roles.
How evaluation works
- Policies are inherited: a role on a folder applies to every project in it.
- Grants are additive: effective access is the union of all bindings on the resource and its ancestors.
- Deny policies are checked first and can block a permission even if a role allows it.
- IAM Conditions limit a binding, for example only until a date or only for resources whose name starts with
dev-.
gcloud projects add-iam-policy-binding dl-lab-dev --member="group:devops@example.com" --role="roles/compute.instanceAdmin.v1"
gcloud projects get-iam-policy dl-lab-dev --format=json > policy.json
Good practice
- Grant roles to groups, not to individual users.
- Grant at the lowest level that works: a bucket or a project, not the organization.
- Prefer predefined roles; create custom roles when predefined ones are too broad.
- Replace Owner/Editor on production projects with specific predefined roles.
add-iam-policy-bindingchanges one binding safely;set-iam-policyreplaces the whole policy and can remove access by accident.
| Command | Meaning |
|---|---|
gcloud projects get-iam-policy PROJECT |
Read the project policy |
gcloud projects add-iam-policy-binding PROJECT --member=… --role=… |
Add one binding |
gcloud projects remove-iam-policy-binding PROJECT --member=… --role=… |
Remove one binding |
gcloud iam roles create vmOperator --project=… --permissions=… |
Custom role |
Traps: Editor cannot change IAM policies but can change almost everything else; custom roles cannot be created on folders; removing a project-level binding does not remove a role inherited from a folder.