IAM
Granting, changing, revoking access to GCP resources
⭐ GCP IAM
At a high level:
GCP IAM = Identities + Roles + Policies that define who can do what on which resources.
But unlike AWS, GCP IAM is deeply tied to:
Google Workspace / Cloud Identity
GCP Resource Hierarchy (Org → Folder → Project → Resource)
Understanding the hierarchy is essential — more than in AWS.
Component
Formal Name
Analogy
Who
Principal (Member)
The Actor (Employee, App)
What
Role
The Keycard (Set of permissions)
Where
Resource
The Door (Project, Bucket, VM)
The Rule
Policy
The Security Ledger
GCP Resource Hierarchy (Very Important)
The hierarchy looks like this:
IAM policies inherit downward:
A role granted at the Organization level applies to every project and resource.
A role granted at a Folder applies only to the projects inside that folder.
A role granted at a Project applies to everything inside that project.
A role granted at a Resource applies only to that resource.
This inheritance system is more explicit and “centralized” than AWS.
Identities (Who is performing the action?)
GCP IAM can assign roles to several identity types:
1️⃣ Google Accounts (Humans)
Emails like
user@gmail.comorperson@company.comUsed for console access
2️⃣ Service Accounts (Applications/Workloads)
This is the equivalent of AWS IAM Roles + Users combined.
Represents an application or workload (VM, Cloud Run, GKE pod)
Uses keyless authentication (IAM + workload identity)
Can also impersonate other service accounts
3️⃣ Google Groups
Logical collections of users & service accounts
Best practice for team-based permissions
4️⃣ Cloud Identity / Google Workspace Domains
Represents company-wide identity providers
Used for SSO + centralized identity
5️⃣ External identities via Workload Identity Federation
Connects AWS, Azure, GitHub, OIDC providers without long-lived keys
Roles (What a principal can do)
GCP IAM roles are bundles of permissions (e.g., storage.objects.get, compute.instances.start).
There are three types of roles:
a) Primitive Roles (avoid using)
roles/ownerroles/editorroles/viewer
These are broad, legacy roles that affect the entire project.
b) Predefined Roles (recommended)
Google-managed granular roles such as:
roles/storage.adminroles/bigquery.dataEditorroles/compute.instanceAdmin.v1
c) Custom Roles (for fine-grained control)
You define your own set of permissions. Useful when predefined roles are too broad.
Policy Bindings (the IAM policy)
In GCP, an IAM Policy is an object attached to a resource. It does not exist in a vacuum; it defines access for the specific resource it lives on.
The Logic: An IAM Policy consists of one or more bindings. A binding "binds" one or more Principals to a single Role.
Resource (Where): The object the policy is attached to (Organization, Project, or Bucket).
Role (What): A named list of permissions.
Principals (Who): The members (users, groups, or service accounts) being granted that role.
Technical Nuance: You don't "add a resource to a policy." Instead, you "Set the IAM Policy on a Resource." Because of Inheritance, a policy set on a Project automatically covers every resource inside it, but you can also set "Sub-Policies" on individual resources (like a single Cloud Storage bucket) to add even more specific access.
One-line formula: Policy = { Binding(Role + Principals), Binding(Role + Principals) } Then, attach that Policy to a Resource.
Service Accounts (non-human identities)
Service accounts are the GCP version of AWS roles—but more flexible since they are actual identities.
A service account is:
An identity for workloads (VMs, Cloud Run, GKE, Cloud Functions)
Able to call Google APIs
Used for authentication between services
They can also:
Act as principals
Have keys (discouraged)
Serve as resources that need permission (for example: granting users permission to impersonate a service account)
IAM Best Practice
Do not use service account keys unless absolutely necessary. Prefer Workload Identity Federation or attached service account identity for workloads.
Impersonation (secure access without keys)
Instead of giving users a service account key, you grant:
roles/iam.serviceAccountTokenCreatorAllows you to become the SA (get a temporary OAuth token) from your local terminal.
OR
roles/iam.serviceAccountUserAllows you to attach the SA to a resource (like a VM).
Then the user/application can impersonate the service account.
This removes static credentials entirely.
Example use cases:
CI/CD pipelines
Local developer workflows
Cross-project access
Resource Hierarchy (important for inheritance)
GCP IAM relies heavily on its hierarchy:
If you assign permissions at a higher level, they cascade down.
Example:
If you give a principal roles/viewer at the project level, they can view every resource in that project.
Granularity increases as you move downward.
Conditions (IAM Conditions)
GCP supports Conditional IAM, adding context-based access control.
You can restrict access by:
Time of day
Resource name
IP ranges
Identity attributes
Request attributes
Service attributes
Example: Allow a service account to write to a bucket only during business hours.
Separation of Duties (Best Practices)
To strengthen security:
Use predefined roles for standard job duties.
Use custom roles only for exceptions.
Keep service accounts scoped to one application (not shared).
Split permissions like “create service accounts” vs “use service accounts.”
Use conditions to restrict abuse of high-privilege roles.
Organization-Level Controls
Important tools:
Organization Policy Service
Used to enforce constraints such as:
Block public IP creation
Block service account key creation
Force VPC-SC
Restrict regions
Disable legacy APIs
VPC Service Controls (VPC-SC)
Adds perimeter-based security around services to prevent data exfiltration.
Think of it as the “zero-trust” perimeter for GCP.
Billing Account Linkage: Remember that Billing Accounts sit at the Org level but link to Projects. IAM roles for billing (e.g., Billing Account User) must often be granted at the Billing Account resource level, not just the Project level.
Audit Logging
GCP automatically generates:
Admin Activity logs (always enabled)
Data Access logs (optional, but recommended)
System Event logs
Policy Denied logs
Security teams rely heavily on these for investigations.
IAM Best Practices (GCP-specific)
Use Groups instead of individuals where possible.
Use Service Accounts for workloads, not users.
Prefer Workload Identity and impersonation over SA keys.
Use predefined roles unless you need custom granular control.
Audit and clean up unused service accounts regularly.
Restrict privilege at the lowest resource level where practical.
Use IAM Conditions for contextual restrictions.
Use Organization Policies to enforce security guardrails.
Regularly rotate high-privilege admin duties among trusted personnel.
Additional concepts
IAM Deny Policies (The "Hard" No)
Standard IAM policies are Allow policies. But if you want to ensure that nobody (even an Owner) can delete a production database, you use a Deny Policy.
Priority: Deny always overrides Allow. If a user is an "Owner" (Allow) but a Deny Policy says "No Delete," the user cannot delete.
Use Case: Preventing accidental deletion of critical "Sovereign" data or blocking certain regions for compliance.
Note for your hierarchy: Deny policies are also inherited downward. A Deny at the Organization level applies to every project.
Workload Identity Federation (The "Key Killer")
You mentioned in your notes that service account keys are discouraged. Workload Identity Federation (WIF) is the reason why.
Instead of downloading a JSON key file to your GitHub Actions or local server, you configure GCP to "trust" the external provider (like GitHub or AWS).
How it works: GitHub proves its identity to GCP → GCP gives a short-lived token → GitHub uses that token to deploy.
Why it's better: No keys to leak, no rotation needed, and it's much more secure.
IAM Conditions & Tags
Sometimes "Role + Member" isn't enough. You might need logic like: "Alice can be an Admin, but only if she is connecting from the office IP" or "only until Friday."
Attributes: You can use attributes like
request.time,resource.name, orresource.type.Resource Tags: You can tag a BigQuery dataset as
environment: production. You can then write an IAM condition that says: "Service Account X has access to BigQuery only if the dataset is tagged asenvironment: dev."
Summary of the above 3 concepts
Concept
Purpose
Analogy
Deny Policy
Absolute restriction
The "Keep Out" sign that overrides any invitation.
WIF
Keyless external access
A "Temporary Badge" for a visitor instead of giving them a permanent key.
Conditions
Context-aware access
Access granted only if it's "Business Hours" or "Internal Wi-Fi."
Last updated