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
| Workload | K8s service account | GCP service account |
|---|---|---|
| External Secrets | external-secrets-operator | external-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]"