Skip to content

Chương 13: GKE Workload Identity & Service Accounts — Modern Authentication

Vì sao chương này là xương sống của mọi workload gọi Google API

Gần như mọi workload production trên GKE đều phải gọi một Google API nào đó: đọc object từ Cloud Storage, publish message lên Pub/Sub, query BigQuery, đọc credential từ Secret Manager, ghi metric/log lên Cloud Operations. Câu hỏi tưởng chừng đơn giản — "workload chứng minh nó là ai với Google bằng cách nào" — lại là một trong những quyết định kiến trúc có hệ quả bảo mật sâu rộng nhất của toàn bộ cluster. Trả lời sai, bạn để lại một long-lived service account key nằm trong etcd, image Docker, và Git history — chính xác là vector tấn công mà mọi báo cáo sự cố credential theft của Google Cloud đều trỏ tới. Trả lời đúng, bạn có một hệ thống xác thực không-key, token short-lived tự refresh, và mọi quyền truy cập đều gắn với một danh tính có thể audit ở mức từng workload.

Chương 12 đã giới thiệu Workload Identity ở góc bảo mậttại sao nó tồn tại và vector tấn công nào nó cắt đứt. Chương 13 này đi tới tận đáy cơ chế: chính xác token nào được sinh ra, ai ký nó, ai verify, request đi qua những thành phần nào, và điều gì xảy ra ở từng millisecond của token exchange path. Đây không phải kiến thức "biết để cho vui" — nó là kiến thức bạn bắt buộc phải có khi một Pod báo 403 Permission Denied lúc 3 giờ sáng và bạn cần biết: lỗi nằm ở projected token, ở metadata server, ở STS exchange, hay ở IAM binding. Mỗi tầng có một cơ chế lỗi riêng, một điểm điều tra riêng, và một cách vá riêng.

Có ba mental model sai phổ biến mà chương này phá bỏ:

  • "Workload Identity là một loại key đặc biệt được Google quản lý." Sai. Không có key nào cả. Cái workload có là một OIDC JWT short-lived do chính cluster (đóng vai trò OIDC provider) ký, và một federated access token đổi từ JWT đó. Hiểu nhầm điều này dẫn tới việc đi tìm "key Workload Identity ở đâu" — một câu hỏi vô nghĩa.

  • "Metadata server chỉ là một endpoint, gọi vào là có token." Sai ở mức nguy hiểm. gke-metadata-server là một DaemonSet chạy trên từng node, chặn (intercept) mọi request tới 169.254.169.254 / metadata.google.internal, và thực hiện một chuỗi token exchange phức tạp đằng sau. Hiểu nó là "magic endpoint" khiến bạn không debug được khi DaemonSet bị OOM-killed hoặc khi Pod dùng hostNetwork: true bypass mất nó.

  • "Workload Identity Federation cho GKE và Workload Identity Federation cho external IdP là hai thứ khác nhau." Sai về bản chất. Chúng là cùng một cơ chế federation xây trên cùng STS endpoint và cùng OAuth 2.0 token exchange (RFC 8693). GKE chỉ là một trường hợp đặc biệt nơi external IdP chính là OIDC provider của cluster. Hiểu thống nhất điều này cho phép bạn dùng cùng một mental model cho cả Pod GKE lẫn GitHub Actions runner lẫn workload chạy trên AWS.

Điểm mấu chốt xuyên suốt chương: xác thực hiện đại trên GCP là một bài toán trao đổi token dựa trên niềm tin OIDC, không phải bài toán quản lý secret. Toàn bộ chương xây dựng một mental model duy nhất — một danh tính bên ngoài (KSA, GitHub repo, AWS role) được một IdP xác nhận bằng JWT có chữ ký; Google STS verify chữ ký đó dựa trên cấu hình tin cậy (pool + provider); và đổi nó lấy một credential Google short-lived gắn với quyền IAM tối thiểu — rồi áp dụng mental model đó cho mọi tình huống.

Điều kiện tiên quyết

  • Chương 12 (GKE Security), đặc biệt file 04 — Workload Identity Federation: chương này là phần deep-dive được Chương 12 chỉ định nối tiếp. Bạn cần đã nắm: vì sao long-lived key nguy hiểm, khái niệm pool PROJECT_ID.svc.id.goog, và bức tranh tổng thể của token exchange ba bước. Chương 13 không lặp lại lập luận bảo mật đó — nó giải phẫu cơ chế.
  • IAM service accounts và IAM policy binding: principal, role, member, roles/iam.workloadIdentityUser, roles/iam.serviceAccountTokenCreator. Toàn bộ tầng authorization của Workload Identity là IAM thuần túy.
  • OIDC basics: ID token, JWT (header/payload/signature), iss/sub/aud/exp claims, JWKS endpoint, RS256 signing. Workload Identity OIDC ở mọi tầng; không nắm OIDC thì cơ chế sẽ trông như phép thuật.
  • Kubernetes ServiceAccount và TokenRequest API: projected volume, bound token, BoundServiceAccountTokenVolume. File 02 đào sâu, nhưng nền tảng giúp ích.
  • Application Default Credentials (ADC): thứ tự ADC dò credential trong client library Google. File 03 và 06 giả định bạn hiểu ADC là gì.

Mức độ sâu

5/5 — Chương đi tới mức: cấu trúc payload của projected ServiceAccount token (iss = OIDC issuer https://container.googleapis.com/v1/projects/.../clusters/..., aud = sts.googleapis.com, exp ≤ 1 giờ, kubernetes.io claims); JWKS endpoint /.well-known/openid-configuration và cơ chế Google STS verify chữ ký JWT mà không cần gọi về cluster; kiến trúc DaemonSet của gke-metadata-server, giới hạn 500 concurrent connection/node, ngưỡng 3.000 ServiceAccount/cluster, quota 6.000 request/phút của STS Exchange Token API; bốn dạng principal/principalSet identifier (subject by name, by UID, namespace-level, cluster-level) và ngữ nghĩa "identity sameness" giữa các cluster; CEL attribute mapping (google.subject=assertion.sub) và attribute condition chống confused-deputy; token exchange flow RFC 8693 qua sts.googleapis.com cho external IdP với từng loại (AWS SigV4, Azure/Entra ID, GitHub Actions OIDC token.actions.githubusercontent.com, Kubernetes, OIDC generic); và quy trình debug từ curl metadata endpoint bên trong Pod đến verify IAM binding. Mọi tuyên bố kỹ thuật đối chiếu trực tiếp tài liệu Google Cloud.


Cấu trúc chapter

1. Workload Identity Architecture — Cluster Như Một OIDC Provider

Mô hình niềm tin nền tảng: cluster phát hành danh tính, IAM tin tưởng danh tính đó.

  • GKE OIDC provider: mỗi cluster là một OIDC issuer với endpoint riêng và JWKS riêng
  • Workload Identity Pool PROJECT_ID.svc.id.goog: cây cầu để IAM hiểu danh tính Kubernetes, tồn tại ngay cả khi xóa hết cluster
  • Bốn dạng định danh: principal://...subject/ns/NS/sa/KSA (theo tên), .../kubernetes.serviceaccount.uid/UID (theo UID), principalSet://...namespace/NS (cấp namespace), .../kubernetes.cluster/... (cấp cluster)
  • Identity sameness: vì sao cùng tên KSA ở hai cluster cùng project = cùng danh tính IAM, và hệ quả isolation
  • Fleet Workload Identity pool vs project pool; mối quan hệ federation tổng quát

2. ServiceAccount Token & Projection Mechanics — Danh Tính Được Ký

Token gốc của toàn bộ chuỗi: ai sinh, ai ký, hết hạn khi nào.

  • TokenRequest API và bound token: khác biệt với legacy secret-based token (không hết hạn, không bound)
  • Projected volume: kubelet mount token qua serviceAccountToken projection, với audience, expirationSeconds, path
  • Cấu trúc JWT: iss (OIDC issuer của cluster), sub, aud (sts.googleapis.com), exp, các claim kubernetes.io/namespace, .../serviceaccount/name, .../pod
  • OIDC issuer endpoint https://container.googleapis.com/v1/projects/.../clusters/.../.well-known/openid-configuration; JWKS public key để STS verify offline
  • Vòng đời refresh: kubelet tự rotate token trước khi hết hạn; vì sao không bao giờ có token "vĩnh viễn"

3. Metadata Server & Token Exchange Path — Trái Tim Của Cơ Chế

Giải phẫu từng bước con đường từ "app gọi ADC" đến "có access token Google".

  • gke-metadata-server DaemonSet: một Pod/node, chặn request tới 169.254.169.254:80 / metadata.google.internal
  • Trust boundary cấp node: HTTP interception, vì sao hostNetwork: true bypass và rủi ro của nó
  • Token exchange path năm bước chi tiết: app gọi ADC → metadata server chặn → lấy projected KSA JWT từ API server → đổi qua Security Token Service (sts.googleapis.com) lấy federated token → trả access token short-lived cho app
  • Caching và refresh: token lifetime 1 giờ (3.600s), client library refresh khi còn 3 phút 45 giây; quota STS 6.000 req/phút
  • Scale bottleneck: 500 concurrent connection/node, 3.000 ServiceAccount/cluster làm OOM metadata server; network policy egress 169.254.169.254/32:80 (Dataplane V2) hoặc 169.254.169.252/32:988

4. IAM Binding Models — Cấp Quyền Cho Danh Tính Workload

Hai mô hình authorization và khi nào dùng cái nào.

  • Mô hình trực tiếp (khuyến nghị): IAM binding role GCP thẳng cho principal://...sa/KSA, không cần GSA trung gian
  • Mô hình impersonation (legacy/phổ biến): annotate KSA iam.gke.io/gcp-service-account, GSA cấp roles/iam.workloadIdentityUser cho serviceAccount:PROJECT_ID.svc.id.goog[NS/KSA]
  • principalSet cấp namespace/cluster: cấp quyền cho cả một namespace hoặc cả một cluster cùng lúc — và rủi ro của nó
  • Cross-project Workload Identity: KSA ở cluster project A impersonate GSA ở project B; annotation credential-quota-project
  • Autopilot: Workload Identity luôn bật, không thể tắt; hệ quả thiết kế
  • Annotation iam.gke.io/return-principal-id-as-email và format danh tính trả về

5. Workload Identity Federation cho External IdP — Liên Bang Danh Tính Đa Đám Mây

Cùng cơ chế federation mở rộng ra ngoài Google Cloud.

  • Workload Identity Pool + Provider cho external IdP: khác biệt với pool GKE cố định
  • Token exchange RFC 8693 qua sts.googleapis.com: external JWT → federated token
  • IdP được hỗ trợ: AWS (SigV4 caller identity), Microsoft Entra ID/Azure, GitHub Actions (token.actions.githubusercontent.com), GitLab, Kubernetes, Okta/AD FS, OIDC/SAML generic
  • Attribute mapping (CEL): google.subject=assertion.sub, attribute.NAME=..., google.groups; tối đa 50 custom attribute
  • Attribute condition: chống confused deputy — ví dụ assertion.repository_owner=='ORG' && assertion.ref=='refs/heads/main'
  • Direct resource access vs service account impersonation; principalSet://...attribute.NAME/VALUE

6. Truy Cập Dịch Vụ & Application Default Credentials Patterns

Từ cơ chế đến code: workload thực sự gọi API như thế nào.

  • ADC behavior trên GKE: thứ tự dò credential, vì sao client library "tự hoạt động không cần sửa code"
  • Pattern truy cập Secret Manager qua Workload Identity (thay cho mount SA key)
  • Pattern Cloud Storage / Pub/Sub / BigQuery: KSA-per-workload với quyền tối thiểu trên đúng resource
  • Credential helper trong container image: Artifact Registry pull qua Workload Identity, docker-credential-gcr
  • Access external service (không phải Google API) bằng token federation ngược; impersonation chain
  • ADC trong môi trường local/dev vs trong cluster: vì sao test local cần gcloud auth application-default login

7. Debugging Workload Identity — Khi Token Exchange Thất Bại

Quy trình điều tra có hệ thống cho mọi failure mode.

  • Debug từ trong Pod: kubectl execcurl -H "Metadata-Flavor: Google" các endpoint /computeMetadata/v1/instance/service-accounts/default/email/token
  • Verify GKE_METADATA mode trên mọi node pool; phát hiện pool còn ở GCE_METADATA
  • Verify IAM binding: gcloud ... get-iam-policy, kiểm tra principal string đúng namespace/tên KSA
  • Token validity check: decode JWT, kiểm aud, exp, sub; phân biệt lỗi authentication vs authorization
  • Cây quyết định lỗi: unable to detect environment, 403 Permission Denied, 404 từ metadata, token rỗng, DNS/network policy chặn metadata
  • Lỗi scale: metadata server OOM, vượt 500 concurrent connection, vượt quota STS

Bản đồ tinh thần: một danh tính, bốn lần biến đổi

Trước khi vào từng file, hãy ghim chuỗi biến đổi danh tính này — nó là khung tham chiếu cho mọi quyết định và mọi lần debug trong chương. Một workload đi từ "không có danh tính Google nào" đến "gọi được Google API" qua đúng bốn lần biến đổi:

BướcDanh tính ở dạngAi tạo/kýAi verifyFile
1. KSAMột ServiceAccount Kubernetes (ns/sa)Người vận hành tạo trong cluster1, 2
2. Projected JWTOIDC token short-lived, ký bởi clusterkubelet (qua TokenRequest API)Google STS (qua JWKS)2
3. Federated tokenShort-lived access token của GoogleSecurity Token ServiceGoogle API backend3
4. (tùy chọn) GSA tokenAccess token của IAM service accountIAM Credentials API (impersonation)Google API backend4

Ba quan sát quyết định cách đọc cả chương:

  1. Không bước nào trong chuỗi này là một long-lived secret. KSA là một object Kubernetes, không phải credential. JWT, federated token, GSA token — tất cả đều short-lived và tự refresh. Đây là toàn bộ lý do Workload Identity tồn tại: chuyển từ "quản lý vòng đời secret" sang "quản lý cấu hình niềm tin".

  2. Bước 4 là tùy chọn — và đó là điểm phân biệt hai mô hình IAM binding. Mô hình trực tiếp (file 4) dừng ở bước 3: federated token gọi thẳng API. Mô hình impersonation thêm bước 4: federated token dùng để mạo danh một GSA. Biết bạn đang ở mô hình nào quyết định bạn debug IAM binding ở đâu.

  3. External IdP federation (file 5) chỉ thay bước 1–2 bằng IdP khác. Thay vì KSA + cluster-signed JWT, bạn có GitHub repo + token.actions.githubusercontent.com-signed JWT, hoặc AWS role + SigV4. Bước 3–4 giống hệt. Đây là lý do nắm vững chuỗi này cho GKE giúp bạn hiểu ngay mọi kịch bản federation khác.


Khung quyết định Workload Identity (tóm tắt)

Ma trận quyết định cốt lõi của chương. Mỗi dòng là một câu hỏi thiết kế thật, file tương ứng đào sâu.

Tình huống / Nhu cầuLựa chọn đúngVì saoFile
Workload GKE mới cần gọi Google APIWorkload Identity, IAM binding trực tiếp cho principal://...sa/KSAÍt thành phần nhất, không key, granularity per-KSA1, 4
Tổ chức đã chuẩn hóa quyền theo IAM service accountMô hình impersonation (annotation + workloadIdentityUser)Tận dụng GSA sẵn có, quản lý quyền tập trung theo GSA4
Workload ở project A cần resource ở project BCross-project: KSA project A impersonate GSA project BPool và GSA có thể ở project khác nhau4
CI/CD runner (GitHub Actions) deploy lên GCPWorkload Identity Federation external + attribute condition theo repoLoại bỏ SA key khỏi CI secret — nơi key lộ nhiều nhất5
Workload đa đám mây trên AWS/Azure gọi Google APIFederation từ AWS role / Entra ID qua pool+providerKhông SA key, dùng danh tính cloud sẵn có5
Cần cấp quyền cho cả một namespaceprincipalSet://...namespace/NSTiện, nhưng đánh đổi granularity — cân nhắc kỹ1, 4
Workload đọc secret cấu hình lúc khởi độngSecret Manager qua ADC + secretmanager.secretAccessor trên đúng secretKhông secret tĩnh trong image/etcd6
Pod báo 403 khi gọi APIDebug theo cây: GKE_METADATA → IAM binding → token claimsMỗi tầng lỗi riêng, điểm điều tra riêng7
Chạy AutopilotKhông cần bật gì — Workload Identity luôn onAutopilot enforce sẵn, không có metadata node để lộ4

Năm sai lầm xuyên suốt thường gặp ở cấp chương

  1. Đi tìm "key Workload Identity". Tư duy theo mô hình secret cũ, hỏi "key nằm ở đâu để backup/rotate". Hệ quả: hiểu sai bản chất, không debug được khi token exchange lỗi. Đúng: không có key; có một chuỗi token short-lived tự refresh, cái cần "quản lý" là IAM binding và cấu hình pool (file 1–4).

  2. Bật Workload Identity ở cluster nhưng quên một node pool. Cluster có --workload-pool nhưng một pool cũ vẫn GCE_METADATA. Hệ quả: Pod trên pool đó lấy được token node service account qua metadata Compute Engine — đúng vector mà Workload Identity định cắt. Đúng: mọi pool phải GKE_METADATA; verify bằng gcloud container node-pools list (file 3, 7).

  3. Dùng hostNetwork: true mà không nhận ra nó bypass metadata server. Pod hostNetwork truy cập thẳng Compute Engine metadata server, không qua gke-metadata-server, nên không có Workload Identity. Hệ quả: hoặc workload lỗi xác thực, hoặc tệ hơn, lấy được token node SA. Đúng: tránh hostNetwork cho workload cần WI, hoặc xử lý xác thực riêng (file 3).

  4. Cấp principalSet cấp namespace/cluster cho tiện rồi quên thu hẹp. Bind role GCP cho cả principalSet://...namespace/NS thay vì từng KSA. Hệ quả: mọi KSA trong namespace — kể cả default và các workload tương lai — đều có quyền đó; "identity sameness" còn khiến nó lan sang cluster khác cùng project. Đúng: binding per-KSA principal, dùng IAM condition giới hạn cluster khi cần (file 1, 4).

  5. Attribute condition lỏng lẻo khi federate external IdP. Tạo provider GitHub Actions nhưng không giới hạn assertion.repository_owner/assertion.ref. Hệ quả: confused deputy — bất kỳ repo GitHub nào (kể cả của kẻ tấn công) cũng đổi được token lấy quyền GCP của bạn. Đúng: luôn có attribute condition khóa chặt org/repo/branch (file 5).


Cross-reference với Google Cloud Architecture Framework

  • Security pillar: chương là hiện thân của nguyên tắc zero long-lived credentialleast-privilege identity trong Well-Architected Framework — danh tính short-lived, gắn workload, audit được (Security pillar).
  • Operational excellence: chuyển từ vòng đời key (rotate, phát hiện rò rỉ, thu hồi) sang cấu hình IAM binding khai báo — giảm gánh nặng vận hành và bề mặt lỗi con người (Operational excellence pillar).
  • Reliability: token exchange path có các bottleneck thật (500 connection/node, quota STS, metadata server OOM) — hiểu chúng là điều kiện để vận hành xác thực ở quy mô mà không gây outage (Reliability pillar).

References chung của chapter


Bảng thuật ngữ then chốt của chương

Thuật ngữÝ nghĩa ngắn gọn
Workload Identity PoolKhông gian tên PROJECT_ID.svc.id.goog để IAM hiểu danh tính Kubernetes (file 1)
OIDC issuerCluster đóng vai trò OIDC provider, endpoint container.googleapis.com/v1/projects/.../clusters/... (file 1, 2)
JWKSBộ public key cluster công bố để STS verify JWT offline (file 2)
Projected tokenKSA JWT short-lived kubelet mount qua projected volume, aud=sts.googleapis.com (file 2)
TokenRequest APIAPI Kubernetes cấp bound token có audience/expiry (file 2)
gke-metadata-serverDaemonSet chặn request metadata, thực hiện token exchange (file 3)
Security Token Service (STS)sts.googleapis.com, đổi external JWT lấy federated token (RFC 8693) (file 3, 5)
Federated access tokenAccess token Google short-lived đổi từ JWT, lifetime 1 giờ (file 3)
principal://Định danh IAM cho một danh tính đơn (một KSA cụ thể) (file 1, 4)
principalSet://Định danh IAM cho một tập danh tính (namespace/cluster/attribute) (file 1, 4, 5)
workloadIdentityUserRole cho phép KSA impersonate một GSA (file 4)
Identity samenessCùng tên KSA ở các cluster cùng project = cùng danh tính IAM (file 1)
Attribute mappingCEL ánh xạ claim của external IdP sang attribute Google (file 5)
Attribute conditionCEL lọc danh tính được phép, chống confused deputy (file 5)
ADCApplication Default Credentials — cách client library tự dò credential (file 6)
GKE_METADATAChế độ node pool bật metadata server Workload Identity (file 3, 7)

Kết luận của chapter

Workload Identity là minh chứng rõ nhất cho một dịch chuyển tư duy trong bảo mật đám mây: từ "giữ bí mật một secret" sang "thiết lập niềm tin giữa các danh tính". Mọi cơ chế trong chương — projected token, metadata server, STS exchange, IAM binding, attribute condition — đều phục vụ một mục tiêu duy nhất: cho phép một workload chứng minh nó là ai mà không bao giờ cầm một credential dài hạn nào trong tay. Khi bạn nắm được chuỗi bốn lần biến đổi danh tính và biết mỗi thành phần ký gì, verify gì, hết hạn khi nào, thì Workload Identity thôi là phép thuật và trở thành một hệ thống bạn có thể thiết kế, vận hành, và debug một cách kỷ luật.

Cách dùng chương hiệu quả nhất là biến mỗi file thành một năng lực vận hành cụ thể: hiểu mô hình niềm tin OIDC của cluster (file 1, 2), giải phẫu được token exchange path tới từng bước (file 3), chọn đúng mô hình IAM binding cho từng tình huống tổ chức (file 4), mở rộng cùng mental model ra CI/CD và đa đám mây (file 5), viết code và cấu hình truy cập dịch vụ không-key (file 6), và quan trọng nhất — debug được khi token exchange thất bại ở 3 giờ sáng (file 7). Khi đó xác thực workload chuyển từ "một thứ ai đó đã cấu hình và không ai dám động vào" thành một hệ thống minh bạch, suy luận được, đúng tinh thần zero-trust mà mọi cluster production ở quy mô lớn buộc phải theo.