Workload Identity

Workload Identity allows you to assign a specific Google Cloud Service Account to a specific application, so that each application can get its own service account identity/permissions using Machine Credential.

Create Service Accounts

Create a Kubernetes Service Account (KSA)

kubectl create serviceaccount helloworld \
--dry-run -oyaml > k8s/helloworld-sa.yaml
kubectl apply -f k8s/helloworld-sa.yaml

Create a Google Cloud Service Account (GSA)

gcloud iam service-accounts create helloworld
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:helloworld@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/pubsub.publisher

Bind Service Accounts

Bind the Kubernetes Service Account (KSA) to Google Cloud Service Account (GSA)

Binding from Google Cloud

PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/helloworld]" \
helloworld@${PROJECT_ID}.iam.gserviceaccount.com

Binding from Kubernetes

PROJECT_ID=$(gcloud config get-value project)
kubectl annotate -f k8s/helloworld-sa.yaml \
iam.gke.io/gcp-service-account=helloworld@${PROJECT_ID}.iam.gserviceaccount.com
kubectl apply -f k8s/helloworld-sa.yaml

Use the Kubernetes Service Account

k8s/nginx-sa-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-sa
labels:
app: nginx-sa
spec:
replicas: 1
selector:
matchLabels:
app: nginx-sa
template:
metadata:
labels:
app: nginx-sa
spec:
# Specify the KSA to use
serviceAccountName: helloworld
containers:
- image: nginx
name: nginx

To try it out, first exec into the Pod:

POD_NAME=$(kubectl get pods -lapp=nginx-sa -o jsonpath='{.items[0].metadata.name}')
kubectl exec -ti ${POD_NAME} -- /bin/bash

Inside the Pod, see metadata server:

curl -H"Metadata-Flavor: Google" \
http://metadata/computeMetadata/v1/instance/service-accounts/default/email