Least Privilege Roles¶
GKE clusters require specific IAM roles. Grant only the minimum roles needed.
Service Account Roles¶
# gke/iam/roles.tf
locals {
# Minimal roles for node service account
node_roles = [
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/monitoring.viewer",
]
# Minimal roles for cluster operations
cluster_admin_roles = [
"roles/container.admin",
]
# Minimal roles for developers (read-only)
developer_roles = [
"roles/container.developer",
]
}
# Grant roles to node service account
resource "google_project_iam_member" "node_role" {
for_each = toset(local.node_roles)
project = var.gcp_project
role = each.value
member = "serviceAccount:${google_service_account.nodes.email}"
}
# Cluster admin service account
resource "google_service_account" "cluster_admin" {
account_id = "cluster-admin"
display_name = "Cluster admin service account"
}
resource "google_project_iam_member" "cluster_admin" {
project = var.gcp_project
role = "roles/container.admin"
member = "serviceAccount:${google_service_account.cluster_admin.email}"
}
# Developer service account
resource "google_service_account" "developer" {
account_id = "developer"
display_name = "Developer read-only access"
}
resource "google_project_iam_member" "developer" {
project = var.gcp_project
role = "roles/container.developer"
member = "serviceAccount:${google_service_account.developer.email}"
}
output "node_service_account" {
value = google_service_account.nodes.email
description = "Node service account email"
}
output "cluster_admin_service_account" {
value = google_service_account.cluster_admin.email
description = "Cluster admin service account email"
}
output "developer_service_account" {
value = google_service_account.developer.email
description = "Developer service account email"
}
Avoid Broad Permissions
Never grant Editor or Owner roles to service accounts. Use fine-grained predefined or custom roles.
Role Descriptions¶
| Role | Purpose | Risk |
|---|---|---|
roles/container.admin |
Full cluster management | High - Unrestricted access |
roles/container.developer |
Deploy and manage workloads | Medium - Read pods, logs, exec |
roles/container.viewer |
Read-only cluster access | Low - Observability only |
roles/logging.logWriter |
Write logs to Cloud Logging | Low - Nodes only |
roles/monitoring.metricWriter |
Write metrics to Cloud Monitoring | Low - Nodes only |
IAM Security Checklist¶
#!/bin/bash
# IAM configuration verification
echo "=== Service Accounts ==="
gcloud iam service-accounts list \
--format="table(email,displayName)" \
--filter="email~gke|email~cluster"
echo ""
echo "=== IAM Bindings ==="
for sa in $(gcloud iam service-accounts list --format="value(email)" --filter="email~gke"); do
echo "Service Account: $sa"
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$sa" \
--format="table(bindings.role)"
echo ""
done
Related Content¶
- Workload Identity Federation - External identity integration
- Audit Logging - Comprehensive activity tracking
- Cluster Configuration - Private GKE cluster setup