ACEChapter 13 of 101Objective 5.1

GCP IAM and Service Accounts

This chapter covers Google Cloud Identity and Access Management (IAM) and Service Accounts, which are foundational to securing GCP resources. IAM is the primary mechanism for controlling who (identity) has what access (role) to which resources. Service accounts are special identities used by applications and virtual machines to authenticate to Google APIs. On the ACE exam, approximately 15-20% of questions touch on IAM concepts, including roles, policies, service accounts, and best practices. Mastering these topics is essential for passing the exam and for real-world GCP administration.

25 min read
Intermediate
Updated May 31, 2026

IAM: Hotel Key Card System

Imagine a large hotel with many different types of rooms and facilities. The hotel has a master key system. Each guest receives a key card that is programmed specifically for their stay. The key card does not contain a list of rooms it can open; instead, it contains a unique identifier. When the guest swipes the card at a door lock, the lock sends the card's ID to a central authorization server. The server checks its database: it looks up the card's identity (who the guest is) and the policies associated with that identity (what roles the guest has, like 'guest of room 204' or 'VIP lounge member'). If the guest's role permits access to that specific door, the server sends an 'unlock' command back to the lock. The key card itself never holds permissions; it is just a token that proves identity. Similarly, in GCP IAM, a service account key or a user's OAuth2 token is like the key card. The token contains only identity information, not permissions. When a request is made to a Google Cloud API, the API checks the token against IAM policies to determine if the action is allowed. The hotel manager can revoke a key card's access at any time by updating the central server's database, without needing to re-issue the physical card. This is analogous to disabling a service account or revoking a user's role – the change takes effect immediately because permissions are evaluated at runtime, not embedded in the credential. The hotel also has a strict rule: no key card can open a door that the guest has not been explicitly authorized for, even if the card has high-level privileges. This mirrors the principle of least privilege in IAM: grant only the minimal permissions needed.

How It Actually Works

What is IAM and Why Does It Exist?

Google Cloud IAM is a unified access control system that allows administrators to authorize who can take what action on which resources. Before IAM, GCP used legacy access control lists (ACLs) on individual resources, which were tedious to manage and did not scale. IAM provides a consistent, fine-grained, and hierarchical permission model across all GCP services.

IAM is built on three core components: - Members: Identities such as Google accounts, Google Groups, service accounts, or G Suite/Cloud Identity domains. Members can be authenticated users (human), applications (service accounts), or even all authenticated users or the public. - Roles: A collection of permissions. A permission is a named action that can be taken on a resource (e.g., compute.instances.start). Roles can be predefined (created by Google), custom (user-defined), or basic (legacy Owner/Editor/Viewer). - Policies: Bindings that associate a list of members with a role, applied to a resource or a hierarchy node (organization, folder, project). Policies are expressed in JSON or YAML format.

How IAM Works Internally

When a request is made to a Google Cloud API (e.g., gcloud compute instances list), the following steps occur:

1.

Authentication: The caller presents a credential (OAuth2 token, service account key, etc.). Google's authentication system validates the credential and extracts the identity (the member).

2.

Authorization: The API service calls the IAM system to check if the member has the required permission on the target resource. IAM evaluates the effective policy by walking up the resource hierarchy (project -> folder -> organization) and collecting all allow bindings. If any policy grants the member a role that includes the required permission, the request is allowed. If no policy grants the permission, the request is denied by default.

3.

Audit Logging: All IAM policy changes and authorization decisions are logged in Cloud Audit Logs for security analysis.

Key Components, Values, and Defaults

Predefined Roles: Google provides hundreds of predefined roles. Examples: roles/compute.instanceAdmin.v1 (full control of Compute Engine instances), roles/storage.objectViewer (read access to objects in Cloud Storage).

Basic Roles: These are legacy roles: roles/viewer (read-only), roles/editor (view + modify), roles/owner (full control + billing). Avoid using basic roles in production because they are too permissive.

Custom Roles: You can create custom roles with a specific set of permissions. Custom roles are defined at the organization or project level. They cannot be used across organizations. Quotas: up to 300 custom roles per organization, up to 300 per project.

IAM Policy Structure: A policy is a list of bindings. Each binding has a role and a list of members. Example:

{
  "bindings": [
    {
      "role": "roles/compute.instanceAdmin.v1",
      "members": [
        "user:alice@example.com",
        "serviceAccount:my-sa@project.iam.gserviceaccount.com"
      ]
    }
  ]
}

- Members: Members are specified using prefixes: - user: for Google account emails - group: for Google Groups - serviceAccount: for service accounts - domain: for G Suite/Cloud Identity domains (e.g., domain:example.com grants access to all users in that domain) - allAuthenticatedUsers: any authenticated user (including users outside your organization) - allUsers: any user, including unauthenticated (public)

Resource Hierarchy: Policies are inherited downward. A policy at the organization level applies to all folders and projects under it. A policy at a folder level applies to all projects in that folder. A policy at the project level applies to all resources in that project. However, some resources (like Cloud Storage buckets) have additional IAM policies at the resource level that can override project-level policies (but not organizational policies).

Deny Policies: As of 2021, Google Cloud supports deny policies (in addition to allow policies). Deny policies are evaluated before allow policies and can explicitly deny access even if an allow policy grants it. Deny policies are defined at the organization, folder, or project level. They use a different syntax and are managed via gcloud alpha iam policies or the Cloud Console.

Configuration and Verification Commands

View IAM policy for a project:

gcloud projects get-iam-policy PROJECT_ID

Set IAM policy for a project:

gcloud projects set-iam-policy PROJECT_ID policy-file.json

Add IAM policy binding:

gcloud projects add-iam-policy-binding PROJECT_ID --member='user:alice@example.com' --role='roles/compute.instanceAdmin.v1'

Remove IAM policy binding:

gcloud projects remove-iam-policy-binding PROJECT_ID --member='user:alice@example.com' --role='roles/compute.instanceAdmin.v1'

Test IAM permissions:

gcloud iam simulate --project=PROJECT_ID --permissions='compute.instances.list' --principal='user:alice@example.com' --resource='//compute.googleapis.com/projects/PROJECT_ID'

List service accounts:

gcloud iam service-accounts list

Create a service account:

gcloud iam service-accounts create SA_NAME --display-name='My Service Account'

Create a service account key:

gcloud iam service-accounts keys create key-file.json --iam-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com

Service Accounts in Depth

A service account is a special type of Google account that belongs to an application or a virtual machine, not to an individual user. Service accounts are used to authenticate application-to-API calls. There are two types:

User-managed service accounts: Created by you. Each has a unique email address in the format NAME@PROJECT_ID.iam.gserviceaccount.com.

Google-managed service accounts: Created automatically by Google services (e.g., Compute Engine default service account, App Engine default service account). Their email format is PROJECT_NUMBER-compute@developer.gserviceaccount.com.

Service accounts can be used in two ways:

1.

Attached to a resource: For example, a Compute Engine VM instance can have a service account attached. Any application running on that VM can use the VM's metadata server to obtain an OAuth2 token for that service account, without needing to manage keys. This is the recommended approach.

2.

Using a key: You can download a private key (JSON or P12) for a service account and use it outside Google Cloud (e.g., on-premises or in another cloud). Keys should be treated as secrets and rotated regularly. Google recommends using workload identity federation instead of keys when possible.

How Service Accounts Interact with IAM

Service accounts are both identities and resources. As an identity, they can be granted IAM roles to access other resources (e.g., a service account can have roles/storage.objectViewer on a Cloud Storage bucket). As a resource, they can have IAM policies that control who can use them (e.g., who can iam.serviceAccounts.actAs to impersonate the service account). The roles/iam.serviceAccountUser role allows a user to impersonate a service account (e.g., to deploy resources that run as that service account). The roles/iam.serviceAccountAdmin role allows managing the service account itself (create, delete, manage keys).

Best Practices for IAM and Service Accounts

Use the principle of least privilege: grant only the permissions needed. Prefer predefined roles over basic roles. Use custom roles when predefined roles are too broad.

Use groups to manage permissions instead of individual users. Assign roles to groups, then add/remove users from groups.

For service accounts, avoid using keys. Instead, attach service accounts to resources (like Compute Engine VMs) and use the metadata server for authentication.

Rotate service account keys regularly (e.g., every 90 days). Use multiple keys to allow rotation without downtime.

Enable audit logging to monitor IAM policy changes and access patterns.

Use organization policies to restrict service account key creation or to enforce constraints like requiring that VMs use only specific service accounts.

How IAM Interacts with Other GCP Services

Cloud Audit Logs: All IAM policy changes are logged. Admin Activity audit logs track who changed what policy. Data Access audit logs track who accessed what resource.

VPC Service Controls: Can restrict access to GCP services from outside a VPC service perimeter, even if IAM allows it.

Access Transparency: Provides logs of actions taken by Google support personnel, even though they are authenticated with Google's own identity.

Cloud Identity-Aware Proxy (IAP): Uses IAM to control access to applications deployed on Compute Engine or App Engine. IAP authenticates users and checks IAM policies before allowing access to the app.

Walk-Through

1

Create a Service Account

Navigate to IAM & Admin > Service Accounts in the Cloud Console, or use the command `gcloud iam service-accounts create SA_NAME --display-name='My Service Account'`. The service account is created with a unique email address. At this point, it has no roles and cannot access any resources. It is just an identity. The service account can be used by applications to authenticate, but it must be granted permissions first.

2

Grant Roles to the Service Account

Use the IAM page or `gcloud projects add-iam-policy-binding` to grant roles to the service account. For example, to grant object viewer access to a Cloud Storage bucket: `gcloud storage buckets add-iam-policy-binding gs://my-bucket --member='serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com' --role='roles/storage.objectViewer'`. The role grants permissions on the bucket. The service account now has the ability to read objects in that bucket.

3

Attach Service Account to a VM

When creating a Compute Engine VM, you can specify a service account to attach. This is done via the Cloud Console (under Identity and API access) or with the `--service-account` and `--scopes` flags. For example: `gcloud compute instances create my-vm --service-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com --scopes=cloud-platform`. The VM will now run as that service account. Any application on the VM can access the metadata server to get an OAuth2 token for the service account. The `--scopes` flag defines the OAuth2 scopes, which act as a secondary access control layer (deprecated but still used for legacy APIs).

4

Application Authenticates via Metadata Server

An application running on the VM can request a token from the metadata server at `http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token`. The metadata server returns an OAuth2 access token valid for 1 hour. The application uses this token to call Google Cloud APIs. The token is automatically refreshed by the metadata server. This mechanism avoids the need to manage service account keys on the VM.

5

API Call with Token

The application makes an API call (e.g., list objects in a Cloud Storage bucket) and includes the access token in the Authorization header: `Authorization: Bearer ACCESS_TOKEN`. The API service validates the token with Google's authentication system, extracts the service account identity, and then checks IAM policies to see if that identity has the required permission (e.g., `storage.objects.list`). If yes, the API call succeeds; otherwise, it returns a 403 Forbidden error.

What This Looks Like on the Job

Enterprise Scenario 1: Microservices on GKE

A large e-commerce company runs a microservices architecture on Google Kubernetes Engine (GKE). Each microservice needs to access specific GCP resources: one service writes to Cloud Pub/Sub, another reads from Cloud SQL, and a third uploads files to Cloud Storage. The security team wants to enforce least privilege. They create a separate service account for each microservice and grant only the necessary roles. For example, the Pub/Sub writer service account gets roles/pubsub.publisher on the relevant topic. The service accounts are attached to the GKE nodes or pods using Workload Identity, which allows pods to impersonate service accounts without keys. This setup ensures that if one microservice is compromised, the attacker cannot access resources meant for other services. In production, they monitor IAM policy changes with Cloud Asset Inventory and set up alerts for any modifications to service account roles. A common misconfiguration is granting roles/owner or roles/editor to a service account, which violates least privilege and can lead to accidental deletion of resources. They use custom roles when predefined roles are too broad.

Enterprise Scenario 2: Cross-Project Access for Data Analytics

A company has multiple GCP projects: one for data ingestion (project-ingest), one for data processing (project-process), and one for data visualization (project-viz). The processing project needs to read data from the ingestion project's Cloud Storage bucket and write results to the visualization project's BigQuery dataset. They create a service account in the processing project and grant it roles/storage.objectViewer on the ingestion bucket and roles/bigquery.dataEditor on the visualization dataset. This cross-project access is configured by adding the service account as a member in the IAM policy of the target project. They must ensure that the service account is not over-permissioned; for example, they avoid granting roles/storage.admin which would allow deleting the bucket. A common pitfall is forgetting that IAM policies are evaluated at the project level, so granting a role at the project level gives access to all resources of that type in the project. To restrict access to a specific bucket, they use resource-level IAM policies. They also enable VPC Service Controls to prevent data exfiltration. Performance is not an issue because IAM decisions are cached and typically take under 100ms.

Enterprise Scenario 3: Third-Party Vendor Access

A company needs to give a third-party vendor access to a specific Cloud Storage bucket to upload log files. The vendor uses their own GCP organization. The company creates a service account in their project and shares the service account email with the vendor. However, the vendor cannot use the service account because they don't have the private key. Instead, the company uses workload identity federation: they configure an OIDC identity provider in their project that trusts the vendor's identity provider (e.g., their Okta tenant). The vendor's application obtains a token from Okta, then exchanges it for a Google Cloud access token via the STS endpoint. This allows the vendor to access the bucket without managing keys. The company grants the vendor's federated identity (e.g., principalSet://iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/my-pool/attribute/email/vendor-app@vendor.com) the role roles/storage.objectCreator on the bucket. This setup is more secure than sharing service account keys, which could be leaked. Misconfiguration often occurs when the OIDC provider is not set up correctly, causing token validation failures. The company must ensure that the vendor's token includes the expected claims (e.g., sub, aud) and that the attribute mapping in the workload identity pool is accurate.

How ACE Actually Tests This

What the ACE Exam Tests on IAM and Service Accounts

The ACE exam (objective 5.1) focuses on the following:

- IAM Roles: Know the difference between basic, predefined, and custom roles. Be able to identify when to use custom roles (when predefined roles are too broad). Understand that basic roles are legacy and should be avoided. - IAM Policy Inheritance: Understand that policies are inherited from organization -> folder -> project -> resource. However, some resources (like Cloud Storage buckets) can have resource-level policies that override project-level policies. The exam may ask: 'If a user has Viewer role at the project level but Owner role at the bucket level, what access do they have on the bucket?' Answer: Owner (resource-level policy overrides project-level). - Service Account Keys vs. Attached Service Accounts: The exam emphasizes that using keys is less secure and that attaching a service account to a VM is preferred. Know the format of service account email: NAME@PROJECT_ID.iam.gserviceaccount.com. Know that the default Compute Engine service account is PROJECT_NUMBER-compute@developer.gserviceaccount.com. - Service Account Roles: roles/iam.serviceAccountUser allows a user to impersonate a service account (e.g., to deploy resources that run as that service account). roles/iam.serviceAccountAdmin allows managing the service account itself. The exam may ask: 'Which role should you grant to a developer so they can deploy a Compute Engine VM that runs as a specific service account?' Answer: roles/iam.serviceAccountUser on that service account. - Deny Policies: Know that deny policies can override allow policies. They are evaluated first. The exam may ask: 'If a deny policy denies a permission and an allow policy grants it, what happens?' Answer: Deny wins. - Common Wrong Answers: 1. 'Grant the user the Owner role on the project to give them access to a single Cloud Storage bucket.' This is wrong because Owner grants full access to all resources; instead, use resource-level IAM on the bucket. 2. 'Create a service account key and embed it in the application code.' This is wrong because keys can be leaked; use metadata server or workload identity federation. 3. 'Use a basic role because it is simpler.' This is wrong because basic roles are too permissive; use predefined or custom roles. 4. 'IAM policies are evaluated only at the resource level.' This is wrong because they are evaluated hierarchically. - Edge Cases:

If a user is granted a role via a group, and also directly, the effective permissions are the union. The exam may test that group membership changes take effect within minutes (not instantly).

Service accounts can be granted roles on other service accounts (e.g., a service account can have roles/iam.serviceAccountTokenCreator on another service account to create tokens for it).

The allAuthenticatedUsers member includes all authenticated users, including those outside your organization. This is a security risk if used inadvertently.

How to Eliminate Wrong Answers: Read the question carefully: Is it asking about a user or a service account? Is it about a VM or a key? If the question mentions 'application running on Compute Engine', the correct answer will likely involve attaching a service account to the VM, not using keys. If the question mentions 'on-premises application', then keys or workload identity federation are appropriate. Always look for the most secure option that meets the requirements.

Key Takeaways

IAM consists of three parts: members, roles, and policies. Policies bind members to roles on resources.

IAM policies are hierarchical: organization > folder > project > resource. Inheritance is downward, but resource-level policies can override project-level policies.

Basic roles (Owner/Editor/Viewer) are legacy and overly permissive; avoid them in production.

Service accounts are identities for applications. Use attached service accounts (via metadata server) instead of keys when possible.

The default Compute Engine service account gets the Editor role automatically; create custom service accounts with least privilege.

Deny policies take precedence over allow policies. They are evaluated first.

IAM policy changes typically take up to 80 seconds to propagate; they are not instantaneous.

Use `gcloud projects add-iam-policy-binding` to grant roles, and `gcloud iam service-accounts create` to create service accounts.

The `roles/iam.serviceAccountUser` role allows a user to impersonate a service account.

Workload identity federation allows external identities (e.g., from AWS or Azure) to access GCP resources without service account keys.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Service Account Keys

Requires downloading a private key file (JSON or P12).

Key must be securely stored and rotated regularly.

Suitable for applications running outside GCP (on-prem, other clouds).

Risk of key leakage if not handled properly.

Can be used for long-running processes without a VM.

Attached Service Accounts (VM Metadata)

No key file to manage; token obtained from metadata server.

Token is automatically refreshed every hour.

Suitable for applications running on Compute Engine, GKE, or Cloud Functions.

More secure because no secrets are stored on the VM.

Simplifies key rotation and reduces operational overhead.

Watch Out for These

Mistake

IAM roles are assigned directly to resources.

Correct

IAM roles are assigned to members, not resources. A policy binds a role to a member on a resource. The role defines a set of permissions that the member has on that resource.

Mistake

Service account keys never expire.

Correct

Service account keys do not have an expiration date by default, but Google recommends rotating them every 90 days. You can set a key expiration when creating the key using the `--valid-after` and `--valid-until` flags.

Mistake

The default Compute Engine service account has no permissions.

Correct

The default Compute Engine service account is automatically granted the `roles/editor` role on the project when the Compute Engine API is enabled. This is a basic role that grants broad edit access. It is recommended to create and use custom service accounts with least privilege instead.

Mistake

IAM policies are evaluated in real time for every API call.

Correct

IAM decisions are cached for performance. Changes to IAM policies typically take effect within 60 seconds (but can take up to 80 seconds). The exam may test that policy changes are not instantaneous.

Mistake

A service account can only be used within the same project.

Correct

A service account can be used across projects by granting the service account access to resources in other projects. The service account's email is in the format `NAME@PROJECT_ID.iam.gserviceaccount.com`, and it can be added as a member in IAM policies of other projects.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between a role and a permission in GCP IAM?

A permission is a named action that can be taken on a resource, such as `compute.instances.start`. A role is a collection of permissions. Roles are assigned to members via IAM policies. For example, the `roles/compute.instanceAdmin.v1` role contains permissions like `compute.instances.start`, `compute.instances.stop`, etc. You cannot assign a permission directly to a member; you must assign a role that contains that permission.

How do I grant a service account access to a Cloud Storage bucket in another project?

You need to add the service account as a member in the IAM policy of the bucket (or the project containing the bucket). Use the command: `gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member='serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com' --role='ROLE'`. The service account's email is from its own project, but it can be used as a member in any project's IAM policy.

What is the default service account for Compute Engine and what permissions does it have?

The default Compute Engine service account is `PROJECT_NUMBER-compute@developer.gserviceaccount.com`. It is automatically created when the Compute Engine API is enabled and is granted the `roles/editor` role on the project. This is a basic role that allows broad edit access. It is recommended to avoid using this default service account and instead create a custom service account with only the necessary permissions.

Can I use a service account key with an on-premises application?

Yes, you can download a service account key (JSON file) and use it to authenticate your on-premises application. However, Google recommends using workload identity federation instead, which allows you to exchange tokens from your identity provider (e.g., Azure AD, Okta) for Google Cloud tokens without managing service account keys. If you must use keys, rotate them regularly and store them securely (e.g., using a secrets manager).

How long does it take for an IAM policy change to take effect?

IAM policy changes typically take effect within 60 seconds, but can take up to 80 seconds to propagate across Google's infrastructure. This is due to caching. The exam may test that changes are not instantaneous. For critical changes, you can use the `--etag` flag to ensure you are modifying the latest version of the policy.

What is the difference between `allAuthenticatedUsers` and `allUsers`?

`allUsers` includes any user, whether authenticated or not (i.e., anonymous users). `allAuthenticatedUsers` includes only users who are authenticated with a Google account (including accounts outside your organization). Both are risky if used broadly because they grant access to a wide audience. Always restrict to specific users or service accounts when possible.

What is Workload Identity Federation and when should I use it?

Workload Identity Federation allows you to grant external identities (e.g., from AWS, Azure, or an on-premises identity provider) access to GCP resources without using service account keys. You configure a workload identity pool and provider, then map attributes from the external token to Google Cloud principals. Use it when you have applications running outside GCP that need to access GCP APIs. It is more secure than using service account keys because you avoid managing and distributing keys.

Terms Worth Knowing

Ready to put this to the test?

You've just covered GCP IAM and Service Accounts — now see how well it sticks with free ACE practice questions. Full explanations included, no account needed.

Done with this chapter?