每個 GitHub Actions 作業都會取得一個權杖。GitHub 會在每個作業開始時建立一個全新的 GITHUB_TOKEN,其範圍限定於工作流程所在的儲存庫,作業中的任何步驟都能使用它。它能做什麼,取決於許多團隊從未檢查過的設定,而在較舊的儲存庫中,答案仍然是「幾乎所有內容都能寫入」。

當作業中的某個環節變成惡意時,這點就很重要。在 2025 年 8 月的 Nx「s1ngularity」入侵事件中,該儲存庫的權杖仍具有讀取與寫入權限。pull_request_target 工作流程中的注入攻擊利用它觸發發布工作流程,進而外洩了被用來發布 Nx 惡意版本的 npm 權杖。若權杖是唯讀的,這一步就會被擋下。

本文說明權杖的權限如何設定、各項常見任務需要哪些權限,以及如何為您的工作流程找出最小權限。

GITHUB_TOKEN 是什麼

GITHUB_TOKEN 是 GitHub Actions 應用程式的安裝存取權杖。它有幾個容易被忽略的特性:

  • 無論您是否使用,它都存在。 工作流程以 secrets.GITHUB_TOKEN 參照它,但任何 action 即使沒有被傳入權杖,也能透過 github.token context 讀取它。
  • 預設會寫入磁碟。 actions/checkout 會為後續的 git 指令保存權杖,除非您設定 persist-credentials: false。v6 之前它會寫入 .git/config;v6 將它移到 $RUNNER_TEMP 下的另一個檔案。2024 年,Unit 42 的 ArtiPACKED 研究發現,權杖會透過包含 .git/config 的建置產物外洩。
  • 它隨作業一起失效。 在 GitHub 託管執行器上,這代表最長 6 小時,也就是作業的時間上限。在自架執行器上,它最長可更新至 24 小時。

由於權杖始終存在,您唯一能控制的就是它能做多少事。

預設值:permissive 或 restricted

每個企業、組織與儲存庫都有權杖的預設值:

  • Permissive: 所有權限皆可讀取與寫入。
  • Restricted: contents 與 packages 唯讀,其他皆無。

自 2023 年 2 月 2 日起,新的企業、組織與儲存庫預設為 restricted。這項變更並未影響既有的設定,因此在此之前建立的任何儲存庫或組織,除非有人更改過,否則仍保留 permissive 預設值。若較上層選擇了 restricted,其下的層級就無法選擇 permissive。

請在 Settings → Actions → General → Workflow permissions 中檢查,先從組織層級開始。同一區塊還有 Allow GitHub Actions to create and approve pull requests,除非有工作流程需要,否則應保持關閉。

permissions 鍵

工作流程中的 permissions 鍵會從預設值調整權杖的權限。它在兩個層級運作:

permissions:
  contents: read

jobs:
  release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<full-commit-sha>

規則如下:

  • 作業層級會覆寫工作流程層級。 將工作流程預設設為唯讀,只在需要的作業中提高權限。
  • 任何未列出的權限都會變成 none。 只要設定了一項權限,其他所有權限都會被移除。permissions: {} 會移除全部權限。
  • 值可以是 read、write 或 none。 write 包含 read。read-all 與 write-all 會一次設定全部權限;請避免使用 write-all。

截至 2026 年 9 月可用的權限:

權限控制範圍
actions工作流程執行、建置產物與快取
artifact-metadata建置產物中繼資料紀錄(2026 年起在這些 API 上取代 contents)
attestations建置產物證明
checks檢查執行與檢查套組
code-quality程式碼品質結果,例如覆蓋率報告
contents儲存庫內容、commit、分支、標籤與版本
deployments部署
discussionsDiscussions
id-token請求 OIDC 權杖(僅限 write 或 none)
issuesIssue 與留言
packagesGitHub Packages,包括容器登錄庫
pagesGitHub Pages 建置
pull-requestsPull request、標籤與審查
security-events程式碼掃描警示與 SARIF 上傳
statusesCommit 狀態
vulnerability-alertsDependabot 警示(僅限 read 或 none)

當作業缺少所需的權限時,API 呼叫會以 403 Resource not accessible by integration 失敗。這個錯誤是提醒您為該步驟加上它需要的那一項權限,而不是改用 write-all。

常見任務需要哪些權限

任務權限
簽出程式碼contents: read
建立版本或推送標籤contents: write
在 issue 或 pull request 上留言issues: write(pull request 留言透過 issues API 進行)
為 pull request 加上標籤或審查pull-requests: write
以 OIDC 向雲端供應商驗證id-token: write
建立建置產物證明id-token: write、attestations: write、contents: read,容器映像檔另需 packages: write
將映像檔推送到 GitHub Container Registrypackages: write
將 SARIF 上傳到程式碼掃描security-events: write
從工作流程部署 GitHub Pagespages: write、id-token: write

大多數測試與建置作業除了 contents: read 之外不需要任何權限。

Fork、pull_request_target 與 Dependabot

  • 來自 fork 的 pull request 在 pull_request 事件中會取得唯讀權杖,無論工作流程要求什麼,除非管理員開啟「Send write tokens to workflows from pull requests」。請保持關閉。
  • pull_request_target 即使是來自公開 fork 的 pull request,也會取得可讀寫的權杖。這就是許多知名權杖竊取事件的根源:Nx 入侵事件、2024 年 12 月的 Ultralytics 入侵事件,以及 2026 年 3 月的 Trivy action 入侵事件,都始於一個 pull_request_target 工作流程。GitHub 正在收緊它:自 2026 年 7 月起,actions/checkout 預設拒絕在這類工作流程中簽出 fork 的程式碼,而自 2026 年 11 月 2 日起,沒有自訂政策的公開儲存庫將預設停用 pull_request_target。
  • Dependabot 的 pull request 會被視同 fork:取得唯讀權杖,且沒有 Actions 機密。如果您正在評估其他更新工具,請參閱 Dependabot 替代方案。

如何找出最小權限

您不必閱讀每個 action 的原始碼來推敲:

  • GitHub Security Lab 的 actions-permissions 會監控工作流程如何使用其權杖,並建議最小權限。目前為公開 Beta。
  • OpenSSF Scorecard 的 Token-Permissions 檢查 會標記未在最上層設定唯讀權限的工作流程,並將此檢查評為高風險。
  • zizmor 是工作流程的靜態分析工具,會標記過多或預設的權限,以及會保存憑證的簽出。
  • StepSecurity 的 Secure-Repo 與 Harden-Runner 會依據 action 知識庫以及作業發出的 API 呼叫,建議作業層級的權限。

實際的導入方式:將組織預設設為 restricted,在每個工作流程最上方加上 permissions: contents: read,然後執行工作流程。以 Resource not accessible by integration 失敗的工作流程,會明確告訴您哪個作業需要哪項額外權限。

CRACI 的定位

最小權限限制了遭竊權杖能做的事,但無法阻止權杖被竊,而作業中的其他機密(例如 npm 權杖與雲端憑證)同樣暴露在風險中。

CRACI 在自己的執行器上執行您的 GitHub Actions 作業。您只要將 runs-on 改為 craci;GITHUB_TOKEN、permissions 鍵與儲存庫設定都照常運作,因為權杖仍由 GitHub 核發。CRACI 增加的是執行器上的能力:決定作業可連線到哪些主機、在作業開始前完成驗證並採失效即封鎖的對外連線政策,以及作業擷取的每個套件的紀錄與其網路連線的追蹤紀錄。即使作業中的惡意程式碼真的取得了權杖,政策也會限制它能傳送到哪裡,而紀錄會顯示發生了什麼事。

關於作業中的其他機密,請參閱 GitHub Actions 機密:如何外洩以及如何鎖定。預約示範,看看您自己的一次建置所留下的紀錄。