← All glossary terms
Google Cloud IAM4 min read

Google Cloud IAM Basics: Principals, Roles, and Permissions

Google Cloud IAM rests on three core ideas: principals, roles, and permissions, joined together by policy bindings on a resource hierarchy. Learn how they interact.

Google Cloud IAM Basics: Principals, Roles, and Permissions

Overview

Google Cloud IAM authorizes API calls based on three core concepts joined by policy bindings attached to a resource hierarchy:

  1. Principals — who is making the request.
  2. Permissions — what atomic action is requested.
  3. Roles — named collections of permissions assignable to principals.

A policy binding says "this principal has this role on this resource (optionally under this condition)." Policies inherit down the hierarchy.


1. Principals

Types

Best Practices

  • Prefer groups over individual users for role assignment.
  • Tag service accounts with owner/purpose.
  • Eliminate allUsers / allAuthenticatedUsers outside intentional public surfaces.

2. Permissions

Format

service.resource.verb

Examples:

  • storage.objects.get
  • compute.instances.start
  • iam.serviceAccounts.actAs
  • bigquery.datasets.create

There are thousands of permissions across Google Cloud services.

Granularity

Permissions are atomic — a single permission usually corresponds to a single API method. This enables fine-grained control.


3. Roles

Roles bundle permissions for assignment.

Three Types

  • Basic roles (legacy): roles/owner, roles/editor, roles/viewer. Each has thousands of permissions across services. Strongly discouraged in production.
  • Predefined roles: maintained by Google per service (e.g., roles/storage.objectViewer, roles/compute.instanceAdmin). Recommended starting point.
  • Custom roles: org or project-scoped, with selected permissions. Use when no predefined fits.

Examples

  • roles/storage.objectAdmin — full control of GCS objects.
  • roles/bigquery.dataViewer — read BigQuery tables.
  • roles/iam.serviceAccountUser — use service accounts for resources.
  • roles/iam.serviceAccountTokenCreator — impersonate service accounts.

4. Policy Bindings

Bindings attach roles to principals on resources:

bindings:
- role: roles/storage.objectViewer
  members:
  - user:[email protected]
  - group:[email protected]
- role: roles/storage.objectAdmin
  members:
  - serviceAccount:[email protected]
  condition:
    title: "Working hours only"
    expression: 'request.time.getHours("UTC") >= 9 && request.time.getHours("UTC") <= 18'

Where Bindings Live

  • Organization node.
  • Folder node.
  • Project node.
  • Resource (some services support resource-level bindings).

Inheritance

Bindings on parent nodes apply to all descendants.


5. Resource Hierarchy

Organization
  ├── Folder: Workloads
  │     ├── Folder: Production
  │     │     ├── Project: prod-app-001
  │     │     │     ├── GCS Bucket
  │     │     │     ├── BigQuery Dataset
  │     │     │     └── Compute Engine VM
  │     │     └── Project: prod-app-002
  │     └── Folder: Non-Production
  └── Folder: Shared Services

Bindings at Organization level affect everything below; folder-level bindings affect all projects in that folder; etc.


6. Conditions

IAM Conditions narrow when a binding applies based on:

  • Time (request.time operations).
  • Resource (resource type, name, tag).
  • Request attributes (caller IP, etc.).

Useful for time-bound access (just-in-time), tag-based ABAC, etc.


7. Deny Policies

A newer feature where you can explicitly deny specific principals from specific permissions across an organization or folder. Deny always wins over Allow. Useful for org-wide guardrails (e.g., deny iam.roles.create for non-admin teams).


Putting It All Together

Example 1: Read-Only Auditor

Binding at Organization: roles/viewer to group:[email protected] with condition restricting to certain folders.

Example 2: ETL Service Account

Service account etl-sa has roles/storage.objectViewer on source bucket and roles/bigquery.dataEditor on destination dataset.

Example 3: Just-In-Time Admin

User has roles/compute.admin on production project but with condition request.time < expiration_time set per-request via approval workflow.


Common Mistakes

  • Basic roles in production (Owner / Editor / Viewer at project or org).
  • Bindings at Organization level for resource-specific access.
  • allUsers binding for "demos" never removed.
  • Service Account Token Creator assigned broadly.
  • Default Compute Service Account with Editor retained.
  • Service account keys generated and forgotten.
  • Custom roles bloated like basic roles.
  • No use of folders — flat structure.

Best Practices

  1. Use predefined roles by default; custom when needed.
  2. Avoid basic roles.
  3. Bindings at the smallest necessary scope (resource > project > folder > org).
  4. Use groups for principal assignment, not individuals.
  5. Use conditions for context restriction.
  6. Use Deny policies for org-wide guardrails.
  7. Workload Identity Federation instead of service account keys.
  8. Service account impersonation instead of key distribution.
  9. IAM Recommender for least-privilege suggestions.
  10. Cloud Audit Logs for IAM events; centralized.

Checklist

  • No basic roles in production?
  • Bindings scoped tightly (resource/project/folder)?
  • Group-based assignment dominant?
  • No allUsers/allAuthenticatedUsers unless intentional?
  • Default service accounts tamed?
  • Workload Identity Federation in CI/CD and on-premises?
  • Conditions used for context?
  • Deny policies for org guardrails?
  • IAM Recommender findings actioned?
  • Audit logs centralized?

How Forestall Helps

Forestall analyzes principals, roles, permissions, and bindings across your hierarchy:

  • Effective permissions per principal.
  • Over-permissioning detection (compared to usage).
  • Privilege escalation chains via service account impersonation.
  • Public exposure findings.
  • Recommendations ranked by impact.

Frequently Asked Questions

Why avoid basic roles?

They include thousands of permissions across services — far broader than any specific job needs.

Can I deny via IAM?

Yes — Deny policies (separate from Allow policies). Deny wins.

Should bindings live on the resource or the project?

As specific as possible. Resource-level if supported; otherwise project; only org/folder if truly needed.

Are custom roles always best?

No — predefined are maintained by Google and cover most needs. Use custom only when no predefined fits.

What's the relationship between IAM and Org Policies?

IAM controls who can do what. Org Policies (separate service) restrict what configurations and resources are allowed (e.g., "no public IPs"). Different layers.


Conclusion

Principals, roles, permissions, and policy bindings are the four foundational concepts of Google Cloud IAM. Combined carefully — least privilege at the smallest scope, group-based principals, no basic roles, conditions for context, federation in lieu of keys — they provide a powerful, hierarchical access control model. Misused, they create the silent over-permissioning paths attackers exploit. Use predefined / custom roles, scoped bindings, and continuous review to keep IAM tight as your GCP estate scales.

Google Cloud IAMGCPIAM Basics

Bring least privilege to your Google Cloud projects.

Forestall maps principals, roles, and bindings across your GCP estate to surface over-permissioning.

We respect your privacy

We use cookies to keep this site secure and working properly. With your permission, we also use optional cookies to understand usage and improve the experience. Cookie Policy

You can change your choice at any time.

Google Cloud IAM Basics: Principals, Roles, and Permissions | Forestall