How to Implement Workload Identity Federation for GKE: A Complete Guide

Workload Identity Federation for GKE eliminates the need for static service account keys by allowing Kubernetes Service Accounts to impersonate Google Service Accounts using short-lived, automatically rotated tokens.

Implementing Workload Identity Federation is the recommended approach for GKE workloads that interact with Google Cloud APIs. This article provides a complete implementation guide based on the production-ready patterns found in the google/skills repository, covering the exact IAM bindings, annotations, and pod specifications required to secure your cluster.

Architectural Overview

Workload Identity Federation relies on a trust relationship between your GKE cluster and Google Cloud IAM. When enabled, the GKE metadata server intercepts token requests from pods and exchanges Kubernetes Service Account (KSA) credentials for Google Service Account (GSA) access tokens.

The architecture involves four key components:

  • Kubernetes Service Account (KSA) – The identity inside the cluster. Pods run under a KSA that is annotated with the target GSA email address.
  • Google Service Account (GSA) – The IAM identity that holds permissions for Google Cloud resources.
  • IAM Policy Binding – Grants the specific KSA permission to impersonate the GSA through the roles/iam.workloadIdentityUser role.
  • Workload Identity Pool – Enabled at the cluster level by setting workloadPool to <PROJECT_ID>.svc.id.goog, allowing the cluster to participate in the federation.

According to the source code in google/skills, this configuration is codified in the gke-workload-security skill under the Configure Workload Identity section (skills/cloud/gke-workload-security/SKILL.md).

Prerequisites

Before implementing Workload Identity Federation, ensure your cluster is properly configured:

  1. Enable Workload Identity on the cluster by setting the --workload-pool flag to your project ID: <PROJECT_ID>.svc.id.goog.
  2. Ensure GKE metadata server is enabled on your node pools (default on newer versions).
  3. Have kubectl and gcloud CLI tools installed with appropriate permissions to create Service Accounts and modify IAM policies.

Step 1: Create the Kubernetes Service Account

First, create a dedicated namespace and Kubernetes Service Account for your workload. This KSA will later be annotated to link it to a Google Service Account.


# Create a dedicated namespace

kubectl create namespace workload-identity-test-ns

# Create the Kubernetes Service Account

kubectl create serviceaccount my-ksa \
  --namespace workload-identity-test-ns

Step 2: Create and Configure the Google Service Account

Create a Google Service Account in your GCP project and grant it the specific IAM roles your workload requires. This example grants read-only access to Cloud Storage.


# Create the Google Service Account

gcloud iam service-accounts create my-gsa \
  --project $PROJECT_ID

# Grant the GSA necessary permissions (e.g., Storage Object Viewer)

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:my-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
  --role "roles/storage.objectViewer"

Step 3: Bind the KSA to the GSA

Establish the trust relationship by binding the KSA to the GSA. This IAM binding allows the specific KSA to impersonate the GSA when requesting access tokens.

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

The member string format <PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME> is critical and must match exactly.

Step 4: Annotate the Kubernetes Service Account

Annotate your KSA with the GSA email address. This annotation tells the GKE metadata server which Google Service Account to impersonate when pods use this KSA.

kubectl annotate serviceaccount my-ksa \
  --namespace workload-identity-test-ns \
  iam.gke.io/gcp-service-account=my-gsa@$PROJECT_ID.iam.gserviceaccount.com

Step 5: Deploy the Workload

Deploy a pod that uses the annotated KSA. The pod specification must reference the KSA name and ensure the workload runs on nodes with the metadata server enabled.

The following manifest is based on skills/cloud/gke-workload-security/assets/workload-identity-pod.yaml from the google/skills repository:

apiVersion: v1
kind: Pod
metadata:
  name: workload-identity-test
  namespace: workload-identity-test-ns
spec:
  serviceAccountName: my-ksa
  automountServiceAccountToken: false
  containers:
  - name: workload-identity-test
    image: gcr.io/google.com/cloudsdktool/cloud-sdk
    command: ["sleep", "infinity"]
    securityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
  nodeSelector:
    iam.gke.io/gke-metadata-server-enabled: "true"

Once deployed, the pod can immediately call Google Cloud APIs using standard client libraries. The client libraries automatically detect the Workload Identity configuration, contact the metadata server to obtain a short-lived token for the GSA, and authenticate requests without any key files present in the container.

Verification

To verify the setup, exec into the running pod and test access to a Google Cloud service:

kubectl exec -it workload-identity-test \
  --namespace workload-identity-test-ns -- /bin/bash

# Inside the pod, verify you can access Cloud Storage

gsutil ls gs://your-bucket-name

If the IAM bindings and annotations are correct, the command will succeed without any service account key files mounted in the pod.

Summary

Implementing Workload Identity Federation for GKE requires coordinating Kubernetes resources with Google Cloud IAM:

  • Enable Workload Identity at the cluster level by configuring the workloadPool.
  • Create a Kubernetes Service Account and annotate it with the target Google Service Account email using iam.gke.io/gcp-service-account.
  • Grant the KSA permission to impersonate the GSA via the roles/iam.workloadIdentityUser IAM binding.
  • Deploy pods using the KSA; the GKE metadata server automatically handles token exchange.
  • Store no long-lived keys in your containers, eliminating secret rotation and leakage risks.

Frequently Asked Questions

What is the difference between Workload Identity and Workload Identity Federation?

Workload Identity is Google Cloud's implementation of Workload Identity Federation specifically for GKE. While Workload Identity Federation is the general mechanism for accessing Google Cloud resources from external identity providers (like AWS, Azure, or on-premise OIDC), GKE Workload Identity uses the same underlying technology to allow Kubernetes Service Accounts to impersonate Google Service Accounts without static credentials.

Do I need to mount service account keys in my pods when using Workload Identity Federation?

No. The primary benefit of Workload Identity Federation is the elimination of static service account keys. The GKE metadata server automatically injects short-lived tokens into your workloads. Your application code uses standard Google Cloud client libraries, which detect the Workload Identity environment and obtain tokens transparently from the metadata server at 169.254.169.254.

How long are the access tokens valid when using Workload Identity Federation?

Access tokens obtained through Workload Identity Federation are short-lived, typically valid for 1 hour. The GKE metadata server handles automatic rotation, refreshing tokens before they expire. Your application does not need to implement refresh logic; the client libraries automatically request new tokens from the metadata server as needed.

Can multiple Kubernetes Service Accounts impersonate the same Google Service Account?

Yes, you can bind multiple KSAs to a single GSA by adding multiple IAM policy bindings. Each binding uses the roles/iam.workloadIdentityUser role and specifies a different KSA member in the format serviceAccount:<PROJECT>.svc.id.goog[<NAMESPACE>/<KSA_NAME>]. This is useful when multiple microservices require the same Google Cloud permissions, though for least-privilege security, distinct GSAs are recommended for different workload types.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →