GitHub Secret Scanning 怎麼阻擋 PR 合併?用 ruleset 留住修補流程
GitHub 現在可以把 Secret Scanning 的結果接到分支 ruleset:Pull Request 的 head 尚未完成掃描,或 PR 引入的秘密仍有未處理告警時,就不能合併。這項功能目前是 public preview,規則名稱是 Require secret scanning alert resolution,所以啟用前要先在測試 repository 觀察實際告警量與團隊流程。
先講結論:先開啟 Secret Scanning 與對應的 Secret Protection/GHAS 能力,再為目標分支建立 ruleset,先用 Evaluate 觀察,確認告警處理流程後才切到 Active。 遇到阻擋時,不要只刪掉字串;應先撤銷或輪替秘密,再移除暴露內容並關閉告警,讓 PR 重新完成掃描。
這條規則和 push protection 有什麼不同
三個機制在不同時間點介入,混在一起設定時最容易讓團隊誤判:
| 機制 | 介入時間 | 它解決的問題 |
|---|---|---|
| Push protection | git push 時 | 在秘密進入 repository 前擋住 push,讓作者當場處理 |
| Secret Scanning alert | 掃描發現秘密後 | 建立告警、提供位置與秘密類型,供團隊調查與輪替 |
| PR merge rule | Pull Request 合併前 | 確認這個 PR 的秘密掃描已完成,且引入的告警都已處理 |
因此,已經通過 push protection 的內容仍可能因其他掃描結果在 PR 階段被擋;反過來,merge rule 也不是替代 push protection 的設定。既有的 GitHub Code Scanning Mitigated 關閉理由則是另一套程式碼掃描告警治理,不要把兩者的關閉理由混用。
啟用前要準備的條件
官方文件列出的前置條件可以整理成四項:
- Repository 或 organization 已有可用的 Secret Protection/GitHub Advanced Security 能力。
- 目標 repository 已啟用 Secret Scanning。
- 你有要套用的 branch ruleset,以及明確的 production 分支範圍。
- 團隊知道哪些秘密類型必須攔截:provider patterns、custom patterns 或 generic patterns。
這項規則不是把所有「看起來像密碼」的文字都當成確定秘密。它會依你選擇的 pattern 範圍判斷,而且官方目前註明 AI-detected secrets 不在這項 merge rule 的支援範圍內。
用 branch ruleset 建立 PR 合併閘門
可以依照下面的順序設定:
- 在 repository 的 Rules/Rulesets 建立或選取 branch ruleset,先鎖定需要保護的目標分支。
- 在規則清單加入 Require secret scanning alert resolution。
- 選擇要套用的 provider、custom 或 generic secret patterns。
- 先把 enforcement status 設成 Evaluate,讓規則產生評估結果但不要立刻攔住所有 PR。
- 用幾個包含正常變更、測試秘密和需要輪替秘密的 PR 觀察結果,再將規則切成 Active。
Evaluate 階段要記錄的不是「有沒有阻擋」而已,還包括掃描完成需要多久、告警是否能對應到實際 commit、誰負責輪替,以及關閉告警後是否能重新掃描通過。這些資料比直接把 Active 當成安全完成更適合拿來設計維運流程。
PR 會在什麼情況下被擋
這條 merge rule 主要有兩種阻擋情況:
- PR head 的 secret scanning 尚未完成。這時應等待掃描結果,不要因為畫面暫時沒有告警就當成安全。
- PR 引入的秘密仍有 open alert。即使作者已經在後續 commit 把字串刪掉,原本的告警也不一定會自動關閉。
處理告警時建議按照這個順序:
- 先在真正的 provider 端撤銷或輪替秘密,因為從 Git 歷史刪除文字不會讓已外洩的 token 失效。
- 在 PR 移除秘密,改用 repository secret、organization secret、OIDC 或其他不進版控的方式注入。
- 回到 Secret Scanning alert 確認新的掃描結果,必要時手動關閉已經完成修補的告警。
- 等待 PR head 掃描完成,再重新檢查 merge requirement。
如果告警來自測試值,也要先確認它不具備任何權限,再依團隊政策選擇關閉理由。不要把「這是測試 token」當成不需要記錄證據的例外。
一個可稽核的 rollout 流程
正式切 Active 前,可以把每個 repository 的 rollout 分成三個階段:
| 階段 | 建議動作 | 完成條件 |
|---|---|---|
| 觀察 | Evaluate、收集 PR 與掃描時間 | 知道告警來源、負責人和處理 SLA |
| 試運轉 | 只選一個高價值 production 分支切 Active | 正常 PR、秘密告警與誤用情境都能走完 |
| 擴大 | 套用到其他分支與 repository | 共享的輪替、稽核和例外流程已文件化 |
若 organization 同時有 GitHub Actions 權限與 reusable workflow 的治理需求,也應把 secrets 的注入方式一併檢查。Secret Scanning merge rule 只處理 PR 合併門檻,不會自動修正 workflow 權限、第三方 action 或 runtime authorization。
常見問題
啟用規則後,所有舊的 secret alert 都會擋 PR 嗎?
不一定。這條規則的重點是 PR 引入的秘密,以及該 PR head 的掃描狀態;既有歷史告警仍要依 Secret Scanning 的告警治理流程處理。實際套用範圍要以目標 branch ruleset 與選取的 patterns 為準。
為什麼我已經把 token 從檔案刪掉,PR 還是不能合併?
因為原本的 Secret Scanning alert 可能仍是 open,或新的 head 尚未完成掃描。先撤銷/輪替 token,再確認告警已依官方流程關閉,最後等待掃描完成。
這條規則可以取代 push protection 嗎?
不行。Push protection 在秘密準備進入 repository 時介入;merge rule 在 PR 要合併時再次確認。兩者是不同層次的防線,應依團隊的開發流程一起設計。
參考資料:
GitHub Changelog:Block pull requests with exposed secrets from merging
回報錯字、失效連結,或告訴我你想看的延伸主題。