Skip to content

IAM in Resource Hierarchy

Overview

IAM (Identity and Access Management) integrates deeply with GCP's resource hierarchy, allowing you to grant permissions at different levels that automatically inherit down the tree. Understanding IAM hierarchy is crucial for implementing least privilege and efficient access control.


Table of Contents

  1. IAM Hierarchy Fundamentals
  2. Permission Inheritance
  3. IAM at Each Level
  4. Best Practices
  5. Common Patterns
  6. Troubleshooting

IAM Hierarchy Fundamentals

How IAM Works in Hierarchy

Organization
├─ IAM Policy: viewer@company.com = roles/viewer
│  └─ Grants view access to EVERYTHING below
│
├─ Folder: Production
│  ├─ IAM Policy: prod-team@company.com = roles/editor
│  │  └─ Grants edit access to all production projects
│  │
│  └─ Project: prod-web
│     ├─ Inherits: viewer@company.com (viewer)
│     ├─ Inherits: prod-team@company.com (editor)
│     └─ IAM Policy: web-admin@company.com = roles/compute.admin
│        └─ Grants compute admin only for this project
│
└─ Folder: Development
   └─ Project: dev-sandbox
      ├─ Inherits: viewer@company.com (viewer)
      └─ IAM Policy: dev-team@company.com = roles/owner
         └─ Full control of dev project

Key Concepts

Policy Inheritance - Permissions granted at higher levels flow down - Cannot be revoked at lower levels - Additive only (more permissive wins)

Effective Permissions - Union of all inherited and direct permissions - Most permissive permission applies


Permission Inheritance

Inheritance Flow

# Check effective IAM policy
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --format="table(bindings.role, bindings.members)"

# Check inherited permissions
gcloud projects get-ancestors-iam-policy PROJECT_ID

Example Scenario

Organization: company.com
├─ alice@company.com = roles/viewer (Org level)
│
├─ Folder: Engineering
│  ├─ bob@company.com = roles/editor (Folder level)
│  │
│  └─ Project: eng-prod
│     └─ charlie@company.com = roles/compute.admin (Project level)

Effective Permissions:
- alice: Can view all resources in organization
- bob: Can edit all resources in Engineering folder
- charlie: Can manage Compute Engine in eng-prod project
- alice in eng-prod: viewer (inherited from org)
- bob in eng-prod: editor (inherited from folder)

IAM at Each Level

Organization Level

# Grant organization-level role
gcloud organizations add-iam-policy-binding ORG_ID \
    --member="user:admin@company.com" \
    --role="roles/resourcemanager.organizationAdmin"

# Common organization roles
gcloud organizations add-iam-policy-binding ORG_ID \
    --member="group:security-team@company.com" \
    --role="roles/securitycenter.admin"

gcloud organizations add-iam-policy-binding ORG_ID \
    --member="group:billing-team@company.com" \
    --role="roles/billing.admin"

Folder Level

# Grant folder-level role
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \
    --member="group:prod-team@company.com" \
    --role="roles/editor"

# Grant to all projects in folder
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \
    --member="group:sre-team@company.com" \
    --role="roles/monitoring.viewer"

Project Level

# Grant project-level role
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="user:developer@company.com" \
    --role="roles/editor"

# Grant specific service role
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:app@PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

Resource Level

# Grant access to specific resource (Cloud Storage bucket)
gsutil iam ch user:user@company.com:objectViewer gs://my-bucket

# Grant access to Compute Engine instance
gcloud compute instances add-iam-policy-binding INSTANCE_NAME \
    --zone=ZONE \
    --member="user:admin@company.com" \
    --role="roles/compute.instanceAdmin"

Best Practices

1. Grant at Appropriate Level

✓ Organization Level - Security team (Security Admin) - Billing team (Billing Admin) - Auditors (Viewer)

✓ Folder Level - Department teams (Editor for their folder) - Environment-specific roles (Prod vs Dev)

✓ Project Level - Application-specific access - Service accounts - Individual developers

✓ Resource Level - Fine-grained access - Temporary access - External users

2. Use Groups

# Create groups for teams
# In Google Workspace Admin Console:
# - engineering@company.com
# - marketing@company.com
# - sre@company.com

# Grant to groups instead of individuals
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="group:engineering@company.com" \
    --role="roles/editor"

3. Principle of Least Privilege

# ❌ Bad: Granting owner at organization level
gcloud organizations add-iam-policy-binding ORG_ID \
    --member="user:developer@company.com" \
    --role="roles/owner"

# ✓ Good: Grant specific role at project level
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="user:developer@company.com" \
    --role="roles/compute.instanceAdmin"

4. Regular Audits

# Audit IAM permissions
from google.cloud import asset_v1

def audit_iam_permissions(organization_id):
    """
    Audit all IAM permissions in organization
    """
    client = asset_v1.AssetServiceClient()

    # Search for all IAM policies
    request = asset_v1.SearchAllIamPoliciesRequest(
        scope=f"organizations/{organization_id}"
    )

    policies = client.search_all_iam_policies(request=request)

    print("IAM Audit Report")
    print("=" * 80)

    for policy in policies:
        print(f"\nResource: {policy.resource}")
        print(f"Policy:")
        for binding in policy.policy.bindings:
            print(f"  Role: {binding.role}")
            for member in binding.members:
                print(f"    Member: {member}")

audit_iam_permissions("123456789")

Common Patterns

Pattern 1: Environment Separation

Organization
│
├─ Folder: Production
│  ├─ IAM: prod-team@company.com = roles/viewer
│  ├─ IAM: prod-sre@company.com = roles/editor
│  └─ Projects: prod-*
│
├─ Folder: Staging
│  ├─ IAM: engineering@company.com = roles/editor
│  └─ Projects: staging-*
│
└─ Folder: Development
   ├─ IAM: engineering@company.com = roles/owner
   └─ Projects: dev-*

Pattern 2: Team-Based Access

Organization
│
├─ Folder: Engineering
│  ├─ IAM: engineering@company.com = roles/editor
│  └─ Projects: eng-*
│
├─ Folder: Marketing
│  ├─ IAM: marketing@company.com = roles/editor
│  └─ Projects: mkt-*
│
└─ Folder: Data Science
   ├─ IAM: data-science@company.com = roles/editor
   └─ Projects: ds-*

Pattern 3: Shared Services

Organization
│
├─ Folder: Shared Services
│  ├─ Project: shared-monitoring
│  │  └─ IAM: all-engineers@company.com = roles/monitoring.viewer
│  │
│  ├─ Project: shared-networking
│  │  └─ IAM: network-team@company.com = roles/compute.networkAdmin
│  │
│  └─ Project: shared-security
│     └─ IAM: security-team@company.com = roles/securitycenter.admin
│
└─ Other folders/projects inherit access to shared services

Troubleshooting

Check Effective Permissions

# Check what permissions a user has
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --filter="bindings.members:user:alice@company.com" \
    --format="table(bindings.role)"

# Check all members with a specific role
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --filter="bindings.role:roles/editor" \
    --format="table(bindings.members)"

Test Permissions

# Test if user has permission
gcloud projects test-iam-permissions PROJECT_ID \
    --permissions=compute.instances.create,compute.instances.delete

# Check service account permissions
gcloud projects test-iam-permissions PROJECT_ID \
    --permissions=storage.buckets.get \
    --impersonate-service-account=SA_EMAIL

Summary

IAM in resource hierarchy provides: - Centralized access management - Automatic permission inheritance - Flexible access control - Scalable security model

Quick Reference

# Organization level
gcloud organizations add-iam-policy-binding ORG_ID \
    --member="user:USER" --role="ROLE"

# Folder level
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \
    --member="group:GROUP" --role="ROLE"

# Project level
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SA" --role="ROLE"

# Check effective policy
gcloud projects get-iam-policy PROJECT_ID

Next Steps


Last Updated: March 2026