Skip to main content

Workload Identity Federation for GKE

GKE Workload Identity Federation lets pods call GCP APIs without storing JSON keys. A Kubernetes Service Account (KSA) is mapped to a Google Service Account (GSA), and GKE automatically provides short-lived credentials to the Pod. The GSA must be granted the required IAM roles to access the corresponding Google Cloud resources.

For Vertex AI chat LLMs, the reference setup uses a dedicated service account with a JSON key (no WIF binding) — see Vertex AI (LLM).

Roles in this deployment

WorkloadK8s service accountGCP service account
External Secretsexternal-secrets-operatorexternal-secrets-operator@<project>.iam.gserviceaccount.com
Application pods<service>-svc-account (per enabled subchart)<your-app-gsa>@<project>.iam.gserviceaccount.com

Terraform provisioning example

In your Terraform variables file (for example values-<env>.auto.tfvars):

wif_service_accounts = {
"external-secrets-operator" = {
roles = ["roles/secretmanager.secretAccessor"]
k8s_namespace = "bh-control-plane"
k8s_service_accounts = ["external-secrets-operator"]
}
"<your-app-gsa>" = {
roles = ["roles/secretmanager.admin"]
k8s_namespace = "bh-control-plane"
# Bind every application KSA from the chart (see values.yaml / subchart serviceAccount.name).
k8s_service_accounts = [
"<service>-svc-account" # example pattern — repeat for each enabled subchart
]
}
}

Provide above roles to the KSA listed under 'k8s_service_accounts' via GSA using WIF before helm upgrade.

Annotate pods with WIF

The WIF to take effect every pods must annotate as below in deployment.yaml file or via helm values.

annotations:
iam.gke.io/gcp-service-account: <your-app-gsa>@<your-gcp-project>.iam.gserviceaccount.com

Notes: Application services use GCP_CREDENTIALS_FILE: "" in values — empty means use Application Default Credentials via WI.

External Secrets Secret store configuration

global:
secretStore:
projectId: "<PROJECT_ID>"
serviceAccountName: external-secrets-operator
gcpServiceAccount: external-secrets-operator@<PROJECT_ID>.iam.gserviceaccount.com

GitHub Actions

For CI pushing to customer GAR, use Workload Identity Federation (recommended):

principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/
workloadIdentityPools/<POOL>/attribute.repository/<org>/<your-deploy-repo>

Bound to a promotion SA with roles/artifactregistry.writer.

Manual binding (if not using Terraform)

gcloud iam service-accounts add-iam-policy-binding \
external-secrets-operator@<PROJECT>.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:<PROJECT>.svc.id.goog[bh-control-plane/external-secrets-operator]"

References