題幹與適用場景
這是身分基礎設施與後端可靠性題。Kubernetes ServiceAccount 使用簽名 JWT 存取 API Server 或其他信任該身分的系統;v1.36 將 external ServiceAccount token signer 能力提升到 stable,可透過本機 Unix domain socket 把簽名請求交給外部系統。題目考察如何減少 API Server 上的私鑰暴露面,同時保持 TokenRequest、驗證公鑰、輪換與高可用語意。
面試官考察點
- 能否分清簽名、簽發、驗證與授權邊界,而不是只說「接一個 KMS」。
- 能否設計 UDS/gRPC 連線、逾時、並行、重試與金鑰不可用時的 fail closed 行為。
- 能否處理新舊公鑰重疊、JWT
kid、快取與驗證方刷新。 - 能否在不撤銷有效短期 token 的前提下完成輪換與回滾。
- 能否給出稽核、延遲、錯誤率與金鑰使用指標。
回答前需要釐清的問題
- token 的 TTL、受眾、簽發 QPS 與 API Server 副本數量是多少?
- 外部 signer 是否提供 HSM 保證、健康探針、版本化金鑰與冪等請求 ID?
- 驗證方如何取得 JWKS,刷新延遲與快取 TTL 是多少?
- signer 不可用時,允許暫時拒絕新 token,還是存在受控的舊金鑰回退?
- 輪換期間是否有離線任務或叢集外系統依賴這些 JWT?
30 秒回答框架
「我把鏈路拆成 TokenRequest、API Server 呼叫外部 signer、驗證方取得公鑰與 RBAC 授權。API Server 透過受保護的 Unix socket 呼叫 signer,帶逾時、請求 ID 與有限重試;私鑰只在 KMS/HSM 內使用。輪換時先發布新公鑰並讓驗證方快取重疊,再用新 kid 簽發,等待舊 token 的 TTL 過期後撤下舊鑰。signer 不可用時拒絕新簽發並告警,不靜默生成未保護的 token;回滾保留舊公鑰與舊 signer 版本。觀測簽名延遲、拒絕率、socket 錯誤、kid 分布與 JWKS 刷新延遲。」
分步驟深入解答
第一步:定義信任與資料流
TokenRequest 的授權決定誰能為哪個 ServiceAccount 請求什麼 audience 的 token。API Server 驗證請求後,把待簽名的 JWT 載荷交給外部 signer;signer 返回簽名,API Server 再返回 token。API Server 仍負責 issuer、audience、過期時間與 RBAC 語意,外部系統只負責受控簽名,不應自行擴大權限。
第二步:設計本機 signer 介面
官方設定使用 --service-account-signing-endpoint 指向 Unix domain socket,外部服務可以在該 socket 上提供版本化簽名協定。socket 檔案權限、目錄、程序身分與 SELinux/AppArmor 策略要限制為 API Server 可存取。請求包含 key version、演算法、摘要或待簽名字節、請求 ID 與 deadline;回應包含簽名、kid 與稽核關聯 ID。禁止把私鑰或完整 token 寫入普通日誌。
第三步:處理逾時、重試與冪等
簽名呼叫是低延遲路徑,應設定短 deadline 與有界並行。網路或 HSM 短暫失敗可有限重試,但不能無限重試放大 API Server 請求佇列。請求 ID 讓 signer 與 API Server 關聯稽核;若協定支援冪等快取,可避免同一請求重複計數。逾時後返回明確錯誤並拒絕新 token,已有 token 是否繼續驗證由公鑰與過期策略決定。
第四步:設計金鑰輪換與 JWKS 重疊
先生成新金鑰並讓 signer 能用新 kid 簽名,同時把新公鑰發布到 JWKS。等待所有驗證方完成刷新後,再讓新 token 使用新 key;舊公鑰至少保留到最長 token TTL 加快取與時鐘偏差窗口。撤下舊 key 前驗證舊 token 已自然過期,不能僅依據簽發端已切換。輪換操作應可暫停、稽核與回滾。
第五步:保證多副本與災備
每個 API Server 副本都要能存取本機或高可用 signer,且金鑰版本與時鐘一致。若 signer 是集中服務,評估跨節點網路、隔離域與故障半徑;若使用每節點 sidecar,必須確認 HSM 連線與版本分發不會分叉。演練 signer 重啟、socket 檔案遺失、HSM 限流、JWKS 服務不可達與 API Server 滾動升級。
第六步:驗證、稽核與回滾
在 canary API Server 先啟用設定,驗證 TokenRequest 的 issuer、audience、kid、過期時間與 RBAC 行為。對新舊 key、不同驗證方與時鐘偏差執行整合測試。指標包括簽名 p50/p95、失敗原因、socket 延遲、HSM 計數、JWKS 刷新年齡與 token 拒絕率。回滾時恢復舊 signer/key 設定並保留舊公鑰;不要刪除舊 key,直到所有舊 token 與稽核窗口結束。
高品質示範回答
「我會把外部 signer 定位為只做簽名的受控邊界:API Server 繼續驗證 TokenRequest、issuer、audience、過期時間與 RBAC,透過受保護的 Unix socket 呼叫 signer,私鑰只在 KMS/HSM 中使用。請求有版本、kid、ID、deadline 與有限重試;signer 不可用時拒絕新 token 並告警。輪換先發布新 JWKS 並等待驗證方刷新,再切換新 kid,保留舊公鑰至少涵蓋最長 TTL、快取與時鐘偏差。多副本要驗證本機 socket、金鑰版本與時鐘一致,演練 HSM 限流、socket 遺失與 JWKS 不可達。canary 重點檢查簽名延遲、拒絕率、kid 分布、JWKS 年齡與 RBAC 整合,回滾保留舊 signer 與舊公鑰。」
常見錯誤
- 讓外部 signer 直接決定 RBAC 或 audience,擴大簽名服務職責。
- 把私鑰複製到 sidecar 或日誌,失去移出 API Server 的安全收益。
- 輪換後立即刪除舊公鑰,導致仍在 TTL 內的 token 無法驗證。
- signer 逾時無限重試,拖垮 API Server 的請求佇列。
- 只測簽名成功,不測驗證方 JWKS 快取、時鐘偏差與多副本一致性。
- 把 signer 不可用時的靜默舊金鑰簽發當作可靠回退,卻沒有稽核邊界。
追問及應對
signer 不可用時能否繼續用本機舊私鑰?
只有在明確的威脅模型、稽核與回滾方案允許時才能考慮;預設應拒絕新簽發,避免秘密重新散落到 API Server。已有 token 仍可由驗證方按舊公鑰驗證,直到 TTL 結束。
如何確定舊公鑰可以刪除?
使用最長 token TTL、驗證方 JWKS 快取 TTL、最大時鐘偏差與離線消費者保留期計算安全窗口,並用指標確認舊 kid 使用量歸零。窗口結束後再刪除,且先保留可恢復備份。
為什麼使用 Unix socket 而不是 HTTP?
本機 socket 可縮小監聽面,減少網路暴露,並利用檔案權限與主機策略控制存取。它不能自動解決協定認證、程序隔離或可用性問題,仍需版本化介面、稽核、逾時與故障演練。