Skip to content

GCP IAM

IAM controls who can do what on which GCP resources. Every API call checks IAM before executing.

TermDescription
PrincipalWho is requesting access (user, service account, group)
RoleCollection of permissions (e.g., roles/storage.objectViewer)
PolicyBinds principals to roles on a resource
PermissionA single action (e.g., storage.objects.get)
TypeExample
Google Accountuser:alice@gmail.com
Service AccountserviceAccount:my-sa@project.iam.gserviceaccount.com
Google Groupgroup:dev-team@example.com
All authenticated usersallAuthenticatedUsers
All users (public)allUsers

Primitive roles (avoid in production โ€” too broad):

  • roles/owner โ€” full control
  • roles/editor โ€” read + write, no IAM
  • roles/viewer โ€” read only

Predefined roles (recommended):

  • roles/storage.objectViewer โ€” read objects in Cloud Storage
  • roles/run.invoker โ€” call Cloud Run services
  • roles/bigquery.dataViewer โ€” read BigQuery datasets
  • roles/container.developer โ€” deploy to GKE

Custom roles โ€” define exactly the permissions needed:

Terminal window
gcloud iam roles create MyCustomRole \
--project=my-project \
--title="My Custom Role" \
--permissions="storage.objects.get,storage.objects.list"
Terminal window
# Grant a user a role on a project
gcloud projects add-iam-policy-binding my-project \
--member=user:alice@example.com \
--role=roles/storage.objectViewer
# Grant a service account a role
gcloud projects add-iam-policy-binding my-project \
--member=serviceAccount:my-sa@my-project.iam.gserviceaccount.com \
--role=roles/run.invoker
# Revoke access
gcloud projects remove-iam-policy-binding my-project \
--member=user:alice@example.com \
--role=roles/storage.objectViewer
Terminal window
# View project-level IAM policy
gcloud projects get-iam-policy my-project
# View IAM policy on a bucket
gcloud storage buckets get-iam-policy gs://my-bucket
# Check what a member can do
gcloud asset search-all-iam-policies \
--query="policy:alice@example.com" \
--scope=projects/my-project

Service accounts are identities for applications and workloads:

Terminal window
# Create a service account
gcloud iam service-accounts create my-service-account \
--display-name="My Service Account"
# Grant roles to the service account
gcloud projects add-iam-policy-binding my-project \
--member=serviceAccount:my-service-account@my-project.iam.gserviceaccount.com \
--role=roles/bigquery.dataViewer
# Create and download a key (avoid if possible โ€” prefer Workload Identity)
gcloud iam service-accounts keys create key.json \
--iam-account=my-service-account@my-project.iam.gserviceaccount.com

Using a key file locally:

Terminal window
export GOOGLE_APPLICATION_CREDENTIALS="./key.json"

Allows GKE pods or Cloud Run services to authenticate as a service account without key files. See GKE documentation for setup.

Grant roles only under specific conditions:

Terminal window
gcloud projects add-iam-policy-binding my-project \
--member=user:contractor@example.com \
--role=roles/viewer \
--condition='expression=request.time < timestamp("2026-12-31T00:00:00Z"),title=temporary-access'

Best practices:

  1. Use predefined roles over primitive roles
  2. Grant at the narrowest resource scope (bucket vs project)
  3. Use service accounts per workload, not shared accounts
  4. Avoid downloading service account keys โ€” use Workload Identity
  5. Audit access regularly with gcloud projects get-iam-policy
  6. Enable organisation policies to restrict dangerous actions