# How to Configure Workload Identity Binding for GKE: Step-by-Step Implementation Guide

> Learn how to configure Workload Identity binding for GKE with this step-by-step guide. Secure your GKE workloads by granting granular IAM permissions.

- Repository: [Google/skills](https://github.com/google/skills)
- Tags: how-to-guide
- Published: 2026-09-02

---

**Configure Workload Identity binding for GKE by creating an IAM policy binding that grants the `roles/iam.workloadIdentityUser` role to your Kubernetes Service Account (KSA) on a Google Service Account (GSA), annotating the KSA with `iam.gke.io/gcp-service-account=<gsa-email>`, and deploying pods with the `iam.gke.io/gke-metadata-server-enabled: "true"` node selector.**

According to the implementation patterns documented in the `google/skills` repository, specifically within [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md), configuring Workload Identity binding enables GKE workloads to impersonate Google Cloud identities without storing long-lived service account keys in your cluster. This approach leverages the GKE metadata server to inject short-lived OAuth tokens automatically, allowing Google client libraries to authenticate seamlessly while maintaining strict least-privilege controls.

## Understanding the Workload Identity Architecture

Before implementing the configuration, it is essential to understand the trust relationship between Kubernetes and Google Cloud identities as defined in the source code.

### KSA to GSA Trust Relationship

The foundation of Workload Identity is an IAM policy binding stored on the GSA itself. As specified in [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md), you must grant the `roles/iam.workloadIdentityUser` role to a member identifier formatted as:

```

serviceAccount:<PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME>]

```

This binding explicitly allows the Kubernetes Service Account to impersonate the Google Service Account. The IAM policy resides in your GCP project and serves as the authoritative trust anchor for the entire Workload Identity flow.

### Metadata Server Integration

GKE clusters running Workload Identity expose a metadata server enabled via the `iam.gke.io/gke-metadata-server-enabled` node selector. When a pod uses an annotated KSA, this metadata server intercepts token requests at `http://metadata.google.internal` and issues short-lived identity tokens valid for the mapped GSA. This mechanism eliminates the need for JSON key files mounted as Kubernetes secrets and handles automatic token rotation transparently.

## Step-by-Step Configuration Guide

Follow these precise steps to configure Workload Identity binding for your GKE cluster, referencing the exact commands and manifests from the `google/skills` repository.

### Step 1: Create the Namespace and Kubernetes Service Account

Create a dedicated namespace and KSA to isolate your workload and maintain clear identity boundaries.

```bash
kubectl create namespace workload-identity-test-ns
kubectl create serviceaccount <ksa-name> --namespace workload-identity-test-ns

```

Replace `<ksa-name>` with your desired Kubernetes Service Account name.

### Step 2: Establish the IAM Policy Binding

Configure the critical trust relationship by binding the KSA to the GSA. Execute the `gcloud iam service-accounts add-iam-policy-binding` command, ensuring you use the exact member identifier format documented in the source code.

```bash
gcloud iam service-accounts add-iam-policy-binding \
    <gsa-name>@<project-id>.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:<project-id>.svc.id.goog[workload-identity-test-ns/<ksa-name>]"

```

This command modifies the IAM policy on the GSA to recognize the KSA as a valid workload identity user.

### Step 3: Annotate the KSA with GSA Identity

Link the Kubernetes Service Account to the Google Service Account using the required annotation key `iam.gke.io/gcp-service-account`. This annotation is read by the GKE metadata server to determine which GSA to impersonate for pods using this KSA.

```bash
kubectl annotate serviceaccount <ksa-name> \
    --namespace workload-identity-test-ns \
    iam.gke.io/gcp-service-account=<gsa-name>@<project-id>.iam.gserviceaccount.com

```

### Step 4: Deploy a Pod with Workload Identity Enabled

Use the manifest from [`assets/workload-identity-pod.yaml`](https://github.com/google/skills/blob/main/assets/workload-identity-pod.yaml) in the `google/skills` repository to deploy a test pod. The specification must include the `iam.gke.io/gke-metadata-server-enabled: "true"` node selector and reference your KSA in the `serviceAccountName` field.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: workload-identity-test
  namespace: workload-identity-test-ns
spec:
  serviceAccountName: my-ksa   # <-- replace with your KSA

  automountServiceAccountToken: false
  containers:
  - image: gcr.io/google.com/cloudsdktool/cloud-sdk
    name: workload-identity-test
    command: ["sleep", "infinity"]
  nodeSelector:
    iam.gke.io/gke-metadata-server-enabled: "true"
  securityContext:
    runAsNonRoot: true
    runAsUser: 65532
    seccompProfile:
      type: RuntimeDefault

```

Deploy the pod using:

```bash
kubectl apply -f assets/workload-identity-pod.yaml -n workload-identity-test-ns

```

### Step 5: Verify Token Acquisition

Validate the configuration by executing a shell in the running pod and querying the metadata server for an access token.

```bash
kubectl exec -it workload-identity-test -n workload-identity-test-ns -- /bin/bash
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

```

A successful JSON response containing an `access_token` confirms that the Workload Identity binding is properly configured and the pod can impersonate the GSA. You can further verify functionality by running Google Cloud CLI commands inside the pod, such as `gcloud storage ls`, to confirm API access.

## Security Best Practices

When you configure Workload Identity binding for GKE, adhere to these security principles derived from the `google/skills` implementation:

- **Least-Privilege IAM Roles**: Grant the GSA only the specific IAM roles required by your workload (e.g., `roles/storage.objectViewer`), limiting the blast radius of potential compromises.
- **Disable Legacy Token Auto-Mount**: Set `automountServiceAccountToken: false` in your pod spec, as shown in the example manifest, to prevent legacy Kubernetes service account tokens from being mounted unnecessarily.
- **Namespace Isolation**: Use dedicated namespaces for KSAs to prevent cross-namespace identity confusion and maintain clear audit trails for which workloads can assume specific Google identities.

## Summary

- **Configure Workload Identity binding** by creating an IAM policy binding between your KSA and GSA using the `roles/iam.workloadIdentityUser` role and the member format `serviceAccount:<PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME>]`.
- **Annotate the KSA** with `iam.gke.io/gcp-service-account=<gsa-email>` to establish the identity mapping recognized by the GKE metadata server.
- **Enable metadata server injection** by setting the node selector `iam.gke.io/gke-metadata-server-enabled: "true"` on your pods.
- **Verify functionality** by querying the metadata server endpoint from within a running pod to confirm short-lived token issuance.
- **Reference implementation** examples are available in [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md) and [`assets/workload-identity-pod.yaml`](https://github.com/google/skills/blob/main/assets/workload-identity-pod.yaml) within the `google/skills` repository.

## Frequently Asked Questions

### What is the exact IAM member format for Workload Identity binding?

The IAM member format is `serviceAccount:<PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME>]`. This unique identifier allows Google Cloud IAM to recognize Kubernetes Service Accounts as valid principals for policy bindings, as implemented in the `google/skills` repository's GKE security guides. The format must include the project ID, the literal string `.svc.id.goog`, and the exact namespace and KSA name in brackets.

### Why does my pod need the `iam.gke.io/gke-metadata-server-enabled` node selector?

This node selector ensures the pod is scheduled on nodes running the GKE metadata server, which is the component responsible for intercepting metadata requests and issuing short-lived OAuth tokens for the mapped Google Service Account. Without this selector, the pod cannot obtain valid credentials through Workload Identity and will fail to authenticate with Google Cloud APIs.

### How do I troubleshoot 403 errors from the metadata server?

First, verify that the IAM binding includes the correct namespace and KSA name in the member identifier, as typos here are the most common cause of authentication failures. Then confirm that the KSA annotation key `iam.gke.io/gcp-service-account` exactly matches the GSA email address. Finally, ensure the GSA has the necessary GCP IAM roles granted directly to it, not just to the KSA binding.

### Can I use Workload Identity with existing Google Service Accounts?

Yes, you can bind existing GSAs to new or existing KSAs without recreating the GSA. Simply add the IAM policy binding using `gcloud iam service-accounts add-iam-policy-binding` with the appropriate KSA member format, then annotate the KSA accordingly. This allows you to migrate existing workloads to Workload Identity without rotating service account keys or changing application code.