1844 字
9 分鐘

GitHub Actions 9 月更新:vulnerability-alerts 與 reusable workflow 怎麼用?

GitHub 在 2026 年 9 月初公布的 Actions 更新,對日常維護最有感的不是多了一個版本號,而是 workflow 權限與 reusable workflow 的身分資訊變得更明確。這次公告同時包含 self-hosted runner deprecation API;Runner 版本盤點已整理在 GitHub Actions 自架 Runner 更新清單,本文集中處理另外兩個會直接影響 YAML 與稽核流程的變化。

直接答案是:需要讀取 Dependabot alerts 的 job,在最小範圍加入 vulnerability-alerts: read;需要知道 reusable workflow 實際由哪個 repository、ref 和 commit 執行時,在被呼叫的 workflow 內讀取 job.workflow_refjob.workflow_shajob.workflow_repositoryjob.workflow_file_path。這兩項功能都不等於取得 secret scanning 權限,也不能繞過 GHES 或 fork/Dependabot 執行環境的限制。

先把 9 月更新分成三種問題#

更新主要用途你要改的地方
vulnerability-alerts permissionGITHUB_TOKEN 讀取 Dependabot alertsworkflow 或特定 job 的 permissions
job.workflow_* context在 job 中辨識目前 workflow 檔案的來源reusable workflow 的步驟與稽核輸出
self-hosted runner deprecation API盤點版本何時停止註冊或執行既有 runner inventory 與維運腳本

不要把三項更新塞進同一個「安全性升級」步驟。前兩項是 workflow 內容與權限設計;第三項是 runner 生命週期。拆開後,失敗時比較容易判斷是 token 權限、context 不可用,還是 runner 版本問題。

vulnerability-alerts: read 讀 Dependabot alerts#

GitHub Actions 的 permissions 可以設定在 workflow 頂層,也可以設定在單一 job。若只讓一個稽核 job 呼叫 Dependabot alerts,建議把權限放在 job 層級,讓其他 job 不會一起拿到不需要的 token scope。未明確指定的權限會變成 nonevulnerability-alerts 只接受 readnone,不能設定 write

下面的例子只列出目前 repository 的 Dependabot alerts,不需要 checkout 原始碼,因此沒有額外加入 contents 權限:

name: List Dependabot alerts
on:
workflow_dispatch:
jobs:
list-alerts:
runs-on: ubuntu-latest
permissions:
vulnerability-alerts: read
steps:
- name: Read Dependabot alerts
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
gh api --paginate "/repos/${GH_REPO}/dependabot/alerts?per_page=100" \
--jq '.[] | [.number, .state, .dependency.package.name, .security_advisory.severity] | @tsv'

這段 YAML 的重點不是 gh api 本身,而是權限邊界:

  • 只會授予這個 job 讀取 Dependabot alerts 的權限,其他未列出的 scope 維持 none
  • 如果 job 同時需要 checkout,才另外加入 contents: read;不要因為常見範本而把 contents: write 一起打開。
  • Secret scanning 不是這個 permission 的延伸功能。GitHub 文件指出,secret scanning 需要 GitHub App 或 personal access token 的相應能力,不能只靠 vulnerability-alerts: read 取代。
  • fork pull request 與 Dependabot 觸發的 workflow 仍有 token 只讀、不可使用 secrets 等限制;測試 permission 時要用實際事件再驗證一次。

若既有 workflow 已經在 job 層級明確設定 permissions,加入新的 key 後也要重新檢查其他 scope。GitHub 的行為是未列出的權限設為 none,所以「只補一行」可能讓原本依賴 contentspull-requests 的步驟失敗。

job.workflow_* 確認 reusable workflow 來源#

Reusable workflow 最常見的稽核問題是:呼叫端寫的是一個 ref,但實際執行 job 的 workflow 檔案來自哪個 repository、哪個 commit?新的 job context 欄位讓被呼叫的 workflow 可以把來源記錄下來:

Context代表的資訊
job.workflow_ref定義目前 job 的 workflow 檔案 ref
job.workflow_sha定義目前 job 的 workflow 檔案 commit SHA
job.workflow_repository定義目前 job 的 workflow 檔案 repository
job.workflow_file_pathworkflow 檔案在該 repository 的路徑

在 reusable workflow 內,這組值用來辨識 reusable workflow 自己的來源;它不是把 caller 的 repository 當成被呼叫檔案的來源。這個差異對跨 repository 的部署範本、稽核 log 和 checkout 很重要。

例如,平台團隊可以在 reusable workflow 內 checkout 定義該 workflow 的 repository 與 commit,並只記錄不含 secret 的來源欄位:

name: Reusable deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout workflow source
uses: actions/checkout@v6
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}
- name: Record workflow source
env:
WORKFLOW_REF: ${{ job.workflow_ref }}
WORKFLOW_SHA: ${{ job.workflow_sha }}
WORKFLOW_REPOSITORY: ${{ job.workflow_repository }}
WORKFLOW_FILE: ${{ job.workflow_file_path }}
run: |
printf 'workflow_ref=%s\n' "$WORKFLOW_REF"
printf 'workflow_sha=%s\n' "$WORKFLOW_SHA"
printf 'workflow_repository=%s\n' "$WORKFLOW_REPOSITORY"
printf 'workflow_file_path=%s\n' "$WORKFLOW_FILE"

這些欄位是來源資訊,不是授權決策的替代品。若部署流程要求只能使用已審核的 reusable workflow,仍應在 caller 端 pin 到受控的 commit SHA,並維持最小 token 權限;不要只把 workflow_ref 印進 log 就當作供應鏈驗證完成。若 reusable workflow 還會傳遞 secrets,權限和傳遞方式可對照 GitHub Actions reusable workflow 的 secrets 邊界

GHES 與跨事件測試不能省略#

GitHub 官方 contexts 文件目前註明,這四個 job.workflow_* 欄位在 GitHub Enterprise Server(GHES)不提供。若同一份 workflow 同時支援 GitHub.com 與 GHES,應把這些欄位視為可選資料,或由 caller 透過明確 input 傳入需要的識別資訊;不要在沒有 fallback 的情況下直接讓 null 進入部署路徑。

建議用以下矩陣做一次驗證:

測試情境要確認的結果
手動執行 Dependabot audit jobAPI 可讀取 alerts,未列出的 token scope 沒有被意外打開
caller 呼叫跨 repository reusable workflowjob.workflow_repositoryjob.workflow_sha 指向被呼叫的 workflow 來源
fork pull request 或 Dependabot 事件只讀 token 與 secrets 限制仍符合預期,log 不會洩漏敏感值
GHES runnerjob.workflow_* 不可用時,fallback 或明確跳過,不讓部署誤判來源
權限縮減後的完整 workflowcheckout、artifact、pull request comment 等既有步驟仍各自擁有必要的 read scope

測試時要保存 workflow run、事件類型、repository 與 commit,而不只是貼上一段成功的 console output。權限問題通常只在特定 trigger 或 fork 權限模式下出現。

一個可回滾的採用順序#

  1. 先複製現有 workflow 的成功 run 與目前 permissions 設定,作為 baseline。
  2. 只在 Dependabot audit job 加入 vulnerability-alerts: read,先驗證 API 和其他步驟。
  3. 在 reusable workflow 加入 job.workflow_* 的非敏感 log,確認 caller、ref、SHA 和 path 的實際值。
  4. 對 GitHub.com、fork/Dependabot 事件與 GHES 分別測試;為不可用的 context 加 fallback。
  5. 最後才把來源資訊接到稽核或部署策略,並保留能回到舊版 workflow 的 commit。

這樣可以把「取得資料」和「相信資料」分成兩個 review。新 context 能幫你看清楚 job 由哪個 workflow 檔案定義,但真正的供應鏈安全仍取決於 ref pinning、token 權限、runner 和部署端的驗證。

實務上,這次更新的重點是兩個小而清楚的邊界:Dependabot alerts 用 vulnerability-alerts: read 精準授權;reusable workflow 用 job.workflow_* 記錄執行來源。先在單一 job 和非敏感 log 驗證,再擴大到部署或稽核流程,回滾與定位都會比較容易。

常見問題#

Q: vulnerability-alerts 可以設定成 write 嗎?#

A: 不行。GitHub Actions workflow syntax 目前只接受 readnone;它是讀取 Dependabot alerts 的唯讀權限。若工作需要修改其他安全資料,應依該 API 的授權模型另行設定,不能把這個 key 當成通用安全權限。

Q: 加上 vulnerability-alerts: read 就能讀 secret scanning 結果嗎?#

A: 不能。Dependabot alerts 與 secret scanning 是不同的資料與授權邊界;secret scanning 需要 GitHub App 或 personal access token 的相應能力。不要用 workflow 的 GITHUB_TOKEN permission 直接推論另一個安全 API 也能呼叫。

Q: job.workflow_* 在 GHES 也能直接使用嗎?#

A: 不能直接假設可以。官方 contexts 文件目前將這四個欄位列為 GHES 不提供;跨平台 workflow 應準備可選欄位、明確 input 或跳過該段稽核邏輯的 fallback。

參考資料:

GitHub Changelog:2026 年 9 月初 Actions 更新

GitHub Docs:Workflow syntax — permissions

GitHub Docs:Contexts — job context

GitHub Actions 9 月更新:vulnerability-alerts 與 reusable workflow 怎麼用?
https://laplusda.com/posts/github-actions-september-2026-workflow-updates/
作者
Zero
發佈於
2026-09-06
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

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