Apple 的技術說明指出,altool2023 年 11 月 1 日起不再被公證服務接受,現行命令列流程應改用 notarytoolApple 的遷移說明 因此,遇到 macOS App 公證失敗時,不要反覆提交同一個 ZIP、DMG 或 PKG;先看 notarytool 狀態與日誌,判斷是認證、簽署、封裝還是票據階段出錯,再修復最終分發產物。即使結果顯示 Accepted,仍要完成 staple、Gatekeeper 檢查與獨立環境安裝驗收。

這篇適合使用 Developer ID 在 Mac App Store 之外發佈 App 的獨立開發者,也適合在遠端 Mac 或 CI 維護 notarytoolstapler 自動化的人員。若你的產品含有外掛、輔助工具、登入項目、DMG 或 PKG 等嵌套元件,下面的時間線尤其重要。

先保留現場,再決定是否重做產物

第一個里程碑:把失敗階段固定下來

先不要刪除原始產物、憑證、金鑰或工作目錄。把以下內容存放在同一個具備存取控制的發佈紀錄中:

  • notarytool submit 的完整輸出;
  • 提交 ID、時間、使用的 Team ID 與已脫敏的 Bundle ID;
  • 最終提交檔案的名稱、路徑與摘要;
  • 執行時使用的 Xcode 路徑、xcode-selectDEVELOPER_DIR 設定;
  • 目前處於 Build、Archive、Export、Sign、Package、Submit、Accepted、Staple 還是 Gatekeeper 驗收階段。

Apple 的公證工作流程文件把提交、查詢狀態、取得日誌與票據處理視為不同步驟。這代表「指令成功結束」並不等於使用者下載的檔案已經能正常啟動。

notarytool 顯示 Invalid 後,如何找出具體錯誤?
使用提交 ID 查詢該次提交的資訊,再取得對應日誌;不要只依終端機最後一行文字猜測原因。日誌中若列出具體檔案路徑,先處理第一個有效錯誤,再重新檢查它所屬的嵌套層級。若只有一段泛化訊息,保留提交 ID 與原始輸出,並對照 Apple 的常見公證問題排解文件

失敗狀態與下一個動作

觀察到的階段 你應保留的證據 下一個動作
認證失敗或尚未完成提交 脫敏後的認證方式、命令輸出、提交檔案摘要 先確認憑據來源與工具鏈,再決定是否重新提交
持續處理中 提交 ID、提交時間、狀態查詢結果 不要平行提交同一產物;必要時查看官方服務狀態
Invalid 公證日誌、具體路徑與錯誤描述 修復最終產物,重新簽署與封裝
Acceptedstaple 失敗 Accepted 資訊、stapler 輸出 確認操作的是同一個最終檔案,再做票據驗證
本機成功、使用者仍被攔截 Gatekeeper 輸出、下載後檔案摘要、安裝環境 在沒有開發快取的 Mac 上驗證真實下載檔

如果提交長時間停留在處理中,不要把論壇個案中的等待時間當成固定規則;先核對Apple Developer System Status與官方文件,再判斷是否是服務端問題。

最終產物與原始 App:先檢查哪一個?

第二個里程碑:以 ZIP、DMG 或 PKG 為檢查對象

公證檢查的對象是你實際提交的分發產物,不是 Xcode 專案中尚未封裝的原始 App。你可能在本機檢查過 .app,但在 Export、打包 DMG 或建立 PKG 時又加入了另一個執行檔、外掛或安裝腳本,最後送出的內容已經不同。

先對最終產物做以下核對:

  1. App 主程式是否使用適合直接分發的 Developer ID 簽名;
  2. 是否啟用 Hardened Runtime,並使用安全時間戳;
  3. entitlements 是否只保留實際需要的項目;
  4. App 內的 Framework、Plug-in、XPC 服務、登入項目、輔助工具與其他可執行檔是否各自完成簽署;
  5. 外層封裝是否仍包含你檢查過的同一個 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、遺漏的元件或不一致的簽署順序。

你可以把流程拆成明確的里程碑:

  1. 從乾淨的 Build 或 Archive 產生候選 App;
  2. 列出所有嵌套程式碼與其簽名狀態;
  3. 修復最內層元件,再簽署外層 App;
  4. 重新建立 ZIP、DMG 或 PKG,不沿用舊容器;
  5. 對新產物重新計算摘要並提交;
  6. 將新的提交 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-selectDEVELOPER_DIR
  • 將憑據來源限制在指定的安全範圍,避免把秘密放入命令列輸出;
  • 將產物摘要、提交 ID、日誌與版本號互相關聯;
  • 為狀態查詢、等待、逾時與重試設定人工停止條件;
  • 讓任務在斷線或主機重啟後能從「已產生產物」或「已取得提交 ID」的節點恢復;
  • 以非正式版本先完成一次完整的 staple、下載與 Gatekeeper 驗收。

若你目前的開發電腦會睡眠、多人共用簽署環境,或無法長期保留 Developer ID 私鑰、Xcode 工具鏈與公證日誌,將流程放到權限隔離的常駐遠端 Mac,通常比臨時在不同電腦重做更容易追蹤。你可以先查看 VMSPIN 的遠端 Mac 方案方案價格,只把正式版本前的非正式產物拿來驗證,不要在尚未驗收的環境直接切換正式發佈。

對獨立開發者而言,本機方案的缺點通常不是「不能簽名」,而是私人金鑰容易跟著使用者帳號、睡眠狀態與臨時工具鏈漂移;遠端流程則可能因會話中斷、Xcode 路徑不同或日誌沒有集中保存而失敗。若你已完成本機故障定位,卻需要一台能長時間保留工具鏈、權限與紀錄的主機,租用 VMSPIN 的遠端 Mac 會比反覆在個人電腦上重建發佈環境更合適;先用測試版本跑完公證、票據與 Gatekeeper 驗收,再決定是否把正式自動化遷移過去。若只是偶爾發佈、需要實體介面,或已有穩定且可備份的本機 Mac,則不必為了單次公證失敗而租用長期環境。

本週建議你按照這條順序執行:保留失敗現場,取得 notarytool 日誌;以實際 ZIP、DMG 或 PKG 檢查簽署與嵌套元件;由內向外重新封裝並提交;最後在獨立 Mac 上完成 staple 與 Gatekeeper 驗收。這樣才能把「公證服務接受」與「使用者真的能安裝」分成兩個可核對的結果。