2026 年 Mac 雲 CI 裡做 Apple 公證(Notarization):notarytool 憑據、常見拒絕項與「無頭 SSH vs 短時桌面會話」分流決策表
很多團隊已經能在 Mac 雲節點上穩定 xcodebuild archive,卻卡在「公證」這一步:要麼 notarytool 報憑據錯誤,要麼 Apple 返回難以解讀的拒絕詳情,要麼流水線必須突然接入圖形會話。本文給出一套可寫進 Runbook 的分流方法:先用對照表歸類失敗,再用決策矩陣判斷純 SSH 是否足夠,最後給出 notarytool 提交、輪詢、stapler 與日誌保留的五步落地順序,並附 Mac 雲側磁碟與並發建議。
本文要點
1. 痛點拆解:公證與上傳、籤名混為一談
在 Mac 雲或自託管 Runner 上,常把三條鏈路捆在一起:代碼籤名、Apple 公證(Notarization)、App Store Connect / TestFlight 上傳。相關但憑證與失敗語義不同。
- 籤名:Profile、證書鏈與 Hardened Runtime 決定
codesign;失敗多在 Archive/export,日誌在xcodebuild。 - 公證:向 Apple 提交 zip/dmg/pkg 等待檢物;拒絕多在 notarytool 的 JSON 或
log輸出,而非本地編譯器。 - 上傳:Transporter/Fastlane 等走 App Store Connect API Key;與公證端點不同,混用 Secrets 會失去分層排障。
三層拆開,是在 Mac 雲「像管 VPS 一樣 SSH」前提下穩定自動化的關鍵。
2. CI 公證失敗類型對照表
用於快速定位:先查籤名/entitlements,還是先查 notarytool 與網絡。
| 現象 | 更可能根因 | 優先動作 |
|---|---|---|
notarytool 立即報認證失敗 | App Store Connect API Key 與公證用途不匹配、Key 過期、Issuer ID 填錯 | 核對 Key 權限、.p8 路徑、CI 機密注入是否截斷換行 |
提交成功但長時間 In Progress | Apple 側隊列、包體過大、或掃描命中額外啟發式 | 保留 submission id,使用 notarytool log 拉取詳情;對大包體設置更長超時 |
| 拒絕信息指向 hardened runtime / library validation | 嵌入二進位未籤名、使用了不當的 disable-library-validation、或 Helper 未獨立籤名 | 對 app bundle 做 codesign --verify --deep 與 entitlements diff |
| 僅 CI 失敗、本機圖形會話成功 | 鑰匙串或交互依賴 | 見第三節矩陣:短時 VNC 或拆分人工一步 |
3. 無頭 SSH 與短時桌面會話:決策矩陣
Mac 雲可像 Linux 一樣管 launchd/SSH;公證偶發需圖形或鑰匙串解鎖,下表作工程分流(安全邊界由團隊自定)。
| 維度 | 純 SSH 無頭(推薦默認) | 短時桌面 / VNC 會話 |
|---|---|---|
| 憑據形態 | 使用 API Key + notarytool 非交互參數;Secrets 只注入到 CI Job 環境 | 需要鑰匙串解鎖、系統彈窗或僅 GUI 工具才能完成的步驟 |
| 可審計性 | 日誌可完整落盤到構建目錄並隨製品歸檔 | 人工步驟多,需額外錄屏或雙人覆核才能滿足審計 |
| 穩定性 | 適合 7×24 重複執行與多分支並行 | 適合低頻、關鍵路徑上的例外流程,不建議作為默認路徑 |
| 與 Mac 雲的結合方式 | launchd 固定 PATH,CI 用戶與 Xcode 命令行工具版本釘死 | 為公證子任務單獨隊列,避免與重負載 xcodebuild 爭用 CPU 與磁碟 |
4. 五步落地:notarytool → 輪詢 → staple → 歸檔 → 回滾
2026 年仍可復用的最小順序;flag 以本機 xcrun notarytool 幫助為準。
- 凍結工具鏈:鏡像記錄
xcodebuild -version,CI 顯式鎖定,避免靜默升級致行為漂移。 - 準備提交物:dmg/zip/pkg 記 sha256;路徑在構建目錄內且 CI 用戶可讀;大包預留臨時空間。
- submit:API Key 調用
notarytool submit,stdout/JSON 寫入artifacts/notary/submit.log。 - 輪詢:
notarytool info等輪詢,隊列高峰指數退避;失敗用notarytool log拉詳情並隨製品上傳。 - staple 與回滾:對 dmg/pkg 執行
xcrun stapler staple;日誌與包一併歸檔;staple 失敗則阻斷髮布並保留上一版製品。
示意(請替換 Key 與路徑):
5. 可引用參數:超時、磁碟與並發
供容量評審與 Runbook;以 Apple 文檔與合規為準。
- 磁碟:公證伴隨解包壓縮;在已有 Archive 外建議約 25GB 峰值緩衝;低於約 10GB 應拒新 Job 或清
DerivedData/舊ipa。 - 輪詢:拆分「已提交」與「已公證」指標;單 submission 上限約 45–90 分鐘並按包體分層。
- 並發:同機多 notary 易搶 IO;公證並發建議 1–2,與重編譯錯峰。
- 日誌與密鑰:notary JSON/log 建議保留約 90 天;與上傳日誌分庫。公證 Key 與上傳 Key 分離並按約 90 天輪換。
6. FAQ 與和 TestFlight 鏈路的銜接
問:公證和 TestFlight 上傳哪個先做? 常見是先籤名與公證/staple,再上傳;順序須與 export 形態一致並寫進 Runbook,避免 Gatekeeper 與渠道狀態不一致。
問:CI 裡 notarytool 偶發網絡錯誤? 查代理 HTTPS_PROXY/NO_PROXY;公證與上傳域名可能不同。
問:能否完全避免 VNC? 多數可以;若遇鑰匙串/圖形依賴,優先拆分密鑰與單步人工,而非長期桌面共享。
筆記本易受關機與策略影響;純託管分鐘 Runner 大包公證成本高。要穩定 Apple 工具鏈與可審計 Key、少扛硬體運維時,專用 Mac 雲更適合「籤名—公證—上傳」;可結合站內 TestFlight 文對齊 Job 與 Secrets。