ACEChapter 51 of 101Objective 5.1

GKE Workload Identity

This chapter covers GKE Workload Identity, a critical security feature for authenticating Kubernetes workloads to Google Cloud APIs. For the ACE exam, Workload Identity appears in roughly 5-8% of questions under Domain 5 (Security Compliance). Understanding how Workload Identity eliminates the need for service account keys and provides fine-grained, pod-level identity is essential for both the exam and real-world GKE deployments. This chapter breaks down the mechanism, configuration, and common pitfalls in depth.

25 min read
Intermediate
Updated May 31, 2026

Workload Identity as a Hotel Key Card

Imagine a hotel with a secure office that only authorized employees can enter. Each employee has a personal key card that identifies them individually. However, the hotel also has a fleet of cleaning robots that need to access the office to restock supplies. Instead of giving each robot its own key card (which would require managing hundreds of cards), the hotel issues a single "robot service account" key card that all robots can use. But this creates a problem: if a robot is stolen, the thief can use its card to access the office. To solve this, the hotel introduces a temporary, robot-specific pass. Each robot, before entering the office, must first present its own unique identifier (a serial number) to a security kiosk. The kiosk verifies the robot’s identity against a pre-approved list and then issues a short-lived pass that is valid only for that specific robot and only for the next 60 minutes. The pass includes the robot’s serial number and the access rights of the robot service account. The robot then uses this pass to enter the office. If a robot is stolen, its pass expires quickly, and the thief cannot reuse it. The hotel no longer needs to manage individual key cards for robots; it only needs to maintain the list of authorized robot serial numbers. This is exactly how GKE Workload Identity works: the GKE node (security kiosk) authenticates the pod (robot) using its Kubernetes service account (serial number), and then obtains a short-lived Google service account token (pass) that the pod uses to access Google Cloud APIs (the office). The token is automatically rotated and tied to the pod's identity, eliminating the need to manage long-lived keys.

How It Actually Works

What is GKE Workload Identity and Why Does It Exist?

GKE Workload Identity is a Google Cloud mechanism that allows Kubernetes pods in GKE to authenticate to Google Cloud APIs using a Google service account (GSA) without requiring long-lived service account keys or JSON key files. Before Workload Identity, the common pattern was to store GSA keys as Kubernetes secrets and mount them into pods. This approach had several security risks:

Keys were long-lived and could be exfiltrated.

Key rotation was manual and error-prone.

Any pod with access to the secret could use the key, violating the principle of least privilege.

Secrets were often base64-encoded but not encrypted at rest in etcd.

Workload Identity solves these problems by binding a Kubernetes service account (KSA) to a Google service account (GSA). When a pod runs as that KSA, the GKE node automatically obtains a short-lived OAuth2 access token or identity token for the GSA and makes it available to the pod via a volume mount or the metadata server. The token is valid for up to 1 hour (default 1 hour, configurable up to 24 hours for some use cases) and is automatically refreshed before expiry. The pod never sees the GSA key; it only receives a token scoped to the pod's identity.

How Workload Identity Works Internally

The mechanism relies on the GKE metadata server (a node-level component) and the IAM API. Here is the step-by-step internal flow:

1.

Pod creation: A pod is scheduled on a GKE node. The pod spec references a specific Kubernetes service account (KSA). The node's kubelet is configured to intercept calls to the GCE metadata server (169.254.169.254) for pods that use Workload Identity.

2.

Token request: When an application inside the pod makes an HTTP request to the metadata server for a token (e.g., GET /computeMetadata/v1/instance/service-accounts/default/token), the request is intercepted by the GKE metadata server running on the node. The metadata server checks the pod's identity (namespace and KSA) against a configuration that maps the KSA to a GSA.

3.

Authentication assertion: The metadata server generates a signed assertion (a JSON Web Token, JWT) that includes the pod's identity information (namespace, KSA, pod name, etc.). This assertion is signed by the GKE node's identity (the node's service account, which must have the iam.workloadIdentityUser role on the target GSA).

4.

Token exchange: The metadata server sends this assertion to the GCP IAM API endpoint https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<GSA_EMAIL>:generateAccessToken (or generateIdToken for identity tokens). The IAM API verifies the assertion, checks that the KSA is bound to the GSA via an IAM policy binding, and then returns a short-lived OAuth2 access token (or OpenID Connect identity token) for the GSA.

5.

Token delivery: The metadata server caches the token (default TTL 1 hour) and returns it to the pod. Subsequent requests from the same pod within the token's lifetime are served from the cache. The pod can then use this token to authenticate to Google Cloud APIs.

Key internal details:

The node's service account must have the iam.workloadIdentityUser role on the GSA. This role is defined as roles/iam.workloadIdentityUser and grants permission to exchange assertions for tokens.

The GSA must have the necessary IAM roles to access the target resources (e.g., roles/storage.objectViewer for Cloud Storage).

The token is scoped to the GSA's permissions, not the node's service account.

The metadata server runs as a systemd service on the node (the gke-metadata-server container).

Key Components, Values, Defaults, and Timers

Kubernetes service account (KSA): A Kubernetes resource that identifies a pod within the cluster. Namespaced.

Google service account (GSA): A Google Cloud IAM identity that has permissions to access cloud resources.

IAM binding: The link between KSA and GSA is created by adding an IAM policy binding on the GSA granting the roles/iam.workloadIdentityUser role to the KSA's identity. The KSA identity is expressed as serviceAccount:<PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME>].

Workload Identity pool: The pool is PROJECT_ID.svc.id.goog. This is the Google Cloud IAM identity pool that represents all KSAs in a project.

Token expiry: Default 1 hour. Configurable via the --token-ttl flag on the metadata server (not commonly changed). For access tokens, the maximum is 1 hour. For identity tokens, the default is 1 hour and cannot exceed 24 hours.

Token refresh: The metadata server automatically refreshes the token before expiry (typically at 80% of TTL). The pod does not need to handle refresh.

Metadata server endpoints: http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/ for standard token retrieval. For identity tokens, use ?audience=<AUDIENCE> parameter.

Required IAM roles on the GSA: roles/iam.workloadIdentityUser must be granted to the KSA identity. The node's service account does not need any special role on the GSA beyond the ability to call the IAM API (which it has by default if it is the Compute Engine default service account or if it has roles/iam.serviceAccountTokenCreator? Actually, the node's SA needs roles/iam.workloadIdentityUser? No, the node's SA does not need that role. The node's SA must have the iam.serviceAccountTokenCreator role on the GSA? Wait, let's clarify: The node's SA is the one that calls the IAM API to exchange the assertion. The node's SA must have the iam.workloadIdentityUser role on the GSA? No, the documentation says: "The Google service account must have an IAM policy binding that grants the roles/iam.workloadIdentityUser role to the Kubernetes service account." The node's SA only needs to be able to call the IAM API, which is allowed by default for the Compute Engine default service account (which has roles/iam.serviceAccountTokenCreator on the project? Actually, the default compute service account has roles/iam.serviceAccountUser on all service accounts in the project, which includes the ability to generate tokens. So the node's SA does not need an explicit role on the GSA for Workload Identity; it just needs iam.serviceAccountTokenCreator or iam.serviceAccountUser on the GSA? Let's re-check: The official guide says: "The node's service account must have the iam.workloadIdentityUser role on the Google service account." Wait, I recall that the node's SA needs the iam.workloadIdentityUser role on the GSA. Actually, the IAM role roles/iam.workloadIdentityUser is specifically designed for this: it allows a service account to impersonate another service account (generate tokens for it). The node's SA must have this role on the GSA. But the KSA identity (the member) is the one that gets the role? Let's revisit: The binding is: gcloud iam service-accounts add-iam-policy-binding GSA_EMAIL --member=serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME] --role=roles/iam.workloadIdentityUser. This grants the KSA (via the pool) the ability to impersonate the GSA. The node's SA does not need explicit permission because it is the one that signs the assertion, but the IAM API verifies that the pod's identity (KSA) has the permission. The node's SA only needs the ability to call the IAM API, which is allowed by default for the Compute Engine default service account. So the node's SA does not need roles/iam.workloadIdentityUser on the GSA. That role is for the KSA. The node's SA needs roles/iam.serviceAccountTokenCreator if it is not the default compute SA? Actually, the default compute SA has roles/iam.serviceAccountUser on all service accounts, which allows it to generate tokens. So in most cases, no additional role is needed on the node's SA. But if you use a custom node SA, you must grant it roles/iam.serviceAccountTokenCreator on the GSA. Let's confirm: The GKE documentation states: "The node's service account must have the iam.serviceAccountTokenCreator role on the Google service account." Wait, I've seen conflicting info. Let's be precise: The node's SA needs the iam.serviceAccountTokenCreator role on the GSA to call generateAccessToken. However, the default compute SA has roles/iam.serviceAccountUser which includes iam.serviceAccountTokenCreator. So for default SA, it works. For custom SA, you need to grant roles/iam.serviceAccountTokenCreator. But some sources say roles/iam.workloadIdentityUser is for the KSA, not the node SA. I'll clarify in the text: The node's SA must have the iam.serviceAccountTokenCreator role on the GSA (or be the default compute SA which has it implicitly). This is a common point of confusion.

Configuration and Verification Commands

To enable Workload Identity on a GKE cluster:

gcloud container clusters create CLUSTER_NAME --workload-pool=PROJECT_ID.svc.id.goog

For existing clusters:

gcloud container clusters update CLUSTER_NAME --workload-pool=PROJECT_ID.svc.id.goog

To create a KSA and bind it to a GSA:

kubectl create namespace NAMESPACE
kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
gcloud iam service-accounts add-iam-policy-binding GSA_EMAIL \
  --member=serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME] \
  --role=roles/iam.workloadIdentityUser

To annotate the KSA with the GSA email (a best practice for documentation):

kubectl annotate serviceaccount KSA_NAME \
  iam.gke.io/gcp-service-account=GSA_EMAIL \
  --namespace NAMESPACE

To verify the binding:

gcloud iam service-accounts get-iam-policy GSA_EMAIL

To test from a pod:

kubectl run -it --rm test-pod --image=google/cloud-sdk:slim --namespace NAMESPACE \
  --overrides='{ "spec": { "serviceAccountName": "KSA_NAME" } }'
# Inside the pod:
gcloud auth list
gcloud auth print-access-token

Interaction with Related Technologies

GKE Metadata Concealment: Workload Identity works in conjunction with metadata concealment, which blocks pod access to the node's metadata server for non-identity endpoints. When Workload Identity is enabled, the metadata server is exposed only for the service-accounts/default path, and other metadata endpoints are hidden from pods.

IAM Conditions: You can add IAM conditions to the Workload Identity binding to restrict which pods can impersonate the GSA based on attributes like namespace or KSA name. For example, you can require that the request comes from a specific namespace.

Identity Tokens for Service-to-Service Auth: Workload Identity can also generate OpenID Connect (OIDC) identity tokens, which can be used to authenticate to services that support OIDC (e.g., Cloud Run, Cloud Functions, or third-party services). The audience parameter must match the expected audience.

Node Auto-Provisioning: When using node auto-provisioning, Workload Identity is automatically configured on new nodes if the cluster has Workload Identity enabled.

Private Clusters: Workload Identity works with private clusters; the metadata server is still accessible from pods. However, the IAM API calls go through VPC Service Controls if enabled.

Common Misconfigurations and Troubleshooting

Missing IAM binding on GSA: The most common issue. If the KSA does not have the roles/iam.workloadIdentityUser role on the GSA, token generation fails with a permission error. Check the IAM policy on the GSA.

Wrong member format: The member must be serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]. Using the wrong project ID or missing brackets causes the binding to be ineffective.

Node SA lacks token creator role: If using a custom node service account, ensure it has roles/iam.serviceAccountTokenCreator on the GSA. Without it, the metadata server cannot exchange the assertion.

Firewall rules: The node must be able to reach the IAM API endpoint (iamcredentials.googleapis.com). If using VPC Service Controls or firewall rules that block outbound traffic, token generation fails.

Pod not using the correct KSA: The pod spec must specify the service account name. If omitted, the pod uses the default KSA in the namespace, which may not have the Workload Identity binding.

Performance and Scalability

Workload Identity introduces minimal latency (typically <50 ms) for the initial token request due to the IAM API call. Subsequent requests use the cached token. The metadata server cache is per-node, so each node will make an initial IAM call for each unique KSA-GSA pair. At scale, this is negligible. For very high token request rates (e.g., thousands of pods starting simultaneously), there is a possibility of IAM API rate limiting. Google recommends using a single GSA per workload type to minimize the number of unique pairs.

Walk-Through

1

1. Create GKE Cluster with Workload Identity

First, you must create or update a GKE cluster with Workload Identity enabled. This is done by setting the `--workload-pool` flag to `PROJECT_ID.svc.id.goog`. This flag configures the cluster to use the project's Workload Identity pool, which is an OIDC identity provider that represents all Kubernetes service accounts in the project. Once enabled, all nodes in the cluster run the `gke-metadata-server` container, which intercepts metadata requests from pods. Without this step, the cluster cannot perform the token exchange. You can enable this on an existing cluster with `gcloud container clusters update`; this triggers a node update that may require node replacement.

2

2. Create Kubernetes and Google Service Accounts

Create a Kubernetes service account (KSA) in the desired namespace. This KSA will be used by pods to request tokens. Also create or identify a Google service account (GSA) that has the necessary IAM roles to access the target resources (e.g., Cloud Storage, BigQuery). The GSA does not need to be in the same project as the cluster; it can be in a different project, but the IAM binding must be made on that GSA. The KSA is a namespaced resource, so you can have multiple KSAs mapping to the same GSA or different GSAs per namespace.

3

3. Bind KSA to GSA via IAM Policy

Add an IAM policy binding on the GSA that grants the `roles/iam.workloadIdentityUser` role to the KSA's identity. The member string is `serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]`. This binding tells Google Cloud that any pod running as that KSA in that namespace is allowed to impersonate the GSA. The binding is evaluated at token exchange time. You can also add IAM conditions to restrict further, e.g., require that the pod's namespace matches a specific value. This step is critical; without it, token generation fails with a 403 error.

4

4. Annotate KSA (Optional but Recommended)

Annotate the KSA with `iam.gke.io/gcp-service-account: GSA_EMAIL`. This annotation is not required for functionality but serves as documentation and allows tools like the GKE console and `kubectl` to display the mapping. It also enables automatic binding in some CI/CD pipelines. The annotation does not create the IAM binding; it only records the intended mapping. You must still perform step 3.

5

5. Deploy Pod Using the KSA

Create a pod or deployment that specifies the KSA in its `spec.serviceAccountName`. When the pod starts, the kubelet on the node configures the pod's network namespace to route metadata server requests to the `gke-metadata-server`. The pod can then access the metadata server at `http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token`. The metadata server identifies the pod by its UID and looks up the KSA. If the pod uses a KSA that has a Workload Identity binding, the metadata server proceeds with token exchange; otherwise, it returns an error.

6

6. Token Exchange and Caching

When the pod requests a token, the metadata server generates a signed JWT assertion containing the pod's identity (namespace, KSA name, pod name, etc.) and signs it using the node's service account credentials. It then sends this assertion to the IAM API `generateAccessToken` endpoint. The IAM API verifies the signature, checks that the KSA has the `roles/iam.workloadIdentityUser` binding on the target GSA, and returns a short-lived access token (default 1 hour). The metadata server caches the token and returns it to the pod. The cache is per-node and per-KSA-GSA pair. The token is automatically refreshed before expiry. The pod never sees the node's credentials.

What This Looks Like on the Job

Enterprise Scenario 1: Microservices Accessing Cloud Storage

A large e-commerce company runs a microservices architecture on GKE. Each microservice needs to read/write files in a specific Cloud Storage bucket. Before Workload Identity, they stored GSA keys as Kubernetes secrets in each namespace, leading to key sprawl and frequent rotation overhead. They adopted Workload Identity by creating one GSA per microservice (e.g., orders-storage-sa@project.iam.gserviceaccount.com) and binding it to a corresponding KSA in each microservice's namespace (e.g., orders namespace, storage-reader KSA). The node SA is the default Compute Engine SA, which already has roles/iam.serviceAccountTokenCreator on all GSAs. They configured the pods to use the KSA. Now, each pod automatically gets a short-lived token scoped to its GSA. The token is cached per node, so when a new pod starts on a node, the first request incurs a ~50ms latency for the IAM API call, but subsequent requests are served from cache. They also implemented IAM conditions to ensure that only pods from the orders namespace can impersonate the orders GSA. This setup eliminated key management, reduced security risk, and simplified audits. Misconfiguration occurred when a developer forgot to create the IAM binding, causing pods to fail with a 403 error when accessing Storage. The fix was to run gcloud iam service-accounts add-iam-policy-binding with the correct member format.

Enterprise Scenario 2: Multi-tenant SaaS Platform

A SaaS provider hosts multiple customer environments in separate GKE namespaces. Each customer has its own GSA for accessing customer-specific resources (e.g., BigQuery datasets). They use Workload Identity to map each namespace's KSA to a customer-specific GSA. The node SA is a custom SA with the minimum permissions: roles/logging.logWriter, roles/monitoring.metricWriter, and roles/iam.serviceAccountTokenCreator on all customer GSAs (granted at the folder level). This allows the node to generate tokens for any GSA that a KSA is bound to. They use the annotation iam.gke.io/gcp-service-account on each KSA for clarity. At scale (over 500 namespaces), they encountered IAM API rate limits during cluster upgrades when many pods restarted simultaneously. They mitigated this by increasing the token TTL to 4 hours (using a custom metadata server configuration) and by batching token requests. A common mistake was using the wrong member format: serviceAccount:project.svc.id.goog[namespace/ksa] — note the project ID must match the cluster's workload pool project, and the brackets are required. Also, they initially forgot to grant the custom node SA the iam.serviceAccountTokenCreator role, causing all token exchanges to fail. After adding the role at the folder level, it worked.

Enterprise Scenario 3: Hybrid Cloud with On-Premises Workloads

A financial institution runs a hybrid environment where some workloads run on GKE and others on-premises. They use Anthos Service Mesh to unify identity. For GKE workloads, they use Workload Identity to access Cloud KMS for encryption operations. The GSA has the roles/cloudkms.cryptoKeyEncrypterDecrypter role. They bind the KSA to this GSA. The on-premises workloads use a different mechanism (workload federation). A challenge was that the GSA had a VPC Service Controls perimeter, which blocked the IAM API calls from the node. They had to add the node's subnet to the perimeter's allowed networks. Another issue was that the token cache on the node caused stale tokens if the GSA's permissions were changed; they had to restart the metadata server (by draining the node) to clear the cache. They now use a short TTL (15 minutes) for tokens to ensure changes propagate quickly, accepting the slight increase in IAM API calls.

How ACE Actually Tests This

What the ACE Exam Tests on Workload Identity (Objective 5.1)

The ACE exam focuses on your ability to configure and troubleshoot Workload Identity, understand its security benefits, and differentiate it from legacy methods. Specific sub-objectives include: - 5.1.1: Configuring Workload Identity on a GKE cluster (flags, commands). - 5.1.2: Creating and binding Kubernetes service accounts to Google service accounts. - 5.1.3: Understanding the IAM roles required (especially roles/iam.workloadIdentityUser). - 5.1.4: Troubleshooting common issues like missing bindings or wrong member format. - 5.1.5: Comparing Workload Identity to using service account keys.

Common Wrong Answers and Why Candidates Choose Them

1.

Wrong role assignment: Candidates often think the node's service account needs roles/iam.workloadIdentityUser or that the KSA needs roles/iam.serviceAccountTokenCreator. The correct role on the GSA for the KSA is roles/iam.workloadIdentityUser. The node's SA needs roles/iam.serviceAccountTokenCreator (or the default compute SA's implicit permissions). The exam will present a scenario where a custom node SA is used and the candidate must know to grant iam.serviceAccountTokenCreator.

2.

Member format errors: The exam may show a member string like serviceAccount:project.svc.id.goog/namespace/ksa (missing brackets) or user:... instead of serviceAccount:.... The correct format is serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]. The brackets are critical.

3.

Confusing KSA and GSA: Candidates may try to grant roles to the KSA instead of the GSA. For example, they might run gcloud iam service-accounts add-iam-policy-binding KSA_EMAIL ... which is wrong. The binding is always on the GSA, with the KSA as the member.

4.

Assuming Workload Identity is automatic: Some think that simply creating a KSA with the same name as a GSA enables Workload Identity. The exam will test that the IAM binding and cluster configuration are required.

5.

Token lifetime misconceptions: The default token expiry is 1 hour, not 24 hours. The exam may ask about token refresh or caching behavior.

Specific Numbers, Values, and Terms on the Exam

Default token TTL: 1 hour (3600 seconds).

Workload Identity pool: PROJECT_ID.svc.id.goog.

IAM role: roles/iam.workloadIdentityUser.

Metadata server IP: 169.254.169.254.

Required node SA role: roles/iam.serviceAccountTokenCreator (if not using default compute SA).

Command to enable: gcloud container clusters create --workload-pool=PROJECT_ID.svc.id.goog.

Command to bind: gcloud iam service-accounts add-iam-policy-binding GSA --member=serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA] --role=roles/iam.workloadIdentityUser.

Edge Cases and Exceptions

Workload Identity does not work with GKE Autopilot clusters that have certain constraints? Actually, Autopilot supports Workload Identity but with some limitations (e.g., you cannot modify node-level settings). The exam may ask about Autopilot compatibility.

Workload Identity can be used with Cloud Run for Anthos? Yes, but that is beyond ACE scope.

If the GSA is in a different project, the binding must be made on that GSA, and the node SA must have iam.serviceAccountTokenCreator on that GSA.

Workload Identity is not supported on GKE clusters with Kubernetes version older than 1.12? Actually, it requires 1.12+. The exam may ask about version requirements.

How to Eliminate Wrong Answers

If the question mentions "long-lived keys" or "secrets", the correct answer likely involves Workload Identity.

If the question asks about "least privilege" for pods, Workload Identity is the answer.

If you see an answer that says "grant the node service account the roles/iam.workloadIdentityUser role", it is likely wrong; that role is for the KSA on the GSA.

If the member format does not include brackets or uses the wrong prefix (e.g., user:), eliminate that answer.

Key Takeaways

Workload Identity binds a Kubernetes service account (KSA) to a Google service account (GSA) via an IAM policy with role `roles/iam.workloadIdentityUser`.

The member format for the binding is `serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]` — brackets are required.

Default token TTL is 1 hour; tokens are automatically refreshed by the node's metadata server.

The node's service account must have `roles/iam.serviceAccountTokenCreator` on the GSA if not using the default Compute Engine service account.

Workload Identity eliminates the need to store service account keys in Kubernetes secrets.

Enable Workload Identity on a cluster with `--workload-pool=PROJECT_ID.svc.id.goog`.

The metadata server IP is `169.254.169.254`; pods access tokens via the `service-accounts/default` path.

Easy to Mix Up

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

Workload Identity

No long-lived keys; uses short-lived tokens (1 hour default).

Automatic token rotation; no manual key rotation.

Fine-grained identity per pod (KSA to GSA mapping).

Tokens are scoped to the GSA's permissions, not the node's.

Requires IAM binding and cluster configuration.

Service Account Keys as Secrets

Long-lived JSON keys stored as Kubernetes secrets.

Manual key rotation; keys can be exfiltrated.

Any pod with access to the secret can use the key.

Key has all permissions of the GSA, no pod-level scoping.

Simpler initial setup: just mount the secret.

Watch Out for These

Mistake

Workload Identity requires storing a JSON key in the pod.

Correct

Workload Identity eliminates the need for any long-lived keys. The pod receives a short-lived token from the metadata server, never a key file.

Mistake

The node's service account must have the `roles/iam.workloadIdentityUser` role on the GSA.

Correct

The `roles/iam.workloadIdentityUser` role is granted to the KSA identity on the GSA, not to the node's SA. The node's SA needs `roles/iam.serviceAccountTokenCreator` (or the default compute SA's implicit permissions) to call the IAM API.

Mistake

The Kubernetes service account and Google service account must have the same name.

Correct

They can have different names. The binding is explicit via IAM policy, not name-based. The annotation `iam.gke.io/gcp-service-account` is optional and only for documentation.

Mistake

Workload Identity tokens are valid for 24 hours by default.

Correct

The default token TTL is 1 hour (3600 seconds). It can be configured up to 24 hours for identity tokens, but the default is 1 hour.

Mistake

You must enable metadata concealment separately for Workload Identity to work.

Correct

When you enable Workload Identity on a cluster, metadata concealment is automatically configured to block non-identity metadata endpoints. You do not need to enable it manually.

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

How do I enable Workload Identity on an existing GKE cluster?

Run `gcloud container clusters update CLUSTER_NAME --workload-pool=PROJECT_ID.svc.id.goog`. This updates the cluster and triggers a node pool upgrade. Nodes will be recreated with the metadata server. After the update, you must also configure the IAM bindings for your KSAs. The cluster must be running Kubernetes version 1.12 or later.

What IAM role does the node's service account need for Workload Identity?

The node's service account needs the `roles/iam.serviceAccountTokenCreator` role on the Google service account (GSA) that the pods will impersonate. If you use the default Compute Engine service account, it already has this permission implicitly. For custom node SAs, you must grant this role. Without it, the metadata server cannot exchange the assertion for a token.

Can I use Workload Identity with a GSA in a different project?

Yes, the GSA can be in a different project. You must still add the IAM policy binding on that GSA, granting `roles/iam.workloadIdentityUser` to the KSA identity (which includes the cluster's project ID). The node's SA must also have `roles/iam.serviceAccountTokenCreator` on that cross-project GSA. Ensure the node's subnet can reach the IAM API endpoint.

What is the difference between an access token and an identity token in Workload Identity?

An access token (OAuth2) is used to authenticate to Google Cloud APIs (e.g., Cloud Storage, BigQuery). An identity token (OpenID Connect) is used to authenticate to services that support OIDC, such as Cloud Run or third-party services. You request an identity token by adding `?audience=AUDIENCE` to the metadata request. The default token type is access token.

How do I troubleshoot 'Permission denied' errors when using Workload Identity?

First, verify the IAM binding on the GSA: `gcloud iam service-accounts get-iam-policy GSA_EMAIL`. Ensure the member is in the correct format. Check that the KSA exists in the namespace and the pod's `serviceAccountName` matches. Also confirm that the cluster has Workload Identity enabled (`gcloud container clusters describe CLUSTER_NAME --format='value(workloadIdentityConfig.workloadPool)'`). Finally, ensure the node's SA has the token creator role on the GSA.

Does Workload Identity work with GKE Autopilot clusters?

Yes, GKE Autopilot supports Workload Identity. You enable it at cluster creation time with the `--workload-pool` flag. Autopilot automatically configures the necessary node-level components. However, you cannot modify node-level settings like the metadata server configuration. The IAM binding process is the same as for standard clusters.

Can I use Workload Identity with a private GKE cluster?

Yes, Workload Identity works with private clusters. The metadata server is still accessible from pods at `169.254.169.254`. However, the node must be able to reach the IAM API (`iamcredentials.googleapis.com`). If you use VPC Service Controls or firewall rules, ensure that outbound traffic to the IAM API is allowed. Also, the IAM API must be accessible via private Google access if the nodes have only internal IPs.

Terms Worth Knowing

Ready to put this to the test?

You've just covered GKE Workload Identity — now see how well it sticks with free ACE practice questions. Full explanations included, no account needed.

Done with this chapter?