2026 年六國遠程 Mac:Jenkins 與 Buildkite Agent 憑證拓撲(機器用戶、OIDC、PAT)與 GitHub Actions/GitLab Runner 並存的互斥與租期 FinOps 檢查表

約 17 分鐘閱讀 · MACCOME

如果你在新加坡、日本、韓國、香港、美國東部、美國西部獨佔遠程 Mac上既要跑 JenkinsBuildkite 的 macOS Agent,又已經接了 GitHub ActionsGitLab 自託管 Runner,真正拖垮審計與預算的往往不是 CPU,而是第二套調度器帶來的憑證爆炸:誰持有長期 PAT、match 解密鑰匙串與 ASC 會話落在哪個用戶上下文、短租機重建後密鑰是否「順手複製進鏡像」。本文給你憑證拓撲 + 互斥 + 租期科目三張表,並與站內《Jenkins/Buildkite 錯峰常駐》《Runner 標籤與密鑰隔離》分工閱讀:前者管隊列與錯峰,本文只管身份、OIDC 與 revoke 路徑

六國獨佔機上「第二 CI 控制器」最常見的六類憑證事故

  1. 三套 agent 共用同一 macOS 用戶主目錄:Jenkins 的 ~/.ssh、Buildkite 的 buildkite-agent 與 Runner 的 actions-runner 若混在同一交互帳戶下,一次 git credential-osxkeychain 彈窗就能把無人值守打成「隨機綠」。
  2. 把 90 天輪換的 PAT 寫進短租鏡像:日租衝刺機每周銷毀,鏡像裡卻凍著組織級 PAT,洩露半徑覆蓋整個 org,而不是單臺構建機。
  3. 互斥鎖缺失導致 match 解密與 notary 並發:兩條流水線同時觸碰同一 match 倉庫或同一 ASC API Key 會話,表現為偶發 401/403,復盤時被誤歸為「蘋果側抖動」。
  4. OIDC audience 配錯在雲控制面:Buildkite 或 GitHub 的 OIDC trust policy 若未收窄到具體 repo/environment,agent 能換到「比 job 所需更大」的令牌面。
  5. 鑰匙串分區與 LaunchAgent 啟動順序未文檔化:重啟後 Jenkins 先起、Runner 後起,導致讀取到空鑰匙串分區,首條流水線失敗被人工點「重試」掩蓋。
  6. FinOps 只盯 vCPU 不盯「憑據壽命 × 租期」:長壽命密鑰綁在短租機上,財務看到的是便宜日租,安全團隊看到的是不可接受的撤銷窗口。

六國節點的物理價值是區位與獨佔 IO 可預期;若憑證拓撲寫不清,只是把「筆記本上的混亂」升級成「雲上可並發的混亂」。與《Xcode Cloud 混合 CI》並行時,還要額外回答:哪條身份能觸達 ASC、哪條只能觸達內網 Registry——否則混合矩陣會變成混合事故。

組織治理上建議引入憑據 RACI:平臺工程維護機器用戶與 OIDC 綁定,業務倉庫維護 workflow 級權限,安全團隊驗收 revoke 演練頻率;任何一方缺位都會在第二套控制器上線後指數放大。

維度 優先長壽命 PAT / 部署密鑰 優先 OIDC / 短期令牌
租期 僅允許落在月租及以上基線機,並配鏡像外密鑰注入 可落到日/周租峰值機,前提是控制面 trust 收窄
審計粒度 需額外記錄「誰把 PAT 寫進哪臺機」;旋轉窗口常與財務季對齊 雲側可綁定 repo、environment、agent 池;更易做按 job 歸因
與 Jenkins 插件生態 大量經典插件默認假設靜態憑據文件 需顯式改造 pipeline 或 wrapper;一次性成本高
與 Buildkite agent 鉤子腳本易偷偷 export 秘密 推薦 hooks 只做裝配,秘密來自 OIDC 交換的短時 token
與 GHA/GitLab Runner 自託管 runner 常見 .credentials 長期文件 GitHub/GitLab OIDC 換雲廠商 STS 已是主流路徑,應優先對齊
warning

紅線:不要在短租峰值機上生成組織級長期 PAT 或根級部署密鑰;若業務堅持,應把密鑰壽命與租期上限寫進同一張審批表,否則 FinOps 與安全永遠對不上帳。

六步 Runbook:從「能跑」到「能 revoke、能分攤科目」

  1. 盤點三套調度器實際觸碰的秘密面:列出 Jenkinsfile / Pipeline、Buildkite pipeline、GitHub workflow 各自讀取的環境變量與文件路徑;標記哪些是 org 級、哪些是 repo 級。
  2. 為每套 agent 分配獨立機器用戶與主目錄:例如 jenkinsbuildkiterunner 三分帳戶;禁止共用登錄會話做 CI。
  3. 為獨佔資源加互斥:match 解密、notary upload、ASC 瀏覽器會話類步驟必須串行;鎖名寫入 ROUTING.md 與流水線注釋。
  4. 把 OIDC trust 條件寫成可評審文本:audience、repository、ref 前綴、environment 名;與雲 IAM 或內網 STS 策略交叉對照。
  5. 做季度 revoke 演練:隨機作廢一類令牌,驗證三臺 agent 是否按預期降級而非靜默繼續。
  6. 把憑據壽命寫進租期 FinOps 表:長壽命只綁基線機;峰值機只出現短時 STS;科目與錯峰租期表同頁展示。
bash
# 示例:互斥鎖佔位(按你們協調後端替換 flock 實現)
exec 9>/var/lock/match-decrypt.lock
flock -n 9 || { echo "match decrypt busy"; exit 42; }

# 示例:機器用戶分軌(LaunchDaemon / plist 片段思路,勿照抄路徑)
# UserName=buildkite vs UserName=runner —— 各自 HOME 下只放自己的 git 憑據助手配置

三條應寫進評審紀要或 Grafana 註解的量化口徑(閾值按組織基線替換)

  • 長壽命秘密綁定短租機的 job 佔比:目標為 0%;若一周內採樣發現 >3% job 仍從日租機讀取 30 天以上 PAT,觸發安全例外審批。
  • 互斥鎖等待 P95(秒):對 match / notary 類步驟單獨打點;若 P95 持續 >600s 且隊列深度上升,優先擴容串行出口機而非加並行編譯機(示例閾值可按現網調整)。
  • OIDC 換票失敗率:按控制面與 region 拆分;若某六國節點所在大區對 STS 端點 RTT 上升,應先查網絡拓撲再調 runner 並發。

為什麼「全員 SSH 上去手動配一把鑰匙串」或「鏡像裡凍一份萬能 .env」在 2026 年比不加第二控制器更危險

手動配鑰匙串不可審計:誰最後一次解鎖、是否把交互式會話留在機房裡,都無法寫進 SOC2 證據包。鏡像萬能 .env 則把洩露面從「單個 repo」擴大到「任何能啟動容器的人」——與 OIDC 的「按 job 最小權限」哲學完全相反。

當你需要把 Jenkins/Buildkite 與 Runner 穩定並存獨佔 Apple Silicon、固定大區出口、可把基線租期與峰值租期拆科目的環境裡,MACCOME 的 Mac 雲主機更適合作為長壽命憑據的錨點機短時 OIDC 峰值機的物理承載:節點覆蓋新加坡、日本、韓國、香港、美國東部、美國西部,按日/周/月/季組合彈性租期,先把「誰能在哪臺機上活多久」寫清,再讓編譯並發去追吞吐,而不是在同一臺日租機上同時凍 PAT、跑五個 Simulator、再開三條 notary 上傳。

收束:憑證拓撲應成為 CLONE_POLICY 的姊妹篇 CREDENTIAL_ROUTING.md

交付物建議三張表:機器用戶與 HOME 映射互斥資源與鎖名OIDC trust 條件與 STS 作用域。新人第一天應能回答:我的 job 用哪張身份、失敗時該 revoke 哪一類令牌、短租機上為何沒有任何 90 天 PAT。

Runner 密鑰清單並聯時,請把「GitHub 側 OIDC」與「macOS 鑰匙串分區」寫進同一變更單,否則你會在雲端看到漂亮的 trust policy,在機上看到空的 keychain partition。

常見問題

同一臺六國獨佔機上可以同時跑 Jenkins、Buildkite 與 GitHub Actions Runner 嗎?

可以,但必須分用戶、分鑰匙串分區、互斥獨佔步驟,並避免三套流程共用長期 PAT。錯峰與隊列細節見錯峰常駐 Runbook;公開租期與檔位可先對照租賃價格說明

為什麼要把長壽命憑據綁在月租基線機?

日租機重建頻繁,靜態秘密容易進鏡像或備份鏈;基線機提供穩定審計錨點。運維說明也可查閱幫助中心 · 雲 Mac