Last year when I setup my local (off cloud) Kubernetes cluster, I found that you could use workload identity to trust the kubernetes identities and impersonate GCP service accounts. Ref: blog post
This year, I see they've upgraded it to not require impersonation at all, allowing you to use the workload identity directly. The upstream docs are still the same at Configure Workload Identity Federation with Kubernetes.
Compared to the previous config,
this time we have two new keys: universe_domain
and token_info_url
,
and no longer need service_account_impersonation_url
1{
2 "universe_domain": "googleapis.com",
3 "type": "external_account",
4 "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID",
5 "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
6 "token_url": "https://sts.googleapis.com/v1/token",
7 "credential_source": {
8 "file": "/var/run/service-account/token",
9 "format": {
10 "type": "text"
11 }
12 },
13 "token_info_url": "https://sts.googleapis.com/v1/introspect"
14}
Mounting the config and pointing GCP SDKs to it is still the same,
though I'm still confused by the audience
not needing https:
in the config
but needing it in the GCP and token setup.
Also, I realized that if you used a projected serviceAccountToken volume,
the default token isn't mounted,
causing issues if the application talked to the Kubernetes API.
Setting automountServiceAccountToken
appears to be the easiest way to get it back.
1spec:
2 template:
3 spec:
4 automountServiceAccountToken: true
5 containers:
6 - env:
7 - name: GOOGLE_APPLICATION_CREDENTIALS
8 value: /etc/workload-identity/creds.json
9 volumeMounts:
10 - name: token
11 mountPath: /var/run/service-account
12 readOnly: true
13 - name: gcp-creds
14 mountPath: /etc/workload-identity
15 readOnly: true
16 volumes:
17 - name: token
18 projected:
19 sources:
20 - serviceAccountToken:
21 audience: https://iam.googleapis.com/projects/330311169810/locations/global/workloadIdentityPools/kubernetes/providers/justia-asami
22 expirationSeconds: 3600
23 path: token
24 - name: gcp-creds
25 configMap:
26 name: gcp
With this we can grant access to the new principal types such as:
# a specific service account
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/system:serviceaccount:KSA_NAMESPACE:KSA_NAME
# service account with the same name in all namespaces
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.service_account_name/KSA_NAME