Apple 的技術說明指出,altool 自 2023 年 11 月 1 日起不再被公證服務接受,現行命令列流程應改用 notarytool。Apple 的遷移說明 因此,遇到 macOS App 公證失敗時,不要反覆提交同一個 ZIP、DMG 或 PKG;先看 notarytool 狀態與日誌,判斷是認證、簽署、封裝還是票據階段出錯,再修復最終分發產物。即使結果顯示 Accepted,仍要完成 staple、Gatekeeper 檢查與獨立環境安裝驗收。
這篇適合使用 Developer ID 在 Mac App Store 之外發佈 App 的獨立開發者,也適合在遠端 Mac 或 CI 維護 notarytool、stapler 自動化的人員。若你的產品含有外掛、輔助工具、登入項目、DMG 或 PKG 等嵌套元件,下面的時間線尤其重要。
先保留現場,再決定是否重做產物
第一個里程碑:把失敗階段固定下來
先不要刪除原始產物、憑證、金鑰或工作目錄。把以下內容存放在同一個具備存取控制的發佈紀錄中:
notarytool submit的完整輸出;- 提交 ID、時間、使用的 Team ID 與已脫敏的 Bundle ID;
- 最終提交檔案的名稱、路徑與摘要;
- 執行時使用的 Xcode 路徑、
xcode-select或DEVELOPER_DIR設定; - 目前處於 Build、Archive、Export、Sign、Package、Submit、Accepted、Staple 還是 Gatekeeper 驗收階段。
Apple 的公證工作流程文件把提交、查詢狀態、取得日誌與票據處理視為不同步驟。這代表「指令成功結束」並不等於使用者下載的檔案已經能正常啟動。
notarytool 顯示 Invalid 後,如何找出具體錯誤?
使用提交 ID 查詢該次提交的資訊,再取得對應日誌;不要只依終端機最後一行文字猜測原因。日誌中若列出具體檔案路徑,先處理第一個有效錯誤,再重新檢查它所屬的嵌套層級。若只有一段泛化訊息,保留提交 ID 與原始輸出,並對照 Apple 的常見公證問題排解文件。
失敗狀態與下一個動作
| 觀察到的階段 | 你應保留的證據 | 下一個動作 |
|---|---|---|
| 認證失敗或尚未完成提交 | 脫敏後的認證方式、命令輸出、提交檔案摘要 | 先確認憑據來源與工具鏈,再決定是否重新提交 |
| 持續處理中 | 提交 ID、提交時間、狀態查詢結果 | 不要平行提交同一產物;必要時查看官方服務狀態 |
Invalid |
公證日誌、具體路徑與錯誤描述 | 修復最終產物,重新簽署與封裝 |
Accepted 但 staple 失敗 |
Accepted 資訊、stapler 輸出 |
確認操作的是同一個最終檔案,再做票據驗證 |
| 本機成功、使用者仍被攔截 | Gatekeeper 輸出、下載後檔案摘要、安裝環境 | 在沒有開發快取的 Mac 上驗證真實下載檔 |
如果提交長時間停留在處理中,不要把論壇個案中的等待時間當成固定規則;先核對Apple Developer System Status與官方文件,再判斷是否是服務端問題。
最終產物與原始 App:先檢查哪一個?
第二個里程碑:以 ZIP、DMG 或 PKG 為檢查對象
公證檢查的對象是你實際提交的分發產物,不是 Xcode 專案中尚未封裝的原始 App。你可能在本機檢查過 .app,但在 Export、打包 DMG 或建立 PKG 時又加入了另一個執行檔、外掛或安裝腳本,最後送出的內容已經不同。
先對最終產物做以下核對:
- App 主程式是否使用適合直接分發的 Developer ID 簽名;
- 是否啟用 Hardened Runtime,並使用安全時間戳;
- entitlements 是否只保留實際需要的項目;
- App 內的 Framework、Plug-in、XPC 服務、登入項目、輔助工具與其他可執行檔是否各自完成簽署;
- 外層封裝是否仍包含你檢查過的同一個 App。
macOS App 已簽名,為什麼仍然無法通過公證?
簽名只說明程式碼與簽名身分之間的關係,不能替你確認嵌套元件、Hardened Runtime、entitlements、時間戳與分發封裝都符合公證要求。特別是簽署完成後若再修改 Bundle、替換 Framework、加入檔案或重新壓縮,前面的檢查就不能視為仍然有效。
若你要比較 DMG、PKG 與 ZIP 的責任邊界,可參考 Apple 的Mac 軟體封裝說明。重點不是選一種「一定不會失敗」的容器,而是把產生容器之後的檔案視為新的發佈候選物。
用條件分支決定下一步
- 若日誌直接指向某個 Framework、外掛或輔助工具:先修復該最內層元件,再由內向外重新簽署。
- 若錯誤涉及安全時間戳或 Developer ID:先核對簽名身分與簽署時使用的憑據,不要直接更換憑證;更換前保留舊產物與回退方式。
- 若錯誤指向
get-task-allow或 entitlements 格式:回到 Export/Sign 階段修正設定,不要用遞迴簽署掩蓋權限結構。 - 若 App 通過檢查但 DMG 或 PKG 失敗:重新產生外層容器,確認沒有加入未簽署的程式碼。
- 若只有遠端 Mac 失敗,而本機成功:先比對 Xcode 路徑、Keychain 會話、憑據來源與實際提交檔案;不要先判定公證服務故障。
由內到外重簽:不要讓遞迴指令掩蓋結構問題
第三個里程碑:先修元件,再處理外層
安全的修復順序是:先確認並簽署最內層可執行檔,再簽署 App 本身,最後重新產生 DMG 或 PKG,並以新的最終產物提交。不要在一個結構尚未釐清的 Bundle 上直接使用遞迴簽署,因為它可能讓表面狀態看似更新,卻留下錯誤的 entitlements、遺漏的元件或不一致的簽署順序。
你可以把流程拆成明確的里程碑:
- 從乾淨的 Build 或 Archive 產生候選 App;
- 列出所有嵌套程式碼與其簽名狀態;
- 修復最內層元件,再簽署外層 App;
- 重新建立 ZIP、DMG 或 PKG,不沿用舊容器;
- 對新產物重新計算摘要並提交;
- 將新的提交 ID 與產物摘要寫入發佈紀錄。
PKG 需要特別小心:如果安裝器會在目標 Mac 投放其他可執行內容,不能只看安裝器外層是否通過。應依照 Apple 的公證流程說明確認實際分發內容與所需的簽署、公證步驟。不要把某個版本的 Xcode 行為當成永久規則;工具更新後要重新核對官方文件。
提醒:刪除憑證、重簽正式產物或更換認證方式前,先保留可回退的舊產物與發佈紀錄。這些動作可能讓你失去重現原始失敗的條件,也可能使團隊其他成員無法使用原有簽署資產。
Accepted 與可交付:兩個不同的里程碑
第四個里程碑:完成 staple,再做使用者側驗收
notarytool 顯示 Accepted 後,還需要執行 stapler 嗎?
需要。Accepted 表示公證服務接受了該提交,但不代表你已對待交付檔案完成票據封存,也不代表下載、解壓縮、掛載或安裝流程已被驗證。對同一個最終分發檔案執行 staple,再使用票據驗證工具確認結果;如果檔案在 Accepted 後又被改動,應回到封裝與提交階段重新處理。
接著做三組驗收:
- 對下載後的真實 ZIP、DMG 或 PKG 執行 Gatekeeper 評估;
- 在沒有你開發環境快取的另一台 Mac 上安裝或啟動;
- 暫時使用離線或受限網路條件,確認流程不只是依賴線上票據。
測試時要核對檔名、摘要與版本資訊,避免測到工作目錄裡另一份「看起來相同」的檔案。若 DMG 能掛載但 App 啟動被攔截,問題仍屬使用者側驗收未完成,而不是可以直接以 Accepted 結案。
遠端 Mac 自動化:把一次修復變成可追蹤流程
第五個里程碑:固定工具鏈與可回復的發佈任務
本機公證成功,但遠端 Mac 自動公證失敗,應先查什麼?
先比對兩邊是否使用相同的 Xcode 工具鏈、DEVELOPER_DIR、簽署憑據來源、工作目錄與最終產物。圖形會話、SSH 會話與 CI 任務可能使用不同的環境變數或 Keychain 解鎖狀態;如果提交的檔案摘要不同,你其實不是在比較同一次公證。
在遠端 Mac 上把以下項目寫入任務紀錄:
- 明確固定
xcode-select或DEVELOPER_DIR; - 將憑據來源限制在指定的安全範圍,避免把秘密放入命令列輸出;
- 將產物摘要、提交 ID、日誌與版本號互相關聯;
- 為狀態查詢、等待、逾時與重試設定人工停止條件;
- 讓任務在斷線或主機重啟後能從「已產生產物」或「已取得提交 ID」的節點恢復;
- 以非正式版本先完成一次完整的 staple、下載與 Gatekeeper 驗收。
若你目前的開發電腦會睡眠、多人共用簽署環境,或無法長期保留 Developer ID 私鑰、Xcode 工具鏈與公證日誌,將流程放到權限隔離的常駐遠端 Mac,通常比臨時在不同電腦重做更容易追蹤。你可以先查看 VMSPIN 的遠端 Mac 方案與方案價格,只把正式版本前的非正式產物拿來驗證,不要在尚未驗收的環境直接切換正式發佈。
對獨立開發者而言,本機方案的缺點通常不是「不能簽名」,而是私人金鑰容易跟著使用者帳號、睡眠狀態與臨時工具鏈漂移;遠端流程則可能因會話中斷、Xcode 路徑不同或日誌沒有集中保存而失敗。若你已完成本機故障定位,卻需要一台能長時間保留工具鏈、權限與紀錄的主機,租用 VMSPIN 的遠端 Mac 會比反覆在個人電腦上重建發佈環境更合適;先用測試版本跑完公證、票據與 Gatekeeper 驗收,再決定是否把正式自動化遷移過去。若只是偶爾發佈、需要實體介面,或已有穩定且可備份的本機 Mac,則不必為了單次公證失敗而租用長期環境。
本週建議你按照這條順序執行:保留失敗現場,取得 notarytool 日誌;以實際 ZIP、DMG 或 PKG 檢查簽署與嵌套元件;由內向外重新封裝並提交;最後在獨立 Mac 上完成 staple 與 Gatekeeper 驗收。這樣才能把「公證服務接受」與「使用者真的能安裝」分成兩個可核對的結果。