# How to Configure Workload Identity for GKE Pods

> Learn to configure Workload Identity for GKE pods. Securely authenticate GKE pods to Google Cloud APIs without service account keys. Master GKE security today.

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

---

**Workload Identity enables a Kubernetes Service Account (KSA) to impersonate a Google Service Account (GSA) so that GKE pods can securely authenticate to Google Cloud APIs without managing long-lived service account keys.**

Configuring Workload Identity for GKE pods eliminates the security risks of storing JSON keys in Secrets or container images. According to the `google/skills` repository, this configuration requires binding IAM permissions at the Google Cloud layer and annotating the KSA to establish the impersonation mapping. Once configured, the GKE metadata server automatically injects short-lived OAuth 2.0 tokens into pods.

## Prerequisites: Enable Workload Identity on the Cluster

Before configuring individual pods, the GKE cluster must have Workload Identity enabled at the platform level. As documented in [`skills/cloud/gke-platform-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-platform-security/SKILL.md), this requires setting the `workloadPool` parameter to `<project>.svc.id.goog` during cluster creation or modification.

If creating a new cluster, include the `--workload-pool` flag:

```bash
gcloud container clusters create my-cluster \
  --workload-pool=my-project.svc.id.goog \
  --region=us-central1

```

For existing clusters, verify that the `workloadMetadataConfig.mode` is set to `GKE_METADATA` in the node pool configuration, as detailed in [`skills/cloud/gke-basics/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-basics/SKILL.md).

## Step-by-Step Configuration

The complete configuration process involves three main components: creating the Kubernetes Service Account, granting IAM permissions on the Google Service Account, and linking them via annotation.

### Create a Kubernetes Service Account

First, create a namespace and KSA that will represent the pod's identity within the cluster. The [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md) file provides the standard pattern for this step.

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: workload-identity-test-ns
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-ksa
  namespace: workload-identity-test-ns

```

Apply this configuration using `kubectl apply -f ksa.yaml`.

### Grant IAM Permissions on the Google Service Account

Next, authorize the KSA to impersonate the GSA by granting the `roles/iam.workloadIdentityUser` role. The IAM binding must reference the KSA using the specific format `serviceAccount:<project>.svc.id.goog[<namespace>/<ksa-name>]`.

Execute the binding command as shown in [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md):

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

```

This command grants the specific KSA permission to generate short-lived credentials for the GSA.

### Annotate the Kubernetes Service Account

The final linkage step requires annotating the KSA with the target GSA's email address. GKE reads this annotation to determine which Google identity tokens to serve when pods query the metadata server.

Update the KSA manifest to include the `iam.gke.io/gcp-service-account` annotation:

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-ksa
  namespace: workload-identity-test-ns
  annotations:
    iam.gke.io/gcp-service-account: my-gsa@my-project.iam.gserviceaccount.com

```

Apply the updated configuration. GKE now recognizes that pods running as `my-ksa` should receive tokens for `my-gsa`.

### Deploy a Pod Using the Service Account

Reference the KSA in the pod specification. No volume mounts or environment variables containing credentials are required.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-workload-identity
  namespace: workload-identity-test-ns
spec:
  serviceAccountName: my-ksa
  containers:
  - name: app
    image: python:3.11
    command: ["python", "-c"]
    args:
      - |
        from google.cloud import storage
        client = storage.Client()
        buckets = list(client.list_buckets())
        print("Buckets:", buckets)

```

When this pod starts, the Google Cloud client library automatically queries `http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token` to obtain a valid access token.

## How It Works

The Workload Identity mechanism operates through the GKE metadata server running on each node. When a pod with an annotated KSA requests a token, the metadata server validates the pod's identity against the IAM binding and mints a short-lived OAuth 2.0 access token for the associated GSA.

Key architectural characteristics include:

- **Token lifecycle**: Access tokens expire after one hour and are automatically refreshed by client libraries
- **No key material**: JSON service account keys are never stored in etcd, Secrets, or container images
- **Standard client behavior**: Applications use default credential chains without modification

The [`skills/cloud/gke-workload-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-workload-security/SKILL.md) file emphasizes that this approach eliminates the need to rotate long-lived credentials while maintaining strict identity boundaries between namespaces.

## Summary

- **Enable Workload Identity** at the cluster level using `--workload-pool=<project>.svc.id.goog` as documented in [`skills/cloud/gke-platform-security/SKILL.md`](https://github.com/google/skills/blob/main/skills/cloud/gke-platform-security/SKILL.md)
- **Create a KSA** in your target namespace to serve as the pod's identity
- **Bind IAM permissions** using `gcloud iam service-accounts add-iam-policy-binding` with the `roles/iam.workloadIdentityUser` role and the member format `serviceAccount:<project>.svc.id.goog[<ns>/<ksa>]`
- **Annotate the KSA** with `iam.gke.io/gcp-service-account: <gsa>@<project>.iam.gserviceaccount.com` to establish the impersonation link
- **Deploy pods** referencing the KSA in `spec.serviceAccountName` without mounting any credential files

## Frequently Asked Questions

### What is the difference between Workload Identity and traditional service account keys?

**Traditional service account keys** are long-lived JSON files that must be manually rotated and securely stored in Kubernetes Secrets, creating persistent breach risks. **Workload Identity** uses short-lived tokens (maximum one-hour lifetime) minted dynamically by the GKE metadata server, eliminating key storage entirely and leveraging IAM for access control. As implemented in the `google/skills` repository examples, Workload Identity represents the recommended security posture for GKE workloads.

### How do I verify that Workload Identity is working in my pod?

Execute a shell inside the running pod and query the metadata server directly using `curl`:

```bash
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

```

If Workload Identity is configured correctly, the response contains a valid OAuth 2.0 access token. You can also inspect the token's claims using `jwt.io` to verify that the `email` claim matches your target GSA.

### Can I use Workload Identity with multiple Google Cloud projects?

Yes, but the IAM binding must exist in the project that owns the Google Service Account. If your GKE cluster runs in Project A but needs to impersonate a GSA in Project B, you must run the `gcloud iam service-accounts add-iam-policy-binding` command in Project B while referencing the KSA from Project A using the full `serviceAccount:<project-a>.svc.id.goog[<ns>/<ksa>]` identifier.

### What permissions does the KSA need in the Kubernetes cluster?

The Kubernetes Service Account itself requires no special RBAC permissions within the cluster to use Workload Identity. The authorization occurs entirely at the Google Cloud IAM layer through the `roles/iam.workloadIdentityUser` binding. However, the pod must be able to reach the metadata server at `169.254.169.254`, which requires standard network connectivity without restrictive network policies blocking that address.