Mastering IAM in Google Cloud

You’ve done it. You’ve built a magnificent castle in the cloud. Your VPCs are the strong outer walls, your VMs are the bustling workshops, and your databases are the treasure-filled vaults. But now comes the most important question of all: Who gets the keys?

Give everyone a master key, and you’re inviting chaos and plunder. Give no one any keys, and nothing gets done. The art of managing who can do what in your cloud environment is called Identity and Access Management (IAM), and it is the single most important security concept you will master on Google Cloud.

Think of IAM as the ultimate security system for your castle. It’s the gatekeeper, the security guard, and the sophisticated keycard system all rolled into one. Our entire journey through IAM will be about answering one simple, powerful question:

Who can do what on which resource?

Let’s break down this question and, in doing so, build a secure and scalable permissions model from the ground up. This is the core of what you need to know as an Associate Cloud Engineer.

The “Who”: Meet the Principals

Before we can grant permissions, we need to know who we’re granting them to. In IAM, the “who” is called a Principal. There are four main types of principals you’ll encounter.

  1. Google Account: This is you! A person who interacts with Google Cloud through the console or CLI, identified by their email address (e.g., engineer@gmail.com).
  2. Service Account: This is not a person, but an identity for your code. When a VM needs to write a file to a Cloud Storage bucket, it authenticates as a service account. It’s an identity for machines, robots, and applications. We’ll give this special principal its own section later—it’s that important.
  3. Google Group: A collection of Google Accounts and Service Accounts. Instead of giving five developers the same permissions one by one, you can put them all in a group (e.g., web-devs@yourcompany.com) and grant permissions to the group itself. This is a crucial best practice.
  4. Google Workspace / Cloud Identity Domain: This represents your entire company. You can grant a permission to everyone in your yourcompany.com domain, which is useful for granting broad, low-risk access.

The “Can Do What”: A Tale of Three Roles

Now that we know who our actors are, we need to define what they can do. What actions are they allowed to take? This is the job of a Role. A role is simply a collection of permissions. Google Cloud provides a powerful hierarchy of roles, from blunt instruments to surgical scalpels.

The Blunt Instruments: Basic Roles

In the beginning, things were simple. There were three powerful roles that covered everything:

  • Viewer (roles/viewer): Read-only access. Can see resources but cannot change them. Like a key that only lets you look through the windows of the castle.
  • Editor (roles/editor): Read and write access. Can create, modify, and delete most resources. Like a key that opens almost every door, except for the most sensitive ones (like managing users or billing).
  • Owner (roles/owner): God mode. Includes all Editor permissions, plus the ability to manage IAM policies, configure billing, and even delete the project. This is the master key to the entire castle.

For learning and personal projects, these roles are fine. For production, avoid them like the plague. Giving a developer the Editor role on a project just so they can manage VMs also gives them permission to delete your production database. It violates the single most important rule in security…

The Principle of Least Privilege (PoLP)

This principle states that a user or service should only have the absolute minimum permissions required to perform its job, and nothing more. The basic roles are the enemy of this principle. To enforce it, we need more granular tools.

The Scalpels: Predefined Roles

This is where modern IAM shines. Google provides thousands of Predefined Roles that are specific to a service and a job function. Instead of the all-powerful Editor, you can use roles like:

  • roles/compute.instanceAdmin: Full control over Compute Engine instances.
  • roles/storage.objectAdmin: Full control over objects in Cloud Storage buckets.
  • roles/storage.objectViewer: Can only read objects from buckets.
  • roles/cloudsql.client: Allows connecting to a Cloud SQL database.

By using these granular roles, you can build a permission set that adheres to the principle of least privilege. You give the VM administrator the compute.instanceAdmin role and the data analyst the storage.objectViewer role. Neither has permissions they don’t need.

The Custom-Forged Keys: Custom Roles

Sometimes, even the vast library of predefined roles isn’t a perfect fit. Imagine you want to create a “junior operator” role that can start and stop VMs, but you explicitly don’t want them to be able to delete them. No predefined role matches this perfectly.

For this, you can create a Custom Role. You hand-pick the exact permissions you need (e.g., compute.instances.startcompute.instances.stop) and bundle them into your own role.

The Binding: Policies and the Resource Hierarchy

We have our “who” (principals) and our “what” (roles). The final piece of the puzzle is the “on which resource.” A role is useless until you grant it to a principal on a specific resource. This connection is called an IAM Policy Binding.

An IAM policy is a JSON file that binds a list of principals to a role. You don’t apply the policy to the user; you attach the policy to the resource.

But which resource? This is where GCP’s IAM model becomes incredibly powerful. You can attach a policy at any level of the Resource Hierarchy.

  1. Organization: The root node for your entire company. A policy set here is inherited by every single folder, project, and resource in your company. This is where you grant organization-wide roles like Organization Administrator or Billing Account Administrator.
  2. Folders: A way to group projects (e.g., by department: “Finance,” “Engineering”). A policy set on the “Engineering” folder is inherited by all projects within it.
  3. Projects: The most common level for assigning permissions. A policy set on a project applies to all resources within that project. This is where you’d grant a group of developers the Editor role (in dev) or more specific roles in prod.
  4. Resources: The most granular level. You can set an IAM policy on a single Cloud Storage bucket, a single Compute Engine instance, or even a single Pub/Sub topic.

This inheritance model is key. Permissions always flow downwards. If you are an Editor on a project, you are an Editor on every resource inside that project unless a more specific policy denies it. This allows you to set broad policies at the top and more specific ones further down.

Here’s how you’d bind a user to a role on a project using gcloud:

Bash

gcloud projects add-iam-policy-binding my-cool-project \
    --member="user:alice@example.com" \
    --role="roles/compute.instanceAdmin"

This command adds a binding to the IAM policy of my-cool-project. It says, “For this project, the user alice@example.com is granted the compute.instanceAdmin role.”

The Robot Butler: A Deep Dive into Service Accounts

Let’s talk about the most important and often misunderstood principal: the Service Account.

Your application running on a VM needs to read a file from Cloud Storage. How does it authenticate? You could hardcode a developer’s credentials into the code, but that’s a security nightmare. What happens when that developer leaves the company?

The correct way is for the application to authenticate using its own identity—a service account. It’s an IAM identity for your code, not for a person.

How Service Accounts Authenticate

There are two ways a service account can prove its identity:

  1. Service Account Keys (The Last Resort): You can generate a JSON key file for a service account. This file contains a private key that your application can use to authenticate. Treat this key like a password. If it leaks, anyone who has it can act as your service account. Managing, rotating, and securing these keys is a huge operational burden. You should only use them when you have no other choice (e.g., for an application running on-premises or in another cloud).
  2. Attached Service Accounts (The Gold Standard): This is the magic. When you create a Compute Engine VM, a Cloud Function, or an App Engine app, you can attach a service account to it. The resource becomes that identity. The code running on that VM can then get authentication tokens from the local metadata server. There are no keys to manage. Google handles the secure delivery and rotation of credentials behind the scenes. This is the most secure and recommended way for applications within Google Cloud to authenticate.

When creating a VM, you specify which service account it should run as:

Bash

gcloud compute instances create my-vm \
    --zone=us-central1-a \
    --service-account=my-app-sa@my-cool-project.iam.gserviceaccount.com

Common Pitfalls & Best Practices

IAM

  • Pitfall: Using the basic roles (Owner, Editor, Viewer) in production environments. They are overly permissive and a massive security risk.
  • Best Practice: Embrace the Principle of Least Privilege. Use predefined roles to grant only the permissions necessary for a task. If no predefined role fits, create a custom role.
  • Pitfall: Granting permissions to individual users (user:bob@...). This is a management nightmare when people join or leave teams.
  • Best Practice: Grant roles to Google Groups (group:web-devs@...). Manage team membership within the group, and the permissions update automatically.
  • Pitfall: Leaving unused or default service accounts with broad permissions. The default Compute Engine service account has the Editor role by default, which is too powerful.
  • Best Practice: Create dedicated service accounts for each application with the minimal set of roles they need. When creating a VM, attach one of these specific, locked-down service accounts.
  • Pitfall: Downloading and managing service account keys unless absolutely necessary.
  • Best Practice: Leverage attached service accounts on GCE, GKE, Cloud Functions, etc. Avoid keys whenever possible.
  • Pitfall: Not knowing who did what.
  • Best Practice: Regularly review Cloud Audit Logs. These logs record all API calls, telling you who did what, on which resource, and when.

Quick Reference Command Center

Here’s a cheatsheet of gcloud commands for managing IAM.

ActionCommand
Get a Project’s IAM Policygcloud projects get-iam-policy [PROJECT_ID]
Add a Binding to a Project Policygcloud projects add-iam-policy-binding [PROJECT_ID] --member="[MEMBER]" --role="[ROLE]"
Remove a Binding from a Projectgcloud projects remove-iam-policy-binding [PROJECT_ID] --member="[MEMBER]" --role="[ROLE]"
Create a Service Accountgcloud iam service-accounts create [SA_NAME] --display-name="My Cool App SA"
Create a Service Account Keygcloud iam service-accounts keys create key.json --iam-account=[SA_EMAIL]
Bind a Role to a Service Accountgcloud projects add-iam-policy-binding [PROJECT_ID] --member="serviceAccount:[SA_EMAIL]" --role="[ROLE]"
Create a Custom Rolegcloud iam roles create [ROLE_ID] --project=[PROJECT_ID] --file=role-definition.yaml
Create a VM with a Specific SAgcloud compute instances create [VM_NAME] --service-account=[SA_EMAIL] --scopes=...
error: Content is protected !!