2026 年 4–5 月,GitHub Actions 在 AI Coding Agents 的洪流下連續故障:單週 Actions 計算從 5 億分鐘跳到 21 億分鐘,Agent 週提交一度突破 275M,5 月 6 日 Copilot Cloud Agents 中斷期間 Actions Runner 失敗率達 17.1%,GitHub 官方啟動 30× 擴容計畫。同期 TanStack npm 5/11 供應鏈事件、Mini Shai-Hulud 蠕蟲掃 ~/.claude.json 與 MCP 設定,把 pull_request_target + fork checkout + CLAUDE.md 投毒這條新攻擊面拉到了主線。本文面向仍主要依賴 GitHub-hosted Runner 跑 iOS/macOS CI、又準備讓 Copilot Coding Agent / Claude Code / Cursor 自動開 PR 的中小團隊 Tech Lead 與 CI 維運者:先拆七大痛點,再給容量限額矩陣與信任邊界 / 攻擊面對照表,隨後給出八步落地清單、可引用資料與報錯排障矩陣,最後用新加坡 / 日本 / 韓國 / 香港 / 美東 / 美西六地遠端 Mac Mini M4 Pro 自架 Runner 收束 fork PR 與 Agent 觸達流量。所有資料點均來自 GitHub 官方公告、CSA 研究簡報、Runner Guard / Varden 等社群披露,發版後請重新打開連結核對。價格見 租用價格頁,下單見 訂購頁,遠端會話見 雲端說明;可與 GitHub Actions 遠端 Mac Runner 選型篇、Xcode Cloud 混合 CI 篇、CI 與 AI Agent 時間窗篇 交叉閱讀。
[ SECTION_01 ] // PAIN_MAP AI Agent 時代 GitHub CI/CD 最先翻車的幾個面
- Actions 佇列肉眼可見地變深:同一儲存庫在工作日早高峰開啟 Copilot Coding Agent 後,PR 觸發的工作流程從「秒級派工」變成「數分鐘 pending」,儀表板上
queued比例長期高於in_progress,團隊第一反應是 Runner 不夠,根因常是 Agent 把上游 webhook / queue 限額吃滿。 - Agent session 自身在尖峰期罷工:4 月起多次回報 agent session 啟動失敗比例尖峰達 84%,等待時間從 15–40 秒拉到 54 分鐘;快取 bug 還會把限流狀態延續到下一波,形成「連續多次小型停擺」,而不是單次恢復。
- Concurrency group 100 上限被觸發:開啟
concurrency: { group: ..., queue: max }後,Agent 連發數十個 fork PR 讓佇列爆 100,新進來的 run 直接被 reject;人類 push 也跟著排不進去。 - Webhook 速率撞牆:單一儲存庫工作流程觸發事件被限定 1500 / 10s、workflow run 佇列 500 / 10s;Agent 用腳本批次改檔案並 push 子分支時極易越線,被 GitHub 直接丟棄事件,CI 看似「沒人跑」實際是事件被吞。
- iOS/macOS 團隊首當其衝:GitHub-hosted macOS 並發槽位本就稀缺(Free 5 / Pro 5 / Team 5 / Enterprise 50),Linux Job 還能靠擴容緩一緩,Mac Job 直接被「鎖」在 5 路並發上,Archive 與公證排隊尤其難看。
- Agent 不可中止、稽核只剩日誌:workflow 一旦被 Agent 觸發就沒有 Cancel 按鈕,憑證使用、外發請求只能事後翻 workflow log;一旦 prompt injection 成功,留下的痕跡少且分散。
- 除錯回饋環被拉長:過去人類 PR 一天迭代 3–5 次,AI Agent 一天可以迭代上百次,每次都觸發 lint / unit / e2e;GitHub Actions 快取命中率下降、Elasticsearch 搜尋/索引服務擠兌,導致狀態檢查回寫延遲,開發者 UI 上看到的是「不知道有沒有跑完」。
[ SECTION_02 ] // SCALE_MATRIX Agent 流量打滿了 Actions 哪幾條限額:容量矩陣
把 GitHub 公布的 Actions 限額、並發槽位與 2026 年 Agent 實際負載放在同一張表上,能立刻看出哪一類瓶頸先到。下表資料來源於 GitHub 官方文件與 4–5 月公開事故覆盤,發版後以官方文件為準。
| 維度 | 官方限額 / 現狀 | Agent 時代的典型打法 | 先翻車點 |
|---|---|---|---|
| workflow 觸發事件 | 1500 / 10s / repo | Agent 在多 fork PR 上批次 push 子分支 | 事件被丟、CI 看似「沒人跑」 |
| workflow run 入佇 | 500 / 10s | 巨型 monorepo 的 reusable workflow 扇出 | 排隊溢位後整批被 block |
| concurrency group 佇列 | 100 / group(queue: max) |
fork PR 同 group 的多 Agent 並行 | 第 101 起被 reject |
| macOS 並發槽位 | Free/Pro/Team 5、Enterprise 50 | iOS PR 冒煙 + Archive + 公證 全打 macOS | Mac Job 排隊最顯眼 |
| Self-hosted job 佇列 | 排隊 24 小時未派工自動取消 | Agent 通宵打、本地 Runner 容量滯後 | job 被靜默 cancel,狀態混亂 |
| 平台總容量 | Actions 單週 21 億分鐘(2026Q2) | Agent 週提交一度 275M、PR 4M→17M | 30× 擴容仍滯後於增量 |
怎麼看這張表:對中小團隊,最先「肉眼可見」翻車的是 macOS 並發槽位與 concurrency group;對中大型 monorepo,更早先撞的是 webhook / workflow run 速率限額。Agent 的提交節奏與人類不同——它不會因為 review 等待自動減速,所以一旦把 Agent 接到「會觸發完整 CI 矩陣」的分支,限額幾乎會在數小時內被探到。
容量瓶頸不是「Runner 不夠」,而是事件 / 佇列 / 並發槽位三層限額,被 Agent 的提交節奏同時壓到上限;不重畫分流,單點擴容只是把痛點從 A 挪到 B。
[ SECTION_03 ] // TRUST_BOUNDARY pull_request_target 信任邊界塌陷與 CLAUDE.md 投毒攻擊面
容量問題之外,2026 年真正棘手的是新增的攻擊面。Cloud Security Alliance 5/3 的研究簡報把當前模式概括為「AI 程式碼 Agent 在 GitHub Actions 中處理不可信儲存庫內容(PR 標題、issue 內文、程式碼註解、分支名)的同時持有寫權限與 pipeline secrets」;TanStack 5/11 的 npm 供應鏈事件就是這條路徑在生產中被打穿的樣本。
下表對照常見設定與新攻擊面,落點是「哪些工作流程必須立即稽核」。
| 攻擊面 | 觸發條件 | 真實事件參考 | 最小修復方向 |
|---|---|---|---|
| pull_request_target + fork checkout | 用 pull_request_target 又 checkout fork 程式碼並跑建置 |
TanStack 5/11 npm 鏈式入侵 | 改回 pull_request;secrets 由 base 上 reviewer 顯式批後才釋放 |
| CLAUDE.md / .cursorrules 投毒 | fork PR 改寫 CLAUDE.md、copilot-instructions.md、.cursorrules |
Runner Guard RGS-010 已收錄 | Agent 設定只從 base 儲存庫載入,禁止信任 fork 路徑 |
| .mcp.json / MCP server 設定劫持 | Mini Shai-Hulud 抓 ~/.claude.json 與 MCP server 設定 |
Datadog Security Labs 公開樣本 | MCP 憑證不與 Agent 同行程;secrets 在沙箱外注入 |
| Prompt injection 經 PR 中繼資料進 Agent | PR 標題 / issue 內文 / 註解裡夾指令 | CSA 研究簡報案例 | 策略層在模型前過濾 + tool 白名單 + secrets 不入上下文 |
| Self-hosted Runner 被駐留 | 同一 Runner 跑多 PR、不重置環境 | Orca 2026 風險綜述 | Ephemeral Runner,每個 job 銷毀重建 |
| 三方 Action 與快取毒化 | 引用 uses: org/action@v1 而非 SHA;快取跨 PR 複用 |
TanStack 鏈路含 Actions 快取毒化 | 釘 SHA、快取按 trust 分桶、release-only Runner 禁用 PR 快取 |
三層結構是新基線:GitHub 公開的 Agentic Workflows 安全架構提了一個可借鏡的方向——把 Agent 行程的決策層、持有 secrets 的執行層、最終接觸發布憑證的憑證層分開,Agent 不直接持有 write token、secrets 只在下游 job 裡出現,而下游 job 僅在 Agent 輸出經過審核後才執行。這是一條「即使 Agent 被 prompt injection 也不至於直接打穿發布」的設計基線。
iOS/macOS 團隊為何更敏感:蘋果生態的發布通常涉及憑證、provisioning profile、App Store Connect API Key、公證帳號,這些都是「拿到一次就能造成長期影響」的強憑證。把它們與 Agent 觸達的 Runner 放在同一信任域裡,相當於把「最貴的 secrets」和「最不可信的輸入」裝在一台機器上——這是新架構裡第一個要拆開的盒子。
[ SECTION_04 ] // RUNBOOK 八步落地:自架 Mac Runner 分流與三段架構
下列步驟綜合 GitHub Actions 官方文件、CSA 與 Runner Guard 的公開建議,以及 NOVAKVM 遠端 Mac Mini M4 / M4 Pro 在多家 iOS 團隊的常用拓撲整理;如上游策略更新,請以官方連結為準。
https://docs.github.com/en/actions/security-for-github-actions
https://docs.github.com/en/actions/reference/limits
https://github.com/marketplace/actions/runner-guard
https://github.com/markndg/varden
- 稽核 pull_request_target:在儲存庫搜尋
pull_request_target,凡是同時執行actions/checkout指向 PR ref 且後續執行 build / publish / npm install 等指令的 workflow,都列入「待整改」清單;優先改回pull_request,必須保留 secrets 時拆分為「base 安全 job」和「fork 驗證 job」。 - 拆 fork-pr / trusted-build / release-only 三類 Runner 標籤:
fork-pr不持有任何 release secrets,只跑 lint / unit / 沙箱化 e2e;trusted-build處理已合併到受保護分支的常規建置;release-only在 protected environment 下跑公證、簽章、上架,啟用必填 reviewer。 - 把 fork-pr 標籤遷到自架遠端 Mac:在 NOVAKVM 遠端 Mac Mini M4 上以
--ephemeral模式註冊 Runner,每個 job 跑完即銷毀;macOS 用actions/runner自帶的 ephemeral 流程或 launchd 包一層重置腳本。這一步同時緩解 GitHub-hosted macOS 5 路並發的瓶頸。 - 按 region 路由 Agent 流量:給 fork-pr Runner 打上
region=ap-sg、region=jp-tk、region=us-west等標籤,workflow 裡按 PR 作者地區或簡單輪詢路由 Agent 觸發的 job;亞太 Agent 優先打到新加坡 / 香港 / 東京節點,歐美 Agent 走美東 / 美西,避免所有流量擠同一區域。 - 釘 third-party Actions 到 SHA 並掃 AI 設定投毒:所有
uses:改寫為org/action@<full-sha>;在fork-pr階段加入 Runner Guard 這類工作流程掃描,專門偵測CLAUDE.md/copilot-instructions.md/.cursorrules/.mcp.json在 fork PR 中是否被改寫。 - workflow 權限收窄 + OIDC + protected environments:頂層
permissions: read-all、按 job 顯式提升;publish / deploy 改走 OIDC 短期憑證而非長期 PAT;release 憑證統一收進 protected environment 並配 required reviewer。 - Runner 與 Agent 執行時擋板:fork-pr Runner 配置 egress 預設拒絕、按白名單放行(GitHub API、容器 registry、依賴鏡像);MCP / Agent tool 呼叫透過 Varden 類自架 firewall 走「allow / warn / block / monitor」策略,secrets 不進 Agent 上下文視窗。
- 30 天容量回顧閉環:每月查一次 Actions 用量、按 trigger 拆分 fork PR / 主分支 / 定時任務三類的占比;macOS 並發尖峰若長期 >80% 自架容量,按機型梯度(M4 16GB → M4 24GB → M4 Pro 64GB)+ 1TB / 2TB 擴容 + 並聯資源補位,租期上把日租做尖峰緩衝、月租做基線。
$ ./config.sh \
--url https://github.com/acme/ios-app \
--token "$RUNNER_TOKEN" \
--labels "self-hosted,macOS,arm64,fork-pr,region=ap-sg" \
--ephemeral
$ ./config.sh \
--url https://github.com/acme/ios-app \
--token "$RUNNER_TOKEN" \
--labels "self-hosted,macOS,arm64,trusted-build,region=ap-sg" \
--ephemeral
runner registered: fork-pr region=ap-sg ephemeral=true
runner registered: trusted-build region=ap-sg ephemeral=true
# release-only Runner 單獨部署在 protected environment 之後
name: ios-fork-pr
on: pull_request
permissions: read-all
concurrency:
group: fork-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
build:
runs-on: [self-hosted, macOS, arm64, fork-pr]
steps:
- uses: actions/checkout@<full-sha>
- uses: vigilant-llc/runner-guard@<full-sha>
with:
checks: rgs-010,rgs-011,unpinned-actions
- run: xcodebuild -scheme App -configuration Debug \
-destination "platform=iOS Simulator,name=iPhone 15"
[ SECTION_05 ] // HARD_FACTS 可引用資料與 GitHub Actions 排障對照
- Agent 週提交尖峰:275M / 週(來源:GitHub 官方與 byteiota 公開覆盤),同期 PR 月度從 4M(2025/9)躍至 17M(2026/3)。
- Actions 計算用量:2023 年 5 億分鐘 / 週 → 2025 年 10 億 / 週 → 2026Q2 單週 21 億分鐘(來源:GitHub Availability Report,4/28)。
- 30× 擴容計畫:10 月起的 10× 擴容方案在 2 月被判定不夠,目標改為 30×;30× 仍是「設計目標」而非已交付容量,工作日尖峰仍可能擠占。
- 5 月 6 日事故:Copilot Cloud Agents 數小時離線期間,Actions Runner 失敗率約 17.1%,根因定位到 runner 分配子系統在 Agent 突發請求下扛不住。
- Actions 佇列限額(來源:GitHub docs):workflow 觸發事件 1500 / 10s / repo;workflow run 入佇 500 / 10s;concurrency group 100;self-hosted job 佇列 24 小時未派工自動取消。
- macOS 並發槽位:Free / Pro / Team 計畫下 GitHub-hosted macOS 並發上限均為 5;Enterprise 50;larger runner 仍受同一上限。
- AI 設定投毒偵測:Runner Guard RGS-010/011 是首個針對
CLAUDE.md、copilot-instructions.md、.cursorrules、.mcp.json的工作流程掃描規則;TanStack 5/11 npm 與 Mini Shai-Hulud 蠕蟲均被納入 IOC。
| 表面症狀 | 優先懷疑 | 最小驗證動作 |
|---|---|---|
| Workflow 長時間 queued | macOS 並發槽位耗盡 / Agent 占滿佇列 | 查 Actions Insights 並發占比;評估 fork-pr 自架化 |
| Run cancelled — concurrency group full | concurrency group 越過 100 上限 | 按 PR 編號分 group;Agent fork-pr 單獨 group |
| 部分 push 沒觸發任何 run | Webhook 事件被 1500 / 10s 限流丟棄 | 查 webhook 投遞;讓 Agent 節流或合併 push |
| Self-hosted Job 24 小時後自動 cancel | Runner 容量長期不足或下線 | 檢查 Runner 在線率;ephemeral 失敗時回收資源 |
| fork PR build 拿到了 base secrets | pull_request_target + checkout fork ref |
改 pull_request;secrets 轉 protected env |
| Agent 行為突變 / 行為偏離 | fork PR 投毒 CLAUDE.md 或 .cursorrules |
Runner Guard 掃 RGS-010/011;Agent 設定僅從 base 載入 |
| 憑證、API key 出現在公網下載流量 | Mini Shai-Hulud 類 worm 抓 ~/.claude.json、MCP |
憑證輪換;MCP 設定移出 Agent 行程;egress 收窄 |
| npm publish 出現非預期版本 | release.yml 信任邊界塌陷 + 快取毒化 | publish 走 protected env + reviewer + OIDC + 釘 SHA |
[ SECTION_06 ] // PLATFORM_CLOSE 六地節點選型與為什麼 Agent 時代 fork PR 更適合遠端 Mac
把分流落到地理上,能進一步降低「集中式平台單點」的風險。新加坡 / 香港 適合作為亞太 Agent fork-pr 與 trusted-build 主力位,對華語與東南亞團隊 SSH、GitHub clone、Apple 公證回程延遲均較穩;東京 / 首爾 適合日韓客戶與 App Store 日韓區發布的 release-only Runner,把憑證與公證留在資料 residency 友善的節點;美東 / 美西 接歐美時區的 Agent 觸達流量與對接 GitHub、OpenAI / Anthropic API 的回程,避免與亞太 Agent 搶同一池資源。機型上,fork-pr 驗證位用 M4 16GB / 256GB 即可,每個 ephemeral job 跑完銷毀;trusted-build 主力建議 M4 24GB / 512GB;release-only 與多 Xcode 並存放 M4 Pro 64GB / 2TB 配 1TB / 2TB 擴容與並聯資源,相關分層與 Archive 預算可與 多 Xcode 篇 與 並聯資源篇 交叉閱讀。
替代方案的真實缺點:① 繼續完全押注 GitHub-hosted Runner,意味著把容量、信任邊界、debug 全部交給一個仍在 30× 擴容路上的平台,5/6 那種 17.1% Runner 失敗一旦再來,iOS 團隊最先被鎖;② 把自架 Runner 跑在辦公室 Mac mini 或開發者本機,缺乏 ephemeral、缺乏 region 分布、合蓋 / 重啟就掉隊,且與生產憑證同一信任域,恰好是 TanStack 事件中被打穿的位置;③ 用虛擬化 macOS VPS 跑 iOS CI,Apple 工具鏈相容性與公證流程穩定性在 Agent 高頻觸發下波動較大,對 Archive、模擬器並發的支撐不如裸金屬。
對要把 fork PR 驗證、release 憑證、Agent 觸達層 真正拆開 的 iOS / macOS 團隊而言,NOVAKVM 的 Mac Mini 雲端裸金屬租用通常是更優解:六地節點支援按 region 路由 Agent 流量、獨佔 Apple Silicon 適配 ephemeral Runner 與多 Xcode 並存、按天 / 按週 / 按月彈性下單可在 Agent 尖峰期快速補位、可與既有 GitHub-hosted 或 Xcode Cloud 組合做混合 CI。可在 NOVAKVM 租用價格頁 對照機型與租期,在 訂購頁 拉起一台 fork-pr 試驗機跑完兩個迭代週期;遠端會話與備份策略見 雲端說明,更深入的混合 CI 拓撲與時間窗排程可參考 Xcode Cloud 混合 CI 篇 與 CI 與 AI Agent 時間窗篇。