2180 字
11 分鐘

GitHub Actions OIDC immutable subject claims:IAM 信任政策怎麼遷移?

GitHub Actions 用 OIDC 交換雲端短效憑證時,最容易被忽略的不是 id-token: write,而是雲端 IAM 信任條件裡的 sub(subject)字串。只要 repository 新建、改名、轉移,或管理員啟用 immutable subject claims,原本只用組織名稱與 repository 名稱的信任政策就可能不再匹配。

先講結論:2026 年 7 月 15 日之後建立的 repository,預設使用含 owner ID 與 repository ID 的 immutable sub 格式;更早建立的 repository 會保留舊格式,除非主動 opt in。 更新雲端 trust policy 前,先用實際 workflow 取得並檢查 token claims,再按照 repository 使用的格式調整條件。GitHub Enterprise Server 目前不提供這套 immutable subject claims。

這不是把 OIDC 改成另一種登入協定,而是改變雲端在 sub 上看到的識別內容。它解決的是名稱被回收後可能重用同一個 subject 的風險,但也要求部署端把「名稱」和「不可變 ID」的遷移順序排好。

如果你的 OIDC 是為了 release provenance,還要把 trust policy 和 artifact attestations 的 subject 設計 分開審查;如果它位於 reusable workflow,則應另外核對 secrets 傳遞與 caller/called workflow 邊界

先看舊格式與 immutable 格式#

octo-org/octo-repomain branch 為例,GitHub 官方文件列出的差異如下:

repository 狀態sub 範例
舊格式repo:octo-org/octo-repo:ref:refs/heads/main
immutable 格式repo:octo-org@123456/octo-repo@456789:ref:refs/heads/main

如果 job 使用 environment,sub 的 context 會改成 environment 形式,例如:

repo:octo-org@123456/octo-repo@456789:environment:Production

這些數字只是官方格式示例,不是你的 repository ID。不要把文章、別人的 IAM 設定或 repository URL 中的數字直接貼進生產政策;應從你自己的實際 token、GitHub API 或 repository 設定取得值。

為什麼名稱不夠安全?#

舊的預設 sub 主要使用 organization 和 repository name。如果 repository 被刪除,名稱在之後被另一個 owner 重新建立,雲端 trust policy 看到的字串可能一樣,卻已經不是原來的 repository。Immutable 格式把 owner ID 和 repository ID 放進 repo segment,讓名稱變更或 namespace 重新建立時更容易維持唯一性。

目前需要特別盤點三種事件:

  • 2026 年 7 月 15 日之後新建 repository:預設直接使用 immutable 格式。
  • 2026 年 7 月 15 日之前的既有 repository:預設保留舊格式,除非 opt in。
  • 2026 年 7 月 15 日之後的 repository rename 或 transfer:GitHub 文件指出會移到 immutable 格式。

如果同一個組織同時有新舊 repository,不能把一條以 repo:ORG/REPO:* 為基礎的政策當成所有 repository 都會通過;每個 trust relationship 都要核對它實際收到的 sub

OIDC workflow 先只做 claims 檢查#

GitHub 官方提供 github/actions-oidc-debugger action,可以在接雲端 provider 前查看 workflow 會收到的 claims。最小的檢查 workflow 可以長這樣:

name: Inspect Actions OIDC claims
on:
workflow_dispatch:
permissions:
id-token: write
jobs:
inspect:
runs-on: ubuntu-latest
steps:
- name: Print OIDC claims
uses: github/actions-oidc-debugger@main

id-token: write 的意思是允許 workflow 向 GitHub OIDC provider 取得 JWT,不是讓 job 對其他資源取得 write access。這個 debug workflow 不需要 checkout;如果你的實際工作還要讀取原始碼,才另外加入 contents: read

在共用 repository 或生產環境使用 action 時,應依組織供應鏈政策把 action pin 到受信任的 commit SHA;上面的 @main 只是為了對照官方 debugger 的最小概念範例。Debug log 可能包含不應公開的 claims,請限制 workflow 的觸發者和 log 存取權,不要把完整 JWT 複製到 issue 或聊天頻道。

檢查結果至少記錄:

Claim用途
iss確認 issuer 是 https://token.actions.githubusercontent.com
aud確認 audience 和雲端 login action/provider 條件一致
sub確認 IAM trust policy 應比對的主體格式
repository_idrepository_owner_id對照 immutable repository/owner ID
refenvironmentjob_workflow_ref確認 branch、environment 或 reusable workflow 的實際邊界

雲端信任政策的遷移順序#

不要先在 GitHub 啟用新格式,再回頭猜雲端應該改成什麼。較安全的順序是:

  1. 列出所有使用 GitHub OIDC 的 AWS、Azure、Google Cloud、Vault 或其他 provider trust relationship。
  2. 對每個 repository 和觸發條件執行受限制的 debug workflow,保存 issaudsub 和非敏感識別資訊。
  3. 先在 cloud provider 建立能匹配新格式的條件;如果 provider 支援短暫並存,舊格式條件應設定清楚的移除期限,不要用無限制 wildcard 代替遷移。
  4. 依 GitHub OIDC 設定 UI 或 REST API 為既有 repository opt in,或套用組織的 subject customization;不要把 opt-in 和雲端 login action 的 audience 設定混為一談。
  5. 執行實際部署 workflow,確認雲端收到的新 subaudjob_workflow_ref 都符合預期。
  6. 確認所有舊版 workflow 都已切換後,再刪除舊 trust condition,並保留回滾紀錄。

GitHub 文件特別提醒,如果要自訂 sub template,應先在雲端建立匹配條件,再透過 API 套用 GitHub 設定,避免 token 已改格式但 provider 尚未同步。自訂 subject 會改變整個 sub 的格式;對 immutable repository 而言,owner ID 與 repository ID 仍會保留在 repo segment,不能靠 include_claim_keys 移除。

Provider 條件只換字串,不要放寬邊界#

不同雲端 provider 寫 trust condition 的語法不同,但核心都是讓 sub 精確對應 GitHub token:

Provider舊格式條件概念Immutable 格式條件概念
AWStoken.actions.githubusercontent.com:sub 等於舊 repo: 字串同一個 claim 改成含 owner/repo ID 的字串
AzureFederated credential 的 subject 等於舊格式subject 改成 immutable 格式
Google Cloudassertion 的 sub 比對舊格式assertion.sub 比對 immutable 格式
HashiCorp Vaultbound_subject 使用舊格式bound_subject 使用 immutable 格式

不要因為遷移麻煩就把條件改成只驗 repository_owner、只驗 aud,或對整個 organization 使用寬鬆 wildcard。若部署需要限制 branch、environment 或 reusable workflow,就把它們一併納入明確的 claims 設計。真正需要的最小權限,應在 cloud role 的 permission policy 另外維持。

什麼時候用 subject customization?#

Immutable default 解決 repository identity 的唯一性;subject customization 則處理更細的信任條件。例如組織想要求所有部署都經過固定 reusable workflow,可以使用 job_workflow_ref 作為 sub 的一部分。這是另一個設定層級,不能因為看到 include_claim_keys 就以為等同於 immutable default。

目前文件列出的幾個選擇方向是:

  • 只限制某個 repository:使用 repo 條件。
  • 限制 environment 或 branch:使用預設 context 的對應格式。
  • 統一組織部署入口:把 job_workflow_ref 納入條件。
  • 依 repository metadata 做 ABAC:使用 repo_property_* claims,但要先由組織或 enterprise 管理員啟用。

每次改 template 後,都要重新取得一個新 job 的 token 驗證;舊 job 的 JWT 不會因設定修改而變成新格式。

排錯清單#

Not authorized 或 STS 信任失敗#

先把雲端錯誤分成 issuer、audience、subject 和 permission 四類。若 issaud 正確、只有 sub 不匹配,優先檢查 repository 是否新建、rename、transfer 或已 opt in immutable claims。不要一開始就提高 cloud role 權限。

Debugger 取不到 token#

確認 workflow 或 job 有 id-token: write,且是 GitHub Actions 執行的 job。缺少這項 permission 時,action 不能要求 OIDC JWT;它和 contents: readsecrets 或 cloud provider 的 role permission 是不同邊界。

只有 reusable workflow 失敗#

檢查 token 是由哪個 workflow 產生,以及 caller 和 called workflow 的 repository/organization 關係。跨 organization 或 enterprise 的 reusable workflow,官方要求在 caller workflow 或 job 明確設定 id-token: write;同時確認 job_workflow_ref 是否真的被拿來做 trust condition。

GHES 找不到 immutable 格式#

目前 GitHub 文件把 immutable subject claims 限定在 GitHub.com,GHES 不提供這項 rollout。請依 GHES 的 OIDC 文件與實際 claims 設計條件,不要把 GitHub.com 的 owner/repo ID 格式硬套上去。

常見問題#

Q: 既有 repository 會自動改成 immutable sub 嗎?#

A: 官方目前的說明是,2026 年 7 月 15 日前建立的 repository 保留舊格式,除非 opt in immutable subject claims;同日後的新建、rename 或 transfer 事件則採用 immutable 格式。請以 debug workflow 取得的實際 token 為準。

Q: id-token: write 會讓 workflow 可以寫入雲端資源嗎?#

A: 不會。它只允許 workflow 取得 OIDC JWT;真正能不能換成 cloud role,以及 role 能做什麼,仍由 provider 的 trust condition 和 permission policy 決定。

Q: 可以直接用 repo:ORG/REPO:* 同時支援新舊格式嗎?#

A: 不能假設可以。Immutable 格式在 owner 和 repository 名稱後加入 @ID,字串結構已經不同;是否能在 provider 中同時設定兩個精確條件要看 provider 語法。遷移期間寧可短暫列出兩個可審核的值,也不要用會放行未知 repository 的 wildcard。

Q: Subject customization 和 immutable subject claims 是同一件事嗎?#

A: 不是。Immutable default 把 owner/repository ID 放進預設 sub;customization 則用 include_claim_keys 改變 sub 的內容與信任條件。兩者可以一起影響 token,且 immutable repository 的 ID segment 不能被 customization 移除。

查證範圍:本文於 2026-09-08 檢查 GitHub Actions 官方 OIDC reference 與 immutable subject claims 說明;YAML、debugger 和 provider 條件為未連接實際雲端帳號的示例,沒有在本機或 GitHub repository 執行。

參考資料:

GitHub Docs:OpenID Connect reference

GitHub Changelog:Immutable subject claims for GitHub Actions OIDC tokens

GitHub Actions OIDC immutable subject claims:IAM 信任政策怎麼遷移?
https://laplusda.com/posts/github-actions-oidc-immutable-subject-claims/
作者
Zero
發佈於
2026-09-08
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。