跳轉到

D-20261103-01|PR 依賴稽核只擋新增的 advisories

背景與驅動力

issue 001248:security.yml 把同一個 pnpm audit --audit-level moderate 同時掛在 pull_request 與每週排程, PR 上對 base 分支本來就有的 advisories 一樣判失敗。npm 依賴依 .github/dependabot.yml 的政策走 exact pin+ 人工審查、不交 Dependabot,鎖檔自 2026-09 中起沒有再升版,master 的每週排程自 2026-09-14 起連續八週紅 (99 項:3 critical、49 high、41 moderate、6 low、3 ignored),於是每張 PR(含 Dependabot 的 GitHub Actions 升版)的 audit check 都紅、與該 PR 內容無關,merge 門檻失去訊號。解析顯示直接依賴只有 Angular 全家族 22.1.0 與 vitest 4.1.10,其餘全是傳遞依賴;pnpm-workspace.yaml 已有 overrides 與 audit.ignore 機制但 釘值落後。

考慮過的選項

  • B1 維持現況:升版完成前所有 PR 都紅,門檻等於關閉。
  • B2(採納):PR 只擋「相對 base 分支新增」的 advisories,每週排程仍整份把關;基線既有項由排程紅燈與人工 升版清償。
  • B3 PR 不跑 audit、只留排程:PR 新引入的 advisory 要等到下週才被看見。
  • A(同時裁決執行):升版一輪——Angular 22.2.x、vitest、更新與新增 overrides,每筆 override 附 GHSA 註解。

決定

  1. security.yml 分兩條路:github.event_name != 'pull_request'(排程)跑整份 pnpm audit --audit-level moderate; pull_request 以 git fetch --depth=1 origin $GITHUB_BASE_REF 取 base 的 pnpm-lock.yaml、package.json、 pnpm-workspace.yaml(含 audit.ignore)到暫存目錄另跑 pnpm audit --json --audit-level moderate 當基線, PR 端同樣取 JSON,再由 scripts/check-audit-diff.mjs 比對。
  2. 比對鍵=GHSA id+套件名:同一 GHSA 換到另一條依賴路徑不算新增,影響到另一個套件才算;只看嚴重度 ≥ 門檻 (與 --audit-level 同一門檻)。有新增即失敗並列出 GHSA、套件、修補版;既有項只列出不擋;已修掉的列出。
  3. 兩次 audit 的非零退出(有 advisories)以 || true 吞掉只取 JSON;缺檔或非 JSON(登錄表錯誤)由比對腳本 fail closed,不把登錄表故障當成通過。
  4. 規格:資安規範 6.2 表的「Audit warning ≥ moderate」改為上述兩段式口徑;程式架構/security.md 的 CI 兩道段同步, 並寫明 npm 依賴不交 Dependabot、overrides 由人工審查。
  5. 守門:scripts/check-audit-diff.test.mjs(新增/既有/已修掉分類、門檻、同 GHSA 另套件算新增、fail closed、 CLI exit code)與 scripts/workflows.test.mjs(security.yml 兩條路與 base 取檔指令)。

後果與影響

  • PR 的 audit check 重新成為「這張 PR 有沒有帶進新漏洞」的訊號;基線清償的壓力落在每週排程與升版 issue。
  • 升版一輪(決定 A)另記於 001248 時間線:直接依賴與 overrides 釘值更新後排程應轉綠;若仍有無修補版項, 走既有 audit.ignore+書面理由。
  • 不改任何執行期行為、SavedState 或共識。

定案紀錄

2026-11-03 使用者裁決「B2 加 A 全做」。