This chapter follows What is Google Cloud Platform?. Identity and Access Management (IAM) is Google Cloud’s authorization layer: every API checks whether the caller’s principal has an allow policy binding on the target resource.
Without IAM, you cannot push container images, deploy Cloud Run services, or read buckets—even if billing and APIs are enabled.
Principals and resources
A principal is who is calling: a Google account (user:you@example.com), a service account (serviceAccount:deployer@PROJECT.iam.gserviceaccount.com), a Google Group, or a federated identity from Workload Identity Federation.
A resource is anything with a name in GCP: projects, buckets, Artifact Registry repositories, Cloud Run services, and more. Policies can attach at the organization, folder, project, or resource level; child resources inherit project-level bindings unless a stricter resource policy applies.
Roles: basic, predefined, and custom
Basic roles (Owner, Editor, Viewer) span entire projects and are broad. Google recommends avoiding them for day-to-day work; use predefined roles scoped to a product (roles/run.admin, roles/storage.objectAdmin).
Custom roles are bundles of permissions you define when no predefined role fits. Start from a predefined role’s permission list, remove what you do not need, and publish a custom role at the organization or project level.
| Role type | Typical use |
|---|---|
| Basic | Legacy; prefer predefined |
| Predefined | Most applications and automation |
| Custom | Least privilege when predefined roles are too wide |
Permissions are strings such as run.services.update. Roles are named collections of permissions; bindings connect (role, principal) to a resource.
Allow policies and inheritance
An allow policy (IAM policy) is a list of bindings:
{ "bindings": [ { "role": "roles/run.developer", "members": ["user:alice@example.com"] } ]}Grant access with gcloud:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="user:alice@example.com" \ --role="roles/viewer"Use gcloud projects get-iam-policy and resource-specific get-policy commands to audit bindings. Prefer resource-level roles when a principal should touch one bucket or one repository, not the whole project.
Service accounts
A service account is a robot identity other principals impersonate. Cloud Run runs as a service account; Cloud Build uses one to push images and deploy services.
Create two accounts for the series:
gcloud iam service-accounts create file-api-deployer \ --display-name="File API deploy pipeline"
gcloud iam service-accounts create file-api-runtime \ --display-name="File API Cloud Run runtime"Deployer (CI or your user when testing) needs to build, push, and deploy:
DEPLOYER="file-api-deployer@YOUR_PROJECT_ID.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:${DEPLOYER}" \ --role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:${DEPLOYER}" \ --role="roles/run.admin"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:${DEPLOYER}" \ --role="roles/iam.serviceAccountUser"The Service Account User role lets the deployer attach the runtime account to Cloud Run.
Runtime needs object access to the upload bucket (created in the Cloud Storage chapter):
RUNTIME="file-api-runtime@YOUR_PROJECT_ID.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:${RUNTIME}" \ --role="roles/storage.objectAdmin"Narrow this to a single bucket with a bucket-level IAM binding once the bucket exists.
Impersonation for local testing
Instead of downloading JSON keys, impersonate the deployer from your user account:
gcloud iam service-accounts add-iam-policy-binding "${DEPLOYER}" \ --member="user:YOU@example.com" \ --role="roles/iam.serviceAccountTokenCreator"
gcloud auth application-default login \ --impersonate-service-account="${DEPLOYER}"Remove impersonation when you finish testing.
Least privilege in practice
Split deploy and runtime identities so a compromised container cannot push malicious images. Grant Cloud Run Invoker (roles/run.invoker) only to callers that should reach the service—not to the runtime service account unless it calls another Run service.
Review bindings periodically. Remove unused service accounts and replace project-wide Editor grants with product-scoped roles.
Workload Identity Federation (outline)
For GitHub Actions or GitLab CI, Workload Identity Federation lets external OIDC tokens map to a Google service account without long-lived JSON keys. You create a workload identity pool and provider, then bind principalSet://... to roles/iam.workloadIdentityUser on the deployer service account. Cloud Build triggers can use the same deployer account; details appear in Continuous delivery with Cloud Build.
Next: Artifact Registry stores the Docker image you build from the series Dockerfile.
Check your understanding
Question 1 of 6
0 of 6 checked