2026年版 リモート Mac ヘッドレス公証パイプライン:notarytool の App Store Connect API とキーチェーン Profile の比較+stapler と notarytool log の SSH トラブルシュート意思決定表と FAQ
公証を「手元の GUI マシンだけで通る」から「監査可能なパイプライン」へ。まず notarytool の認証モデルを選び、切り分けは stapler と notarytool log に分ける。SSH 駆動のリモート Mac/CI Runner 向けに、比較表と症状ファーストの意思決定表を runbook に貼れる形で整理する。
1. 2026 年に notarytool を既定にする理由
Apple は従来の altool から notarytool(Xcode/Command Line Tools 同梱)へ移行済み。ヘッドレスなリモート Mac では、提出・履歴・詳細ログを 1 本の CLI で扱えることが利点で、アップロード経路のもろさやブラウザ操作に頼らず、スクリプトと runbook に落とし込みやすい。
心の中の手順は 3 段に固定すると運用しやすい:成果物に署名 → notarytool submit(提出 ID を記録)→ 成功までポーリング →(任意)stapler staple でチケットをディスク上に埋め込む。資格情報の置き場所が、このループが SSH 下で安定するかを決める。
2. 二つの認証経路:App Store Connect API キーとキーチェーン Profile
2.1 App Store Connect API(Issuer ID + Key ID + .p8)
App Store Connect → ユーザとアクセス → キー で API キーを作成し、.p8 をダウンロード(一度きり)。notarytool は --key、--key-id、--issuer で利用する。典型的な利点は次のとおり。
- 非対話:Apple ID パスワードや SMS/端末 2FA が不要で CI に向く。
- ローテーションと失効:キー単位のライフサイクルが明確で、漏えい時の爆発半径も小さい。
- 権限のスコープ:ロール境界が分かりやすく、監査に載せやすい。
運用上は .p8 を権限の厳しいパス(モード 600)に置くか、シークレットマネージャから注入し、Git にコミットしない。複数プロバイダとシークレットを自動化で束ねるときの層分けの考え方は、
Flutter iOS ビルドには Mac が必須?レンタルの方がお得(2026)
で扱う iOS 配布パイプラインとも地続きで、資格情報をコードから分離し SSH 上で検証するパターンとして参照できる。
2.2 キーチェーン Profile(notarytool store-credentials)
notarytool store-credentials は Apple ID または API 資格情報をログインキーチェーンに名前付き Profile として保存し、--keychain-profile "名前" で参照する。一度だけ対話セットアップし、同一ユーザセッションで使い回す構成に合う。
リモートヘッドレスでは、SSH の非ログインシェル、デーモン、並列ジョブがキーチェーンのロック状態や「どのユーザのログインキーチェーンか」を食い違わせ、「手元では成功、パイプラインでは不安定」につながりやすい。並列度と初期化の設計をまとめる視点は 2026年におけるMacアーキテクチャリソースの高並列初期化と自動デリバリの実現方法 と通じる。ゼロトラストで管理経路を出す場合は、ビルドシークレットを同じ露出面に載せない、という分離も有効だ。
3. 意思決定表(runbook にそのまま貼れる)
| 観点 | ASC API キー(.p8) | キーチェーン Profile |
|---|---|---|
| ヘッドレス/CI 適合 | 高:フラグまたは環境変数注入 | 中:アンロック+ユーザ文脈に依存 |
| 資格情報ローテーション | キー差し替え、パイプライン変数更新 | キーチェーン項目更新または Profile 再作成 |
| 並列ジョブ | ジョブ間で .p8 を共有(権限/ロックに注意) | ACL とセッション競合が起きやすい |
| コンプライアンス/監査 | Key ID と発行経路が明示的 | ホストとユーザの台帳が増えがち |
| 典型用途 | 共有 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 特定も可) |
根本原因はサーバ側スキャン結果にあり、stapler では見えない |
| ステータスは Accepted だが配布物が「公証されていない」 | 出荷物に stapler staple → stapler validate |
DMG/ZIP/ネストした app にチケットが無い、または未 staple のコピーを出している |
| 手早いゲート:「このファイルにチケットはあるか」 | stapler validate や spctl 系チェック |
API 往復なし、プリフライトに向く |
| 同一スクリプトが「たまに緑、たまに赤」 | 提出 ID を固定しログを diff → キーチェーン、並列、プロキシを疑う | フレークは資格情報文脈やアップロード整合性に多く、ログで再現性のある原因と環境ドリフトを切り分ける |
5. FAQ:ヘッドレス公証の落とし穴
Q1:CI がキーチェーンにアクセスできない/Profile が無い?
まず疑う:ジョブの実行ユーザが store-credentials したユーザと違う、またはログインキーチェーンがロックされている。次:ASC API の三つ組へ切り替える。Profile 継続なら launchd で明示アンロックし、署名と公証のステージを直列化する。
Q2:Accepted なのに stapler がエラー?
まず疑う:staple 対象が誤り(例:DMG を再梱包する前に app だけ staple した等)、読み取り専用パスやサンドボックス制限。次:Apple がサポートする stapler 対象形式に揃え、検証したパスとパイプラインが触るパスを一致させる。
Q3:ログに署名、Hardened Runtime、エンタイトルメントの指摘?
まず疑う:公証前署名と宣言エンタイトルメントの不一致(ネストしたヘルパー含む)。次:同一のリモート Mac 上で再現し、codesign -dvvv とエンタイトルメントを比較して修正し再提出。「ローカルでは直したが CI は古いスクリプト」のすれ違いを避ける。
Q4:企業プロキシでアップロードが壊れる?
まず疑う:プロキシが Apple のアップロード先をブロックまたは MITM している。次:ビルダーに allowlist またはバイパスを付与。SSH から小さな提出で TLS を先に検証してから大きな成果物を流す。
なぜこのパイプラインを Mac mini で回すのか
notarytool、codesign、stapler は macOS ツールチェーンの第一級市民であり、Apple Silicon の Mac mini 上では公証が想定するのと同じランタイムとセキュリティスタックをそのまま使える。ユニファイドメモリとアイドル時おおよそ一桁ワット級の消費電力は、常時接続のリモートビルダーにも向く。静音で熱負荷も抑えやすく、キューが空いていても付けっぱなしにしやすい。
チーム運用では Gatekeeper、SIP、FileVault、ファイル権限モデルにより「どのホストの 誰が 提出できるか」を説明しやすく、汎用 VM では作りにくいコンプライアンスの物語になる。アーカイブ→署名→公証を端到端で組むなら、専用 Mac mini M4 はコスト対効果の高い実機アンカーになりやすい。今すぐリモート Mac を確保し、この runbook を安定して緑に保つ土台にしてほしい。