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.workloadIdentityUserrole. - Workload Identity Pool – Enabled at the cluster level by setting
workloadPoolto<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:
- Enable Workload Identity on the cluster by setting the
--workload-poolflag to your project ID:<PROJECT_ID>.svc.id.goog. - Ensure GKE metadata server is enabled on your node pools (default on newer versions).
- Have
kubectlandgcloudCLI 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.workloadIdentityUserIAM 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →