Google Cloud IAM (Identity and Access Management) controls who can do what on which resources. Every API call is authenticated and authorized through IAM policies attached to resources, projects, folders, or organizations. A solid IAM foundation prevents the most common cloud security incidents: over-privileged accounts, leaked service account keys, and missing audit trails.

Core IAM Concepts

Concept Description
Principal User, group, service account, or workload identity
Role Collection of permissions (predefined or custom)
Policy Binding of principals to roles on a resource
Service Account Identity for applications and automation
Organization Policy Constraints applied across the hierarchy
Condition Optional IAM binding constraint (time, resource, IP)

IAM evaluates policies hierarchically: organization → folder → project → resource. Deny policies (IAM Deny) override allow bindings.

Predefined Roles

Role Permissions Typical Assignment
roles/viewer Read-only access Auditors, stakeholders
roles/editor Read + modify resources Developers (non-prod only)
roles/owner Full control including IAM Project administrators
roles/compute.admin Manage Compute Engine Infrastructure team
roles/run.admin Manage Cloud Run services Platform team
roles/cloudsql.admin Manage Cloud SQL instances DBA team

Grant a role:

  gcloud projects add-iam-policy-binding learning-gcp-dev \
  --member="user:[email protected]" \
  --role="roles/editor"
  

Basic vs. Predefined vs. Custom Roles

Role Type Scope Use Case
Basic (owner/editor/viewer) Broad, thousands of permissions Avoid in production
Predefined Service-specific, maintained by Google Default choice
Custom Permissions you select Fine-grained, audited access

Principle of Least Privilege

Avoid broad roles in production. Use service-specific roles:

  # Storage access only — not full editor
gcloud projects add-iam-policy-binding learning-gcp-dev \
  --member="serviceAccount:[email protected]" \
  --role="roles/storage.objectAdmin"

# Conditional binding: only during business hours
gcloud projects add-iam-policy-binding learning-gcp-dev \
  --member="user:[email protected]" \
  --role="roles/compute.viewer" \
  --condition='expression=request.time.getHours("America/New_York") >= 9 && request.time.getHours("America/New_York") < 17,title=business-hours-only'
  

Service Accounts

Applications authenticate as service accounts — not human users:

  gcloud iam service-accounts create web-app \
  --display-name="Web Application"

# Grant the SA access to Cloud SQL
gcloud projects add-iam-policy-binding learning-gcp-dev \
  --member="serviceAccount:[email protected]" \
  --role="roles/cloudsql.client"

# Grant access to Secret Manager
gcloud projects add-iam-policy-binding learning-gcp-dev \
  --member="serviceAccount:[email protected]" \
  --role="roles/secretmanager.secretAccessor"
  

Workload Identity on GKE

Bind Kubernetes service accounts to GCP service accounts — no key files:

  # Create GCP SA
gcloud iam service-accounts create k8s-app

# Allow K8s SA to impersonate GCP SA
gcloud iam service-accounts add-iam-policy-binding \
  [email protected] \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:learning-gcp-dev.svc.id.goog[default/my-k8s-sa]"

# Annotate K8s service account
kubectl annotate serviceaccount my-k8s-sa \
  iam.gke.io/gcp-service-account=k8s-app@learning-gcp-dev.iam.gserviceaccount.com
  

Organization Policies

Enforce security constraints org-wide:

Constraint Effect
constraints/iam.disableServiceAccountKeyCreation Block SA key downloads
constraints/compute.requireOsLogin Require OS Login for SSH
constraints/gcp.resourceLocations Restrict resource regions
constraints/compute.vmExternalIpAccess Block external IPs on VMs
  # policy.yaml
# constraint: constraints/iam.disableServiceAccountKeyCreation
# booleanPolicy:
#   enforced: true

gcloud resource-manager org-policies set-policy policy.yaml \
  --organization=ORG_ID
  

VPC Service Controls

Create a security perimeter around GCP services to prevent data exfiltration:

  Perimeter: production-data
  ├── Projects: myapp-prod, myapp-data
  ├── Restricted services: storage.googleapis.com, bigquery.googleapis.com
  └── Access levels: corporate VPN IP ranges only
  

Use VPC Service Controls when handling PII, PHI, or financial data.

Audit and Monitoring

  # View IAM policy for a project
gcloud projects get-iam-policy learning-gcp-dev

# List service accounts
gcloud iam service-accounts list

# Review admin activity logs
gcloud logging read 'protoPayload.methodName:"SetIamPolicy"' \
  --limit=10 --format=json
  

Enable Cloud Audit Logs (Admin Activity is always on; Data Access requires explicit enablement for some services).

Real-World Scenario: CI/CD Service Account

A deployment pipeline needs to push images and deploy to Cloud Run:

Role Why
roles/artifactregistry.writer Push container images
roles/run.admin Deploy Cloud Run revisions
roles/iam.serviceAccountUser Act as runtime service account

Bind roles to [email protected]. Use Workload Identity Federation from GitHub Actions — no keys stored in GitHub secrets.

Common Mistakes

Mistake Risk Fix
roles/editor in production Modify/delete any resource Service-specific roles
Long-lived SA keys in repos Credential theft Workload Identity Federation
Individual user bindings Orphaned access when people leave Google Groups for teams
No IAM audit reviews Stale permissions accumulate Quarterly access reviews
Shared service accounts Cannot trace which app made a call One SA per application

Best Practices

  • Enable 2FA on all human Google accounts
  • Use groups for role assignments, not individual users
  • Audit with Cloud Audit Logs (admin, data access, system events)
  • Scan with Security Command Center for vulnerabilities and misconfigurations
  • Encrypt data with CMEK (customer-managed encryption keys) when required
  • Apply VPC Service Controls to prevent data exfiltration
  • Use IAM Recommender to identify over-privileged bindings
  • Implement IAM Deny policies for explicit deny rules org-wide

Troubleshooting

“Permission denied” despite role assignment:

  # Check effective permissions
gcloud projects get-iam-policy learning-gcp-dev \
  --flatten="bindings[].members" \
  --filter="bindings.members:user:[email protected]"

# Verify organization policy is not blocking
gcloud resource-manager org-policies describe \
  constraints/iam.disableServiceAccountKeyCreation --project=learning-gcp-dev
  

Service account impersonation fails: Ensure roles/iam.serviceAccountTokenCreator is granted to the calling principal.

Workload Identity not working on GKE: Verify the cluster has --workload-pool=PROJECT_ID.svc.id.goog and annotations match exactly.

IAM is the security foundation — every GCP resource interaction flows through identity and policy evaluation.

Next: Compute Engine — virtual machines and autoscaling.