Google Cloud IAM Roles Explained: Basic vs Predefined vs Custom

In Google Cloud, you never grant individual permissions directly. You grant roles. A role is a named collection of permissions, and the role you choose determines exactly what an identity can do and, just as importantly, what it cannot. Getting role selection right is the foundation of secure access control in GCP. This page explains how roles work, what the three role types are, and how to make a confident decision for any access scenario.

IAM roles in simple terms

A permission is a single allowed action. storage.objects.get is a permission. It lets a principal read one Cloud Storage object. That is all it does.

A role is a bundle of permissions grouped together under a single name. roles/storage.objectViewer bundles storage.objects.get and storage.objects.list together. When you grant that role, the identity gets both permissions at once.

You grant roles to principals: a user, a group, or a service account. The role binding specifies who gets it and on which resource. The principal, the role, and the resource scope are the three parts of every access decision in GCP. For a broader introduction to how this fits together, see What Is IAM in GCP.

How IAM roles work in Google Cloud

Every IAM access decision in GCP comes down to three things: a principal (who), a role (what permissions), and a resource (on what). When a principal makes a request, GCP checks whether any binding grants a role that includes the required permission on that resource.

The permissions come from the role. The role is attached through an IAM policy on the resource. A policy is the complete set of role bindings that apply to a resource. You never write permissions directly into a policy; you write role bindings.

You can bind a role at different scopes within the resource hierarchy: organisation, folder, project, or an individual resource like a specific Cloud Storage bucket or a Secret Manager secret. A binding at a higher level is inherited by everything below it. A binding at a lower level affects only that resource.

Analogy

The role is what the badge opens. The scope is where that badge is valid. A cafeteria-access badge could be valid for the entire hospital building (project scope) or only for the third-floor cafeteria (resource scope). Same badge, different coverage area. In GCP, you choose the role and the scope independently. The safest combination is a narrow role bound at the narrowest scope that still covers the task.

Tip

Many GCP services support IAM at the individual resource level, not just at project level. Cloud Storage buckets, BigQuery datasets, Pub/Sub topics, and Secret Manager secrets all accept their own IAM policies. Binding at the resource level is almost always safer than binding at project level, because a project-level binding affects every resource of that type in the project.

The three types of IAM roles

GCP organises its roles into three families. Each exists for a different reason and comes with different trade-offs on security, maintenance, and flexibility.

Role typeScopeMaintained byBest use caseRisk levelProduction recommendation
BasicAll services in the projectLegacy (no updates)Personal test sandboxes onlyHighAvoid
PredefinedOne service, one job functionGoogleAlmost everything in productionLow to mediumDefault choice
CustomExactly the permissions you defineYouWhen predefined genuinely over-grantsLow (if maintained)Use when justified

Basic roles

Basic roles predate the modern IAM system. There are three: roles/viewer, roles/editor, and roles/owner. They were designed before Google Cloud had the granular permission model it has today. The problem is not just that they are broad; it is that they are broad across every service in the project at once:

  • Viewer grants read-only access to most resources across all services in the project

  • Editor grants read and write on most resources, including deleting Cloud SQL databases and modifying service configurations

  • Owner grants everything Editor has, plus the ability to modify IAM policies on the project itself

Real example of the risk

Granting roles/editor to a Cloud Run service so it can write to one Cloud Storage bucket also gives it the ability to delete Firestore collections, overwrite BigQuery tables, and reconfigure Pub/Sub subscriptions. That is not a deliberate security decision; it is a default that accumulates risk every time a new service is added to your project. An account with Owner can grant any permission on the project to any identity, including itself. Do not use basic roles in production.

Predefined roles

Predefined roles are the default choice for almost every real access decision. Google creates and maintains them. Each is scoped to a specific service and a specific job function within that service.

Cloud Storage shows how the progression works in practice:

  • roles/storage.objectCreator lets a principal upload new objects but not read existing ones

  • roles/storage.objectViewer lets a principal read and list objects, with no write or delete access

  • roles/storage.objectAdmin covers create, read, update, and delete for objects but not bucket configuration

  • roles/storage.admin covers full bucket and object administration

An application that only uploads reports should get objectCreator, not objectAdmin. That is predefined roles working exactly as intended: a purpose-built role for a specific job. Google keeps predefined roles current as services evolve, so your access stays accurate without any maintenance from you.

Before assuming there is no predefined role for a task, search the catalog. Most services have roles at several granularity levels for common job functions.

# List all predefined roles for a specific service
gcloud iam roles list --filter="name:roles/storage"

# Search across all services by keyword
gcloud iam roles list --filter="title:viewer"

Custom roles

Custom roles let you select individual permissions from GCP’s permission catalog and bundle them into a role you define. They exist for cases where no predefined role fits because the closest option includes specific permissions you do not want to grant.

A CI pipeline that deploys Cloud Run services is a typical example. The nearest predefined role might include permissions to modify IAM bindings or access sensitive configuration. A custom role lets you include only the deployment permissions the pipeline actually needs.

# ci-deployer-role.yaml
title: "CI 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
# Create the custom role from the YAML definition
gcloud iam roles create ciDeployer \
  --project=my-app-prod \
  --file=ci-deployer-role.yaml
Maintenance required

Predefined roles are updated automatically when Google adds new features to a service. Custom roles are not. A role that correctly covered your CI pipeline last year may now be missing a permission needed for a new feature, or may reference a permission that was renamed. Before creating any custom role, commit to a quarterly review schedule. Without that commitment, the security debt accumulates silently.

Custom roles also go through lifecycle stages: ALPHA, BETA, GA, and DISABLED. Setting a role to DISABLED makes any bindings that reference it completely inert without requiring you to remove those bindings first. This is useful during decommissioning.

When to use each type of IAM role

The right role type depends on the situation. Here are concrete scenarios with the correct approach for each.

Scenario: A human operator who only needs to view logs

Use a predefined role scoped to the logging service, such as roles/logging.viewer. Bind it at project level if the operator monitors the whole project, or at a specific log bucket for narrower access. Do not reach for roles/viewer here. That grants read access across every service in the project, not just logs.

Scenario: An app that only uploads files to Cloud Storage

Use roles/storage.objectCreator bound to the specific bucket, not the project. The service account needs to write to one bucket; it does not need access to any other bucket or service. Binding at the bucket level keeps the blast radius small if the service account is ever compromised. See Service Account Keys Explained for why long-lived credentials for service accounts deserve extra scrutiny.

Scenario: A CI pipeline that deploys to Cloud Run

This is often the clearest case for a custom role. The pipeline needs to push container images and deploy services, but it should not be able to modify IAM bindings or access secrets. Start by checking whether any predefined role covers the task without over-granting. If none fit, build a custom role with only the deployment permissions the pipeline actually uses. For advice on structuring service accounts for automation, see Identity vs Service Accounts.

Anti-pattern: Granting Editor to unblock a team

When a team hits a permission error, the instinct is to grant roles/editor quickly and move on. This is almost always wrong. Editor grants write access to nearly every resource in the project. Instead, identify which specific permission is missing, find the predefined role that includes it, and grant that at the narrowest scope that solves the problem. The IAM access denied errors guide walks through how to diagnose exactly which permission is missing.

Scenario: Access that should be conditional or time-limited

Some access decisions require more than just choosing the right role. If access should only apply under certain conditions, such as a time window, a specific IP range, or a resource tag, combine a predefined role with an IAM condition. Conditions attach directly to role bindings and are evaluated at request time.

Basic vs predefined vs custom roles

Most teams should use predefined roles by default. That is not a compromise; it is the correct answer for the vast majority of access decisions in GCP.

  • Predefined roles are the safest default. Google scopes them tightly to a specific service and maintains them over time. You do not need to build or audit the permission list yourself. Start here for every new access decision.

  • Basic roles are almost always the wrong answer. They exist in GCP for historical reasons, not because they represent good practice. Any argument for using a basic role in production can be solved more safely with a predefined role. The only defensible use is a short-lived personal sandbox where the data has no real consequences.

  • Custom roles require the most maintenance. They give you precise control, but that precision comes with a cost. You own the permission list and must keep it accurate as services change. Use custom roles only after doing a thorough search of the predefined catalog and finding no suitable match.

  • When predefined roles feel too broad, check the binding scope first. Sometimes the issue is not the role choice but where it is applied. Binding roles/storage.objectAdmin on a specific bucket instead of the whole project is often more useful than building a custom role.

For a deeper look at the trade-offs between basic and predefined roles specifically, see Basic vs Predefined Roles.

How to choose the right IAM role

Work through this sequence for every access decision. Skipping steps is where over-permissioning starts. For broader context on why this matters, read the guide on least privilege in GCP.

  1. Identify the specific action the principal needs to perform. Not the general job function. The specific API call or operation. This shapes everything that follows.

  2. Search the predefined catalog for that service. Run gcloud iam roles list —filter=“name:roles/SERVICE” and review all candidates. Most services have roles at several granularity levels for common job functions.

  3. Inspect the role before granting it. Run gcloud iam roles describe roles/ROLE_NAME and read the full permission list. Role names are descriptive but not exhaustive. You will regularly find that a role includes permissions you did not expect.

  4. Choose the narrowest predefined role that covers the task. If the job is reading, grant a viewer role. Grant a writer role only after write access is confirmed as necessary.

  5. Bind at the narrowest resource scope. Grant the role on the specific bucket, dataset, secret, or topic rather than at project level, wherever the service supports resource-level IAM.

  6. Use a custom role only if predefined genuinely over-grants. If a predefined role includes permissions you have a specific reason not to grant, and binding scope alone cannot solve the problem, build a custom role. Document why it was created.

  7. Verify what was applied. After binding, run get-iam-policy on the resource and confirm the binding looks exactly as intended.

# Step 2: Search predefined roles for a service
gcloud iam roles list --filter="name:roles/storage"

# Step 3: Inspect what a role actually grants
gcloud iam roles describe roles/storage.objectViewer

# Step 5: Bind at resource scope, not project scope
gcloud storage buckets add-iam-policy-binding gs://my-app-prod-reports \
  --member="serviceAccount:uploader@my-project.iam.gserviceaccount.com" \
  --role="roles/storage.objectCreator"

# Step 7: Verify the binding was applied correctly
gcloud storage buckets get-iam-policy gs://my-app-prod-reports
Tip

The IAM Recommender in the GCP Console analyses 90 days of API usage and suggests narrower roles for identities that are not using all their granted permissions. Use it as a starting point for tightening existing access, but verify each suggestion before applying it. The recommender shows what was used historically, not necessarily what will be needed in future.

For runtime identity patterns, read Service Account Impersonation and Service Account Keys Explained to understand how to avoid long-lived credentials once you have chosen the right roles.

Common mistakes

  1. Granting roles/editor to unblock a permission error. This is the most common shortcut. Editor grants write access to almost every resource in the project. Find the specific permission that is missing, identify which predefined role includes it, and grant that instead. The permission denied errors guide shows how to find the exact permission you need.

  2. Not inspecting a role before granting it. Run gcloud iam roles describe before every grant. You will regularly find that the role includes permissions you did not intend to give. This takes ten seconds and prevents weeks of over-granted access that is hard to clean up later.

  3. Granting at project scope when resource-level scope is available. Cloud Storage, BigQuery, Pub/Sub, and Secret Manager all support IAM at the individual resource level. A project-level binding applies to every resource of that type in the project. Always prefer the narrower scope.

  4. Creating custom roles before exhausting the predefined catalog. Google has built a role for almost every common job function. Run gcloud iam roles list —filter=“name:roles/SERVICE” and check all candidates before building your own. Custom role maintenance is expensive.

  5. Assuming the role name tells the full story. roles/editor sounds like a writing permission; it is actually project-wide write access to most GCP services. roles/storage.objectAdmin sounds comprehensive but does not include bucket configuration. Always describe a role before you grant it.

Best practices for IAM roles in GCP

  • Use predefined roles by default. They are scoped, Google-maintained, and cover most real access needs. Start here before considering anything else.

  • Avoid basic roles in production. Owner, Editor, and Viewer are legacy. They have no place in a production project with real data.

  • Inspect permissions before granting. Run gcloud iam roles describe as a habit, not an afterthought.

  • Grant at the narrowest scope possible. Prefer resource-level bindings over project-level bindings wherever the service supports it.

  • Schedule quarterly reviews for custom roles. Predefined roles update automatically. Custom roles do not. If you cannot commit to reviewing them, the security debt grows silently.

  • Document why a custom role was created. Future reviewers should not have to reverse-engineer the reasoning from the permission list alone.

  • Use IAM Recommender as a starting point, not a final answer. It surfaces roles with unused permissions based on observed usage, but it does not know what a workload might need next month.

If your team is managing IAM at scale, the managing IAM with gcloud and managing IAM with Terraform guides cover how to make these decisions reproducible and auditable.

Frequently asked questions

What are IAM roles in Google Cloud?

IAM roles are named bundles of permissions that you grant to identities in Google Cloud. You cannot grant individual permissions directly; you always grant a role, and the role determines what the identity can do. GCP has three role families: basic roles (legacy, project-wide), predefined roles (maintained by Google, scoped to specific services), and custom roles (you define and maintain yourself).

What is the difference between an IAM role and an IAM permission?

A permission is a single allowed action, written as service.resource.verb. For example, storage.objects.get lets a principal read a Cloud Storage object. A role is a named collection of permissions. You cannot grant permissions directly in GCP; you grant a role that contains them. Predefined roles group permissions logically by job function so you do not have to build the list yourself.

Should I use basic IAM roles in production?

No. Basic roles (Owner, Editor, and Viewer) are legacy and apply across almost every service in the project simultaneously. Editor can delete Cloud SQL databases, overwrite Cloud Storage data, and reconfigure services. Owner can modify IAM policy on the project itself. Use predefined roles instead; they are scoped to a specific service and a specific job function.

When should I create a custom IAM role?

Only when no predefined role fits the task and the closest option includes specific permissions you do not want to grant. Custom roles require manual maintenance; Google does not update them when services add new features. Exhaust the predefined catalog first, and commit to reviewing custom roles on a quarterly schedule before creating one.

Can I grant multiple IAM roles to the same principal?

Yes. A principal can hold multiple role bindings on the same or different resources. GCP evaluates all applicable bindings; if any grants a permission, the request is allowed. There is no subtraction: you cannot use one binding to cancel a permission granted by another binding at the same level.

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