- https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
- https://cloud.google.com/blog/products/containers-kubernetes/introducing-workload-identity-better-authentication-for-your-gke-applications
For this example, I will be setting up access to Google Secrets Manager.
Setup Environment Variables
- PROJECT_ID = Google Project ID
- GSA_NAME = Google IAM Service Account
- K8S_NAMESPACE = Kubernetes namespace
- KSA_NAME = Kubernetes Service Account
export PROJECT_ID=[YOUR_PROJECT_ID]
export GSA_NAME=sonic-itsmetommy
export K8S_NAMESPACE=itsmetommy
export KSA_NAME=sonic
Create Kubernetes Service Account
kubectl create serviceaccount ${KSA_NAME} -n ${K8S_NAMESPACE}
Create Google Service Account
gcloud iam service-accounts create ${GSA_NAME}
Create the binding between the google service account and the Kubernetes service account
The following command grants the same access to any cluster in the project that uses the sonic service account and itsmetommy namespace, and have Workload Identity enabled on the cluster:
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[${K8S_NAMESPACE}/${KSA_NAME}]" \
${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
Add role for Google Secret Manager access
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--role roles/secretmanager.secretAccessor \
--member serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
Verify
gcloud iam service-accounts get-iam-policy \
--flatten="bindings[].members" \
--format="table(bindings.role, bindings.members)" \
${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
gcloud projects get-iam-policy ${PROJECT_ID} \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
Add annotation to Kubernetes Service Account
Add the iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID annotation to the Kubernetes service account, using the email address of the Google service account.
kubectl annotate serviceaccount \
--namespace ${K8S_NAMESPACE} \
${KSA_NAME} \
iam.gke.io/gcp-service-account=${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
Verify
Create a secret using Google Secret Manager if you haven’t already.
echo -n "12345" | gcloud secrets create itsmetommy_db_password \
--replication-policy="automatic" \
--data-file=-
Create a pod using cloud-sdk and adding the correct serviceaccount.
kubectl run -it --rm \
--image google/cloud-sdk:slim \
--serviceaccount ${KSA_NAME} \
--namespace ${K8S_NAMESPACE} \
workload-identity-test
Run the following inside the pod.
# gcloud auth list
# gcloud secrets versions access latest --secret="[SECRET_NAME]"
Example
# gcloud auth list
Credentialed Accounts
ACTIVE ACCOUNT
* sonic-itsmetommy@${PROJECT_ID}.iam.gserviceaccount.com
# gcloud secrets versions access latest --secret="itsmetommy_db_password"
12345
Revoke access
Revoke access to the Google service account.
gcloud iam service-accounts remove-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[${K8S_NAMESPACE}/${KSA_NAME}]" \
${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
Remove the annotation from the Kubernetes service account. This step is optional because access has been revoked by IAM.
kubectl annotate serviceaccount \
--namespace ${K8S_NAMESPACE} \
${KSA_NAME} \
iam.gke.io/gcp-service-account=${KSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
Clean up
# Delete KSA
kubectl delete sa ${KSA_NAME}
# Delete GSA
gcloud iam service-accounts delete ${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com