每次 GitHub Actions 工作流程執行都可以向 GitHub 託管的簽發者 https://token.actions.githubusercontent.com 請求一個已簽署的身分權杖。透過 Workload Identity Federation(工作負載身分聯合),您的工作流程會將該權杖交換為短期的 Anthropic 存取權杖,因此您的 CI 作業可以呼叫 Claude API,而無需在儲存庫中儲存 ANTHROPIC_API_KEY 密鑰。
權杖的 sub 宣告(claim)編碼了儲存庫和觸發情境。對於推送到分支的情況,其格式為 repo:<owner>/<repo>:ref:refs/heads/<branch>。Pull request 執行使用 repo:<owner>/<repo>:pull_request,而受環境限制的部署則使用 repo:<owner>/<repo>:environment:<name>。您的聯合規則會比對此宣告(以及其他宣告,例如 repository_owner 和 ref),以決定允許哪些工作流程執行進行驗證。
id-token: write 權限的 GitHub 儲存庫。GitHub 只會向明確請求身分權杖的作業簽發權杖。請在工作流程或作業層級新增 id-token: write 權限:
permissions:
id-token: write
contents: read在作業內部,執行器(runner)會公開兩個環境變數:ACTIONS_ID_TOKEN_REQUEST_URL 和 ACTIONS_ID_TOKEN_REQUEST_TOKEN。使用請求權杖作為 bearer 憑證並將您選擇的 audience 作為查詢參數來呼叫請求 URL,然後將回傳的「JSON Web Token」(JWT)寫入檔案:
- name: Fetch GitHub OIDC token
run: |
curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://api.anthropic.com" \
| jq -r .value > /tmp/gha-jwt如果您偏好 JavaScript,actions/github-script 透過 core.getIDToken(audience) 提供相同的功能:
- name: Fetch GitHub OIDC token
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const token = await core.getIDToken('https://api.anthropic.com');
fs.writeFileSync('/tmp/gha-jwt', token);解碼後的權杖帶有描述工作流程執行的宣告。您的聯合規則會比對這些宣告:
{
"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",
"sha": "abc123...",
"workflow": "CI",
"actor": "octocat",
"event_name": "push"
}請參閱 GitHub 的 OIDC subject 宣告參考以取得完整的 sub 格式清單。
在 Claude Console 中,開啟 Settings → Workload identity,點擊 Connect workload,然後選擇 GitHub Actions 圖塊。精靈會引導您完成註冊簽發者、建立服務帳戶和建立聯合規則的流程。
精靈會為您建立這些資源。無論您是在精靈中輸入這些值,還是將其傳送至 Admin API,請使用以下值:
聯合簽發者: GitHub 會公開發布其 OIDC 探索文件和 JWKS,因此請使用探索模式。當 GitHub 輪替金鑰時,Anthropic 會自動重新整理金鑰。
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks": { "type": "discovery" }
}聯合規則: 只比對您打算信任的工作流程執行。請參閱限制哪些工作流程可以驗證以了解如何安全地限定這些宣告的範圍。
{
"name": "gha-main",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "repo:your-org/your-repo:ref:refs/heads/main",
"audience": "https://api.anthropic.com",
"claims": {
"repository_owner": "your-org"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}請在工作負載允許的範圍內盡可能具體。只有在規則必須比對來自同一儲存庫的多種事件類型時,才將 subject_prefix 放寬為 repo:your-org/your-repo:*(並搭配 claims.ref 限制),因為 sub 的尾端區段會在 ref:...、environment:... 和 pull_request 事件之間有所不同。
在作業上設定聯合環境變數,並正常呼叫 SDK。Anthropic() 會讀取 ANTHROPIC_IDENTITY_TOKEN_FILE,在第一次請求時交換 JWT,並在存取權杖過期前自動重新整理。
import anthropic
# 讀取 ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、
# ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_ID 與 ANTHROPIC_IDENTITY_TOKEN_FILE,
# 這些值取自作業(job)環境。
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))每個由 GitHub 簽發的身分權杖在簽發後大約五分鐘過期。權杖請求端點(ACTIONS_ID_TOKEN_REQUEST_URL)在整個作業期間保持有效,因此您可以隨時取得新的權杖。SDK 會在第一次使用時交換權杖,並快取產生的 Anthropic 存取權杖。對於執行時間超過 Anthropic 權杖有效期的作業,SDK 會在每次重新整理時重新讀取 ANTHROPIC_IDENTITY_TOKEN_FILE,因此請定期重新執行取得步驟(或將其包裝在背景迴圈中)以保持檔案為最新狀態。或者,您也可以向 SDK 傳遞一個權杖提供者回呼(callback),直接呼叫 ACTIONS_ID_TOKEN_REQUEST_URL,而不是使用檔案路徑。
成功的交換會回傳一個以 sk-ant-oat01- 開頭的 access_token,以及一個以秒為單位的 expires_in 值。若遇到 400 invalid_grant,請參閱疑難排解失敗的交換;GitHub Actions 端最常見的原因是 sub 宣告格式不符(其尾端區段會在 ref:...、environment:... 和 pull_request 事件之間有所不同)。
僅使用 repo:your-org/* 作為 subject_prefix 會比對到您組織中的每個儲存庫,而且如果沒有 ref 限制,它也會比對到從分叉(fork)觸發的 pull_request 執行。任何可以對符合條件的儲存庫開啟 pull request 的人都可能取得聯合的 Anthropic 權杖。
將規則的 match 區塊鎖定在符合您使用情境的最窄範圍:
subject_prefix: "repo:your-org/your-repo:*",這樣組織中的其他儲存庫就不會符合。claims 下新增 "ref": "refs/heads/main"(或您的發布分支),這樣 pull request 執行和功能分支就不會符合。claims 下新增 "repository_owner": "your-org",作為針對 sub 解析邊緣情況的深度防禦檢查。subject_prefix: "repo:your-org/your-repo:environment:production",並在 GitHub 中使用必要審核者來管控該環境。Was this page helpful?