2026年遠端 Mac 無頭公證流水線選型:notarytool App Store Connect API 與鑰匙圈 Profile 對比 + stapler 與 notarytool log 的 SSH 排錯決策表與 FAQ
把公證從「本機 GUI 偶發」收斂成可稽核的流水線:先選對 notarytool 鑑權模型,再以 stapler 與 notarytool log 分工排錯。本文面向 SSH 登入的遠端 Mac/CI Runner,提供對照表與現象驅動的決策表。
1. 2026 年為什麼預設用 notarytool
Apple 已推動開發者從舊的 altool 遷到 notarytool(Xcode 與 Command Line Tools 內建)。在無頭遠端 Mac 上,它的價值在於:同一套 CLI 完成提交、查詢歷程、拉取詳細日誌,便於寫進指令稿與 Runbook,而不依賴易碎的上傳通道或手動開網頁。
流水線心智模型可固定為三步:簽署產物 → notarytool submit(取得提交 ID)→ 輪詢直至成功 →(選用)stapler staple 把票證寫回磁碟。其中「憑證放哪裡」決定你能不能穩定跑在 SSH 工作階段裡。
2. 兩種鑑權:App Store Connect API 金鑰 vs 鑰匙圈裡的 Profile
2.1 App Store Connect API(Issuer ID + Key ID + .p8)
在 App Store Connect 的「使用者與存取 → 金鑰」建立 API 金鑰,下載 .p8(僅一次)。notarytool 透過 --key、--key-id、--issuer 使用它。典型優勢:
- 無互動:不依賴 Apple ID 密碼與簡訊/裝置雙重驗證,適合 CI。
- 可輪換與撤銷:金鑰生命週期清楚,外洩面可控。
- 權限邊界:依角色限制能做的事,便於合規稽核。
實務上把 .p8 放在建置機受控目錄(權限 600)或經密鑰管理注入,不要提交進 Git。與「匯出 iOS 再在遠端 Mac 上跑 Xcode」類流程銜接時,可對照
2026年雲端 Mac mini 建構可靠的設計與實踐(iOS CI 場景)
把歸檔、簽署與公證拆成可重複階段。
2.2 鑰匙圈 Profile(notarytool store-credentials)
notarytool store-credentials 可把 Apple ID 或 API 憑證以「具名 Profile」存進登入鑰匙圈,之後用 --keychain-profile "名稱" 呼叫。適合互動式建立一次、長期在同一使用者工作階段下重複使用的情境。
在遠端無頭環境要注意:SSH 非登入 shell、常駐程序、多 Job 並行 時,鑰匙圈解鎖狀態與「哪個使用者的登入鑰匙圈」不一致,會導致「本機手動能公證、流水線隨機失敗」。若要為 SSH 無頭實驗室補齊帳戶與目錄隔離,可一併參考 2026 最佳「無頭」開發實戰:利用 SSH 在遠程 Mac mini 上構建全自動化 CI 實驗室的避坑指南 ,把建置身分與鑰匙圈上下文寫進同一套 Runbook。
3. 選型對照表(抄進 Runbook 即可)
| 維度 | ASC API 金鑰(.p8) | 鑰匙圈 Profile |
|---|---|---|
| 無頭/CI 友善度 | 高:參數或環境變數注入即可 | 中:依賴鑰匙圈解鎖與使用者脈絡 |
| 憑證輪換 | 換 Key、改流水線變數即可 | 需更新鑰匙圈項目或重建 Profile |
| 多 Job 並行 | 每個 Job 可讀同一 .p8(注意檔案鎖與權限) | 易與鑰匙圈 ACL/工作階段爭用糾纏 |
| 合規與稽核 | 金鑰 ID、簽發紀錄清楚 | 需額外紀錄「哪台機、哪使用者」上的 Profile |
| 典型建議 | 共用 Runner、遠端 Mac 租用節點、多儲存庫 | 單人開發機、固定登入工作階段 |
結論:2026 年團隊級遠端 Mac 公證流水線,預設選 ASC API + .p8;僅在明確能固定「同一 macOS 使用者 + 可靠解鎖鑰匙圈」時再優先考慮純 Profile。
4. stapler 與 notarytool log:SSH 上的排錯分工
兩者解決不同問題:stapler 面向本機磁碟上的套件是否已附公證票證、Gatekeeper 視角是否自洽;notarytool log <submission-id> 面向Apple 伺服器端對你這一次提交的判定細節(含失敗原因條目)。
| 現象(SSH 上常見) | 優先動作 | 原因 |
|---|---|---|
notarytool submit 回傳 Invalid/Rejected |
立刻拉 notarytool log <id>(或 history 找到 id 再 log) |
根因在伺服器端掃描結果,stapler 看不到 |
| 公證狀態已是 Accepted,但下載方仍報未公證 | 對發佈物執行 stapler staple,再 stapler validate |
票證未嵌入 DMG/ZIP 內層 app,或發錯了未 staple 的副本 |
| 僅想確認「磁碟上這份」是否帶票 | stapler validate/spctl 類檢查 |
無需再呼叫 Apple API,適合快速門檻 |
| 同一指令稿「有時過有時不過」 | 先固定提交 ID 對照兩次 log;再查鑰匙圈/並行/網路 Proxy | 偶發多與憑證脈絡或上傳完整性有關,log 能區分「同因重現」還是「環境漂移」 |
5. FAQ:無頭公證最常見坑
Q1:CI 裡提示無法存取鑰匙圈或找不到 Profile?
優先懷疑:Job 跑在與你 store-credentials 時不同的使用者,或登入鑰匙圈未解鎖。下一步:改為 ASC API 三件套;若必須堅持 Profile,把 Runner 服務與鑰匙圈解鎖寫進 launchd 且序列化簽署/公證階段。
Q2:Accepted 了但 stapler 報錯?
優先懷疑:staple 的物件類型不對(例如應先對 app 再封 DMG)、或路徑唯讀/沙箱限制。下一步:對照 Apple 文件對「可 staple 的格式」的說明,確認流水線操作的是同一路徑副本。
Q3:log 裡出現簽署、Hardened Runtime、entitlements 相關條目?
優先懷疑:公證前程式碼簽署與權限宣告不一致(含巢狀 helper)。下一步:在同一台遠端 Mac 上重現建置,以 codesign -dvvv 與 entitlements 對照清單,修完再 submit,避免「本機修、CI 仍舊指令稿」。
Q4:網路走 Proxy 導致上傳失敗?
優先懷疑:企業 Proxy 對 Apple 上傳網域中斷或 MITM。下一步:為建置節點設定直連或允許清單;在 SSH 上以小檔試跑 submit 驗證 TLS,再接入大型產物。
在 Mac mini 上跑公證流水線,為什麼更省心?
notarytool、codesign、stapler 都是 macOS 原生工具鏈的一部分;在 Apple Silicon Mac mini 上,你能獲得與 App Store 生態一致的執行時期與安全堆疊,避免在異構環境裡反覆對齊「簽署+公證」的邊界條件。M 系列統一記憶體與極低待機功耗(約 4W 量級)也讓遠端節點適合長期無人值守:CI 佇列空轉時不吵、不燙、不斷電心疼。
對團隊而言,macOS 上 Gatekeeper、SIP、FileVault 與可稽核的鑰匙圈/檔案權限模型,能把「誰能在哪台機上提交公證」說清楚——正是流水線合規裡最難用虛擬機糊弄過去的一塊。若你正在搭一條從歸檔到公證的端到端鏈路,Mac mini M4 這類靜音小主機往往是性價比最高的真機基座;現在即可入手一台專屬遠端 Mac,把本文的 Runbook 落成穩定綠建置。