DAY 244 · 2026-08-31

API key 的進化版 Workload Identity Federation

SLIDES · 5
Day 244 API key 的進化版 Workload Identity Federation — 投影片 1Day 244 API key 的進化版 Workload Identity Federation — 投影片 2Day 244 API key 的進化版 Workload Identity Federation — 投影片 3Day 244 API key 的進化版 Workload Identity Federation — 投影片 4Day 244 API key 的進化版 Workload Identity Federation — 投影片 5
1 / 5

昨天 Day 243 講的四件事——一個用途一把 key、權限縮小、設花費上限、信用卡那道防線——都建立在同一個前提上:你手上有一把長期有效的金鑰,而它有一天可能會外洩。

還有另一條路,是讓那把長期金鑰根本不存在。Workload Identity Federation(以下簡稱 WIF)做的就是這件事:機器不再隨身帶一把永久鑰匙,而是拿一張幾分鐘就過期的身分證明去換臨時通行證。

今天要分享的是:它到底在幹嘛、為什麼外洩的損失會變小、原理上誰在信任誰、哪些情況它幫不上忙,還有什麼時候值得換。

先說為什麼現在講這個。WIF 原本是雲端部署的東西,但 Anthropic 在 2026 年 6 月 17 日把它正式開放,OpenAI 也有同一套機制——Day 243 那把 AI API key,只要是跑在 CI、Kubernetes、雲端函式這種執行環境上,現在也走得了這條路;跑在你自己筆電上的那把,還是得留著。

它到底在幹嘛:先想像外送員要進大樓

外送員要進大樓送餐,警衛室得發他一張通行證。

舊做法是發一張永久通行證。那張卡本身就是憑證,誰拿到誰就能進,警衛不會再問你是誰。所以卡一旦弄丟、或被人從外送員身上偷走,小偷就能一直進出這棟大樓——而且他可以先不動手,潛伏著,挑未來某一天才進來。你不主動去掛失,它永遠有效。

WIF 是另一種發卡方式。外送員身上什麼卡都沒有。他到大樓的時候,是 foodpanda 出面跟警衛說「這一單是我派的」;警衛驗的是 foodpanda 的簽章,不是外送員本人。確認過了,才發一張十分鐘後失效的臨時訪客證。

餐送完,訪客證自己過期,沒有人需要去掛失。就算它被偷走,撿到的人最多只有那十分鐘可以用,而且他再也拿不到新的——要 foodpanda 出面,警衛才會再發一張。

對應回技術上:外送員是你的服務或 CI job,foodpanda 是它跑在上面的執行環境(GitHub Actions、AWS、GCP),警衛室是 API 供應商或雲端服務,永久通行證是長期 API key,臨時訪客證是短期權杖。

講白一點,長期 API key 是「持有即通行」:那串 sk-... 本身就是憑證,從哪台機器用都行,一直用到你去後台撤銷為止。WIF 把它換成「先證明你是誰,再拿一張快過期的票」。你的工作不再隨身帶鑰匙,而是先跟執行環境要一張 JWT——一份有數位簽章、幾分鐘就過期的身分證明,上面寫著它是誰、從哪個 repo、哪個分支、哪個事件跑起來的。拿這張去換,才換得到一個只能用幾分鐘的存取權杖。

外洩的東西因此從「一把可以一直用的鑰匙」變成「一張快過期的票」。撿到票的人還換不到新的票,因為能幫你簽身分證明的私鑰在 GitHub(或 AWS、GCP、你的 Kubernetes 叢集)那邊,不在你的 repo 裡。

為什麼外洩的損失會變小

長期 API key 短期 federated token
效期 到你撤銷為止 只有幾分鐘。Anthropic 的設定預設 600 秒,直接打 API 不指定的話是 3600 秒(可設 60 到 86400 秒);但實際還會被下一段「上游 JWT 剩餘時間兩倍」的上限壓下來
誰能用 任何人、任何機器、任何 IP 一樣是任何人——只是剩下那幾分鐘
撿到之後 一直用,直到有人發現 用到過期,然後換不到新的
要再拿一把 複製那串字就好 要有辦法讓 GitHub/AWS/叢集幫你簽一張新的 JWT

Anthropic 還多壓了一層:換到的權杖效期是「規則設的秒數」跟「上游 JWT 剩餘時間的兩倍」取小的那個,最短 60 秒。GitHub 發的身分權杖大約五分鐘就過期,所以就算你把規則設成 3600 秒,實際拿到的也是十分鐘上下的東西。上游身分活多久,下游權限最多就跟著活那麼久。

還有一件事跟直覺不太一樣:那組設定值本身不是秘密。federation rule ID、organization ID、service account ID 這些,在官方的 workflow 範例裡是直接寫在 env: 裡的明文,不需要放進 repository secrets。CI 裡跟這條認證路徑有關的部分,真的沒有秘密要保管了。

原理:誰發、誰驗、誰在信任誰

三個角色:

  1. 身分提供者(也就是 OIDC 發證方)——你本來就在用的執行環境:GitHub Actions、AWS、GCP、Kubernetes。它握著一組私鑰,會幫在它上面跑的工作簽 JWT
  2. 工作本身——你的 CI job、你的 pod。它跟身分提供者要那張 JWT
  3. 資源那一方——雲端服務或 API 供應商。它拿身分提供者「公開」的公鑰驗簽章,再比對你事先設好的規則

信任是這樣接起來的:你在資源那一方登記兩樣東西。

第一樣是 issuer——那個身分提供者的 iss 值,還有去哪裡抓公鑰。像 GitHub Actions 就是 https://token.actions.githubusercontent.com,公鑰走 /.well-known/openid-configuration 自動發現,對方會在 GitHub 換金鑰的時候自己更新。

第二樣是規則——什麼樣的 JWT 可以換成什麼身分。GitHub 簽出來的 JWT 解碼後長這樣:

{
  "iss": "https://token.actions.githubusercontent.com",
  "sub": "repo:your-org/your-repo:ref:refs/heads/main",
  "aud": "https://api.anthropic.com",
  "repository": "your-org/your-repo",
  "repository_owner": "your-org",
  "ref": "refs/heads/main",
  "event_name": "push"
}

注意 GitHub 從 2026 年 7 月 15 日起改用 immutable subject:之後新建、改名或轉移的 repo,sub 會變成 repo:your-org@1234567/your-repo@8901234:ref:refs/heads/main(名稱後面多了不可變的數字 ID)。7/15 前的舊 repo 維持原格式,除非你主動 opt in。設規則前先把實際的 JWT 解碼出來看一眼。

規則就寫成:iss 要是這個、sub 要對上 repo:your-org/your-repo:ref:refs/heads/main(要涵蓋多種事件才加結尾的 *,並搭配 claims.ref 限制)、aud 要對——三項都過,才換一個指定身分的短期權杖給它。GitHub 那邊也要在 workflow 裡明確開權限,加上 permissions: 區塊,底下放 id-token: write(Anthropic 文件的範例還會一起帶 contents: read),沒開的 job 拿不到 JWT。

整條路上沒有任何一段是「兩邊共用同一組密鑰」。GitHub 用自己的私鑰簽,對方用公開的公鑰驗,你設定的是一段公開的比對條件。所以中間才沒有東西可以外洩。

各家名字不一樣,這兩個步驟是一樣的:

註冊發證方 設定比對規則
GCP workload identity pool + provider attribute condition(CEL)
AWS IAM OIDC identity provider 信任政策 + AssumeRoleWithWebIdentity
Anthropic federation issuer federation rule → service account
OpenAI workload identity provider service account mapping

這條路做不到的事

  1. 沒有 OIDC 發證方的地方就沒有這條路。 你的筆電沒有,本機開發還是得靠一把 key。自己租的 VM、跑在自家機器上的 cron、不少 PaaS 也都沒有。這些地方 Day 243 那四招照樣是主力
  2. 規則寫太鬆,比長期 key 還危險。 Anthropic 文件裡直接標了警告:subject_prefix 寫成 repo:your-org/*,整個組織的每一個 repo 都會對上,而且沒有加 ref 條件的話,連從 fork 發起的 pull request 都算——任何人只要能對你的 repo 開一個 PR,就換得到權杖。以為自己更安全了,其實是把門開得更大
  3. 信任鏈只到你的身分提供者為止。 對方驗的是「GitHub 說這個 job 是誰」。GitHub 帳號被接管,或有人能在你的 main 分支上跑任意 workflow,WIF 一點都擋不住。它換掉的是秘密怎麼保管,不是誰能執行
  4. 舊 key 沒清掉的話,可能根本沒生效。 Anthropic SDK 的憑證優先順序裡,ANTHROPIC_API_KEY 排在 federation 前面。環境裡留著一把舊 key,它會默默蓋過 federation——你以為換好了,其實還在燒那把 key
  5. 出錯的時候不好查。 換權杖失敗回的是一個沒有細節的 401 Authentication failed,真正的原因要去 Console 的 authentication history 頁面看。最常見的是 sub 沒對上:新舊 subject 格式不同,或者 push、pull_request、environment 這三種事件的 sub 尾巴長得不一樣

什麼時候值得換

  • 跑在 CI 上的自動化:這是 WIF 最順的情境,本來就有 OIDC,改完之後 repository secrets 可以少一項
  • 跑在 Kubernetes、雲端函式上的服務:同理,執行環境本來就會發 JWT
  • 本機開發、一次性腳本、朋友的 demo:維持 Day 243 那四招,一個用途一把 key、權限縮小、設花費上限、信用卡那道防線

一句話總結:Day 243 是讓 key 外洩的那一刻值比較少錢,這篇是讓撿到的人手上那張票,十分鐘後變成一串沒用的字。


延伸閱讀
看完整 244 篇 →