GitHub Actions workflow execution protections 怎麼設?用 ruleset 限制誰能觸發 CI
GitHub Actions 原本主要由 workflow 裡的 on、branch filter 和 job condition 決定何時執行。這些設定能縮小事件範圍,卻不能直接回答「哪一個人或哪一種 actor 可以讓 workflow 進入 runner」。GitHub 現在提供 workflow execution protections,讓管理員用 ruleset 在 workflow 開始前限制觸發者與事件。
直接結論是:把它當成 workflow 的前置准入層,不是 YAML 裡 on 的替代品,也不是 permissions 或 environment reviewer 的替代品。先用 evaluate mode 觀察會被擋住的 run,再啟用 active ruleset,避免把正常的 Dependabot、Copilot 或部署流程一起鎖死。 目前文件仍標示這項功能為 public preview,介面和規則可能變動。
這個 protection 解決哪一個邊界
GitHub 官方的說法是,workflow execution protections 會在 workflow 執行前評估 allow list;未通過的 actor 或 event 不會進入執行階段。這和 workflow 內的安全設定是不同層次:
| 控制面 | 它回答什麼 | 何時生效 |
|---|---|---|
on、branch/path filter | 哪些 repository event 會匹配 workflow | workflow 觸發判斷時 |
| workflow execution protections | 哪個 actor、哪個 event 可以觸發 workflow | runner 開始前 |
permissions | workflow 取得的 GITHUB_TOKEN 能做什麼 | job 執行時 |
| environment reviewers | 哪個部署 job 需要人工核准、何時可讀取 environment secrets | job 進入環境前 |
| 自動保留疑似惡意 workflow | 這一次 run 是否需要額外人工審查 | GitHub 判斷 run 風險時 |
例如 on: workflow_dispatch 只說明 workflow 支援手動執行;它不會單獨限制哪些 repository role 可以按下執行。execution protection 的 actor rule 才是處理「誰能觸發」的控制面。
Actor 和 event 是第一批規則
目前官方文件列出的規則有兩類:
- Actor rules:限制個人、repository role,以及 GitHub Apps、Copilot、Dependabot 等來源。
- Event rules:限制
push、pull_request、pull_request_target、workflow_dispatch等事件。
預設情況下,具有 repository write access 的使用者可以觸發 workflow。這不代表他一定能讀取 production secret 或推送程式碼,但它確實可能讓一份剛被修改的 workflow YAML 進入 runner;若該 workflow 具有過寬的權限,風險就會在執行時放大。
因此,規則設計應先從高風險事件與高權限 workflow 開始,而不是全 repository 一次禁止所有 event:
- 列出會使用部署 token、cloud credential 或 OIDC 的 workflow。
- 針對
pull_request_target、手動workflow_dispatch和需要 production environment 的流程先做 actor/event 盤點。 - 把正常的 Dependabot、Copilot 或 release automation 明確列入允許範圍,並用最小 permissions 限制它們能做的事。
設定位置與安全導入順序
GitHub 的設定路徑是 repository、organization 或 enterprise 的 Actions 設定:
- 開啟 repository 的 Settings。
- 進入 Actions > Policies。
- 建立 ruleset,加入 actor 和 event rules。
- 先選 Evaluate,觀察規則會擋下哪些 workflow run。
- 確認例外與維運流程後,再改成 active。
ruleset 的好處是可以沿用既有的 targeting 與 repository custom properties,把同一套政策套到一組 repository,而不是每個 workflow 各寫一份近似的 YAML。要注意的是,Evaluate mode 是觀察工具,不是安全封鎖;正式啟用前不能把它當成已完成的防護。
不要把它和其他核准機制混在一起
如果 run 顯示等待核准,先確認它屬於哪一種流程。既有的 GitHub Actions workflow 保留與核准檢查處理的是 GitHub 判斷疑似惡意的特定 run;environment reviewer 處理的是部署 job 的人工核准;workflow execution protections 則是讓 actor 與 event 在更前面就不符合政策。
同樣地,這項 ruleset 不能取代 pull_request_target 的安全邊界。即使 actor 與 event 被允許,workflow 仍不能在高權限上下文中直接執行不可信的 fork 程式碼;permissions、checkout 行為、secret 讀取和 action 版本仍要各自 review。
啟用前後怎麼驗證
至少留下四類測試案例:
| 測試 | 要觀察的結果 |
|---|---|
| 允許的 maintainer 手動觸發 | workflow 正常進入 run,token scope 沒有變寬 |
| 不允許的 role 觸發 | run 在執行前被 policy 擋住,沒有 runner side effect |
| Dependabot/Copilot 等自動來源 | 符合業務需求的 automation 沒被誤擋 |
pull_request_target 或高權限部署事件 | 只有明確核准的 actor/event 能進入 workflow |
把被允許與被拒絕的案例都放進 rollout 紀錄。規則只改變「能不能進入 workflow」,不會替你驗證程式碼、secret 或第三方 action,因此仍應保留 build、test 和部署前檢查。
結論:先控准入,再控權限
workflow execution protections 的價值是把「誰可以啟動 CI」從每份 YAML 拉到 GitHub 的集中政策。最安全的導入順序是先盤點高權限 workflow,再用 Evaluate mode 收集誤擋案例,最後同時檢查 actor、event、permissions 和 environment reviewer。這樣 ruleset 才是額外的前置邊界,而不是另一個難以追蹤的開關。
常見問題
Q: workflow execution protections 會取代 on 設定嗎?
A: 不會。on 仍然決定 workflow 監聽哪些事件與分支;execution protections 再往前加一層,限制哪些 actor 與 event 可以通過准入。兩者應一起設定,而不是把所有事件交給 ruleset 後刪掉 workflow filter。
Q: 這項功能會讓 workflow 的 GITHUB_TOKEN 自動變成唯讀嗎?
A: 不會。它控制 workflow 能否被觸發,permissions 才是 GITHUB_TOKEN scope 的控制面。即使 ruleset 已啟用,也要在 workflow 明確設定最小權限,並對 production environment 使用獨立核准。
Q: public preview 適合直接套到整個 organization 嗎?
A: 先不要直接全量啟用。GitHub 文件標示功能仍在 public preview,建議先用 repository 或可辨識的 custom properties 做 evaluate,觀察正常的 release、Dependabot、Copilot 和手動部署流程,再逐步擴大範圍。
參考資料:
GitHub Docs:Workflow execution protections
GitHub Changelog:Control who and what triggers GitHub Actions workflows
回報錯字、失效連結,或告訴我你想看的延伸主題。