Basic vs Predefined vs Custom IAM Roles in GCP

Every access decision in GCP starts with choosing a role family. The three families (basic, predefined, and custom) differ in how broadly they grant permissions, who maintains them, and when they belong in production. Predefined roles are the correct default for almost everything. Custom roles fill specific gaps. Basic roles belong only in throwaway sandboxes.

Simple explanation

If you are new to GCP IAM, start here. These three role families answer one question: how broadly do you want to grant access?

  • Basic roles — three old roles (Viewer, Editor, Owner) that grant access across every service in a project. Created before the modern IAM system existed. Too broad for production.

  • Predefined roles — curated roles maintained by Google, each scoped to one service and one job function. roles/bigquery.dataViewer can only read BigQuery data. It does nothing to Cloud Storage or Cloud Run. These are your default choice.

  • Custom roles — roles you build by selecting specific permissions from GCP’s full permission catalog. Use them when no predefined role fits without over-granting in a way that matters. You maintain them; Google does not.

Default decision

Start with predefined roles for every grant. Move to a custom role only if the closest predefined option includes permissions you genuinely need to exclude. If you are tempted to reach for Editor or Owner, stop — that is the wrong direction.

How IAM role families work in GCP

In GCP, you never grant individual permissions directly. You grant IAM roles: named collections of permissions attached to a principal via a binding in an IAM policy. The role family you choose determines two things: the blast radius if that account is ever compromised, and the ongoing maintenance burden on your team.

  • Basic roles span many services simultaneously. A single compromised account with Editor is a project-wide incident across every service in the project.

  • Predefined roles are scoped to a specific service and function. A compromised account with roles/bigquery.dataViewer can only read BigQuery. It has no access to Cloud Storage, Cloud SQL, or any other service.

  • Custom roles can be scoped to exactly the permissions a job needs, but the definition does not update automatically as services evolve.

Role family choice should also be paired with resource-level scoping. Even a narrow predefined role applied at project level grants that access across every resource of that type in the project. Binding the same role to a specific Cloud Storage bucket or BigQuery dataset limits it to that one resource. Both dimensions together are what least privilege actually means in practice.

Basic roles: what they actually grant

Basic roles predate the modern IAM system. There are three: roles/viewer, roles/editor, and roles/owner. They apply across all services in the project at once.

  • Viewer — read-only access to most project resources, including Cloud Storage objects, Compute Engine instance metadata, and most API resource listings across every service

  • Editor — read and write on most resources: create, modify, and delete data in Cloud Storage, Cloud SQL, Firestore, Compute Engine, and most other services; cannot modify IAM policies

  • Owner — full project access including IAM policy management, member invitations, and the ability to delete the project

Never use in production

If you grant roles/editor to a service account that only needs to read BigQuery data, that account can also delete your Cloud SQL databases, overwrite your Cloud Storage buckets, and modify your Cloud Run configuration. Not because you wanted that. Basic roles do not distinguish between services. One compromised Editor account is a project-wide incident.

There is one acceptable use case for basic roles: a temporary personal sandbox project where you are the only user and there is no sensitive data. Everywhere else, they create unnecessary risk that grows every time Google adds a new service.

Predefined roles: scoped by service and function

Predefined roles are created and maintained by Google. The naming convention is roles/SERVICE.FUNCTION. Each role is scoped to one service and one job function within that service. They are your default choice for almost all access grants.

The same read / write / admin pattern repeats across services. Here are the equivalent tiers across three common ones:

ServiceRead onlyRead + WriteFull admin
Cloud Storagestorage.objectViewerstorage.objectAdminstorage.admin
BigQuerybigquery.dataViewerbigquery.dataEditorbigquery.admin
Cloud Runrun.viewerrun.developerrun.admin

When Google adds new capabilities to a service, the predefined roles for that service are updated automatically. Your existing bindings benefit from those updates without any action on your part. Custom roles work the opposite way.

IAM Recommender

If your project already has over-broad role grants, GCP’s IAM Recommender analyses 90 days of API call history and suggests narrower predefined roles for each principal. It is the fastest way to tighten legacy access without manually auditing every binding.

# Find predefined roles for a specific service
gcloud iam roles list --filter="name:roles/bigquery"

# Inspect what a specific predefined role actually grants
gcloud iam roles describe roles/bigquery.dataViewer

# Compare two candidate roles before deciding which to use
gcloud iam roles describe roles/storage.objectViewer
gcloud iam roles describe roles/storage.objectAdmin
Tip

When choosing a role for a CI/CD pipeline, look for roles ending in Developer or Deployer. A pipeline that only deploys to Cloud Run probably needs roles/run.developer, not anything broader. For the exact commands to apply these grants, see Managing IAM with gcloud.

Custom roles: precision with a maintenance cost

Custom roles let you build a role from individual permissions. Use them when no predefined role fits because the closest option grants specific permissions you need to exclude, specifically ones that genuinely matter for your security requirements.

The tradeoff is precision versus maintenance. A custom role is exactly what you define, nothing more and nothing less. But it stays exactly as you left it. When Google adds new capabilities to a service, predefined roles update automatically. Your custom role does not. A deployment pipeline role that was correct last year may now be missing permissions for a new feature your team started using, or may include permissions that were renamed or split.

# Create a custom role from a YAML definition
gcloud iam roles create runDeployerMinimal \
  --project=my-app-prod \
  --file=run-deployer-role.yaml

# run-deployer-role.yaml:
# title: "Cloud Run Deployer"
# description: "Deploy Cloud Run services without IAM access"
# stage: GA
# includedPermissions:
#   - run.services.create
#   - run.services.update
#   - run.services.get
#   - run.services.list
#   - artifactregistry.repositories.downloadArtifacts

# Add a permission later if requirements change
gcloud iam roles update runDeployerMinimal \
  --project=my-app-prod \
  --add-permissions=run.services.delete

Custom roles have four lifecycle stages: ALPHA, BETA, GA, and DISABLED. Setting a role to DISABLED makes all its bindings inert without removing the role or its policy entries. This is useful during audits and decommissioning when you want to disable access without a destructive change.

Maintenance required

A custom role that was correctly scoped last year may now be missing permissions your application needs, or may include permissions that were renamed. Schedule a quarterly review of each custom role. Predefined roles update automatically; custom roles do not.

For teams using infrastructure as code, managing custom role definitions in version control alongside IAM bindings in Terraform makes quarterly reviews practical: you can diff the permission list, track who last updated the definition, and roll back cleanly if needed.

Basic vs predefined vs custom: side-by-side

Role familyScopeManaged byBest forMain riskUse in production?
BasicAll services in a projectLegacy (Google)Throwaway personal sandboxesProject-wide blast radius on any compromiseNo — avoid
PredefinedOne service, one functionGoogleMost production grantsOccasional minor over-grantYes — default choice
CustomExactly what you defineYour teamGaps predefined roles cannot fillPermission drift without regular reviewsOnly when predefined over-grants meaningfully

Predefined roles are the best default for three reasons: Google maintains them so you get updates automatically, they map to real job functions (dataViewer, developer, deployer), and they have been designed around sensible permission boundaries for each service.

Basic roles are dangerous in production because their scope is the entire project. Every time Google adds a new service, a basic role immediately includes access to it — a growing attack surface you never explicitly approved.

Custom roles are powerful but come with a real operational cost. Every custom role you create is a definition your team must review, update, and eventually deprecate. That overhead is worth it when predefined roles genuinely over-grant in a way that matters. It is not worth it when the concern is theoretical rather than practical.

When to use each role type

Use basic roles only for temporary personal sandboxes

If you are spinning up a short-lived test project for personal learning with no sensitive data, basic roles remove friction. As soon as the project holds anything real, has more than one user, or is connected to any shared resource, replace them with predefined roles.

Use predefined roles for most production workloads

  • Service account that reads BigQuery data — grant roles/bigquery.dataViewer on the specific dataset, not roles/editor on the project

  • CI/CD pipeline deploying to Cloud Run — grant roles/run.developer on the specific Cloud Run service, not a broad developer or editor role at project level

  • Security reviewer who needs read-only audit access — grant roles/logging.viewer and roles/iam.securityReviewer, not roles/viewer across the whole project

  • Platform admin managing one GCP service — use the predefined SERVICE.admin role for that service rather than project-level Owner

Use custom roles when predefined roles over-grant in a meaningful way

Custom roles are worth building when:

  • The closest predefined role includes a write or delete permission you need to exclude for a sensitive workload

  • You are scoping a service account for a very narrow job function where even a viewer-level predefined role includes permissions the workload should never have

  • Your organisation has a compliance requirement to document exactly which permissions each role grants, with an attached review cadence

How to choose the right role family

Work through this in order for every access decision. For the commands to apply the grant once you have decided, see Managing IAM with gcloud. For the underlying principle, see Least Privilege in GCP.

  1. Identify the service involved. Which GCP service does the identity need to interact with? Cloud Storage? BigQuery? Cloud Run? Pub/Sub?

  2. Find the narrowest predefined role. Run gcloud iam roles list —filter=“name:roles/SERVICE” and look for roles matching the actual job function: viewer, creator, developer, deployer.

  3. Inspect the role’s permissions before granting. Run gcloud iam roles describe roles/ROLE_NAME. Check whether any included permissions are unnecessary for the task.

  4. Confirm it covers the real task. Does the predefined role include every permission the identity actually needs?

  5. Create a custom role only if the over-grant genuinely matters. If the predefined role includes a permission you do not need but it poses no realistic risk for this workload, the maintenance cost of a custom role is not worth it.

  6. Never fall back to basic roles in production. If you cannot find the right predefined role, use a custom role. Never treat Editor as a fallback.

Add a time dimension

For temporary access or access that should expire after a deployment window, combine your role choice with IAM Conditions. You can set a binding to expire at a specific date, restrict it to resources matching a name prefix, or require a specific resource tag — without needing a separate role.

Common mistakes

  1. Granting roles/editor to fix a permission error quickly. This unblocks the error but grants write access to every service in the project. Identify the specific permission missing, find the correct predefined role that includes it, and replace the Editor grant. The fix takes two commands and removes significant ongoing risk.

  2. Granting roles/owner to a service account. A service account with Owner can modify any IAM binding on the project, including granting itself or others new permissions. If a workload’s service account is ever compromised, Owner means total project compromise. Use the predefined admin role for the specific service instead. See Service Account Impersonation for safer patterns.

  3. Creating a custom role before checking predefined options. Run gcloud iam roles list —filter=“name:roles/SERVICE” and gcloud iam roles describe on every candidate first. The right predefined role exists for most common tasks — the custom role maintenance burden is only worth taking on when it genuinely does not.

  4. Sharing one broad role across multiple workloads. Each service account should have role assignments tailored to its specific job. A shared powerful role means a compromise of any one workload exposes all the others.

  5. Not scheduling reviews of custom roles. Custom role permissions go stale as services evolve. A role that was correctly scoped at creation may now be missing permissions added to the equivalent predefined role, or may include permissions that were renamed — silently breaking your application or silently granting more than intended.

Frequently asked questions

What is the difference between basic and predefined roles in GCP?

Basic roles (Viewer, Editor, Owner) apply across every service in the project simultaneously — they predate modern IAM. Predefined roles are scoped to one service and one job function, like roles/bigquery.dataViewer for BigQuery read access only. Predefined roles are the correct default for almost all production grants. Basic roles are only appropriate in throwaway sandbox projects with no sensitive data.

Are predefined roles safer than basic roles?

Yes, significantly. A compromised account with roles/editor can delete Cloud SQL databases, overwrite Cloud Storage objects, and modify Cloud Run configuration. The same account with roles/bigquery.dataViewer can only read BigQuery data. Predefined roles limit the blast radius to one service and one function within that service.

When should I create a custom IAM role in GCP?

Create a custom role only when the closest predefined role over-grants permissions that matter for your security requirements. Before creating one, run gcloud iam roles list --filter="name:roles/SERVICE" to confirm no suitable predefined role exists. Custom roles require ongoing maintenance — they do not update automatically when Google adds new features to a service.

Is Owner ever appropriate in Google Cloud?

Owner is appropriate only for a small number of project administrators who manage billing, IAM, and project lifecycle. It should never be granted to service accounts or used for day-to-day operational work. For service-specific administration, use the predefined admin role for that service rather than project-level Owner.

How do I find the right predefined role for a task?

Run gcloud iam roles list --filter="name:roles/SERVICE" to list predefined roles for a service, then gcloud iam roles describe roles/ROLE_NAME to inspect its permissions. The GCP documentation for each service also lists available roles. For existing bindings, IAM Recommender analyses actual API usage over 90 days and suggests narrower alternatives.

What happens to bindings when I disable a custom role?

Setting a custom role to DISABLED stage makes all its bindings completely inert — principals with that role effectively have no permissions from it until the role is re-enabled. This lets you deactivate a role without deleting it or removing its policy entries, which is useful during audits and decommissioning.

Last verified: 21 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.