IAM and Security
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.