GCP IAM Guide

IAM Roles

Role TypeDescriptionExamples
Basic rolesCoarse-grained legacy rolesroles/viewer, roles/editor, roles/owner
Predefined rolesCurated by Google for specific servicesroles/storage.objectAdmin, roles/container.developer
Custom rolesUser-defined with specific permissionsprojects/my-proj/roles/myCustomRole
# List predefined roles for a service gcloud iam roles list --filter="name:roles/storage" # Create custom role gcloud iam roles create myCustomRole \ --project=my-project \ --title="My Custom Role" \ --permissions=storage.objects.get,storage.objects.list \ --stage=GA # Update custom role gcloud iam roles update myCustomRole \ --project=my-project \ --add-permissions=storage.buckets.get

Policy Bindings

# Add single binding (non-destructive) gcloud projects add-iam-policy-binding my-project \ --member="user:alice@example.com" \ --role="roles/storage.objectViewer" # Add with condition gcloud projects add-iam-policy-binding my-project \ --member="serviceAccount:sa@my-project.iam.gserviceaccount.com" \ --role="roles/compute.instanceAdmin" \ --condition='expression=resource.name.startsWith("projects/my-project/zones/us-central1"),title=ZoneRestriction' # Get full IAM policy gcloud projects get-iam-policy my-project --format=json # Set full policy (replace entire policy) gcloud projects set-iam-policy my-project policy.json # Remove binding gcloud projects remove-iam-policy-binding my-project \ --member="user:alice@example.com" \ --role="roles/storage.objectViewer"

Service Accounts

# Create service account gcloud iam service-accounts create deploy-sa \ --display-name="Deployment SA" # Grant SA access to project gcloud projects add-iam-policy-binding my-project \ --member="serviceAccount:deploy-sa@my-project.iam.gserviceaccount.com" \ --role="roles/run.developer" # Allow user to impersonate SA (Service Account Token Creator) gcloud iam service-accounts add-iam-policy-binding \ deploy-sa@my-project.iam.gserviceaccount.com \ --member="user:alice@example.com" \ --role="roles/iam.serviceAccountTokenCreator" # Create key (avoid if possible, use Workload Identity instead) gcloud iam service-accounts keys create key.json \ --iam-account=deploy-sa@my-project.iam.gserviceaccount.com # List keys gcloud iam service-accounts keys list \ --iam-account=deploy-sa@my-project.iam.gserviceaccount.com

Workload Identity Federation

# Create workload identity pool gcloud iam workload-identity-pools create github-pool \ --project=my-project \ --location=global \ --display-name="GitHub Actions Pool" # Create OIDC provider (GitHub Actions) gcloud iam workload-identity-pools providers create-oidc github-provider \ --project=my-project \ --location=global \ --workload-identity-pool=github-pool \ --display-name="GitHub" \ --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \ --issuer-uri="https://token.actions.githubusercontent.com" # Bind SA to WIF pool gcloud iam service-accounts add-iam-policy-binding \ deploy-sa@my-project.iam.gserviceaccount.com \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/my-org/my-repo"

Audit Logs

# Query audit logs via gcloud gcloud logging read \ 'logName="projects/my-project/logs/cloudaudit.googleapis.com%2Factivity" AND protoPayload.methodName="storage.objects.delete"' \ --limit=50 \ --format=json # Enable data access audit logs (via IAM policy JSON) { "auditConfigs": [{ "service": "storage.googleapis.com", "auditLogConfigs": [ {"logType": "DATA_READ"}, {"logType": "DATA_WRITE"} ] }] } # Export logs to BigQuery gcloud logging sinks create my-bq-sink \ bigquery.googleapis.com/projects/my-project/datasets/audit_logs \ --log-filter='logName:"cloudaudit.googleapis.com"'