Developer ID で自分配布するとはどういうことか
macOS アプリをユーザーに届ける方法は大きく 2 つあります。一つは Mac App Store (MAS) を通じる方法、もう一つは開発者が自ら作った .dmg (または .app) ファイルをウェブサイトや GitHub などからダウンロードさせる 直接配布 (direct distribution) です。
直接配布には明確なメリットがあります。App Store の審査を待つ必要がなく、決済手数料もかかりません。また、好きなタイミング・好きな方法でアップデートをリリースできます。その代わり、App Store が代わりに処理していた作業 — コード署名、公証 (notarization)、自動アップデート — を開発者自身が用意しなければなりません。
これらを用意しないと、macOS のセキュリティ機能である Gatekeeper がアプリの起動をブロックします。ユーザーがアプリを初めて開こうとしたとき、「確認できない開発者からのアプリのため開けません」といった警告が表示され、ほとんどのユーザーはそこでインストールを諦めてしまいます。正しく配布されたアプリのようにダブルクリックだけで開くようにするには、アプリを Developer ID 証明書で署名し、Apple から公証を受ける必要があります。
このシリーズでは、その事前設定のプロセスを扱います。一つ良いニュースがあります。ここで行う設定のほとんどは 一度だけ行えばすべてのリリースで再利用できます。
このシリーズで作るもの
3 編にわたって、以下を整えます。
- (1 編、この記事) Developer ID Application 証明書 + 公証用の認証情報
- (2 編) Sparkle 自動アップデートのための EdDSA 署名キー
- (3 編) アップデートフィードをホストする公開リポジトリ + ビルド設定の完了
シリーズを終えた時点で、次のものが揃っているはずです。今は一覧を眺めるだけにして、各編で一つずつ揃えていきましょう。
- macOS キーチェーン (Keychain) に保存された
Developer ID Application証明書 - キーチェーンに保存された公証用の認証情報プロファイル
- Sparkle のアップデート署名用 EdDSA キーペア (公開鍵 + 秘密鍵)
- 安全な場所に秘密鍵のバックアップ
- アップデートフィード (appcast) をホストする 公開 GitHub リポジトリ + GitHub Pages
- ビルド設定ファイル (
ExportOptions.plist) とアプリ側の設定
サンプルアプリ — FocusTimer
このシリーズでは、架空の macOS アプリ FocusTimer (集中時間を管理するシンプルなタイマーアプリ) を例として使います。コマンドやパスに登場する FocusTimer、バンドル識別子 com.example.FocusTimer、ドメイン example.com、証明書名、Team ID などはすべてサンプル値です。実際に試す際は、ご自身のアプリ名とアカウント情報に置き換えてください。
この記事は Xcode 26 と Sparkle 2.x (自動アップデートフレームワーク、2 編で登場) を基準に書いています。Apple は画面構成やメニューの位置を頻繁に変更するため、ボタン名が多少異なっていても、全体の流れは同じと考えて構いません。
事前準備 — コマンドラインツール
まず、ビルド・リリース自動化に必要なコマンドラインツールを 2 つインストールします。macOS のパッケージマネージャー Homebrew がインストール済みであることを前提とします。
brew install gh create-dmg
gh— GitHub 公式 CLI。後ほど GitHub Release を作成する際に使います。create-dmg— 配布用.dmgディスクイメージを作成するツール。ユーザーがアプリをApplicationsフォルダにドラッグするよう案内する画面も生成してくれます。
今すぐ使うわけではありませんが、リリース自動化スクリプトがこれらのツールの存在を最初に確認し、見つからなければ即座に停止するよう設計されることが多いため、あらかじめインストールしておきます。
ステップ 1 — Apple Developer Program の確認
Developer ID 証明書を発行し、アプリを公証するには Apple Developer Program のメンバーシップが必要です。個人アカウントの場合、年間 $99 の有料プログラムです。
すでに加入済みであれば、有効な状態であるかどうかだけ確認すれば大丈夫です。
- developer.apple.com/account にアクセス
- Membership details セクションで、状態が Active であることを確認
- 同じ画面で、ご自身の Team ID (例では
ABCDE12345) をメモしておきます。後のステップで繰り返し使います。
まだ加入していない場合、メンバーシップの承認には通常 1 日ほどかかります。承認前は証明書を発行できないため、最初に処理しておくことをお勧めします。
ステップ 2 — Developer ID Application 証明書の発行
Developer ID Application 証明書は、配布する .app と .dmg に署名する際に使う証明書です。macOS Gatekeeper は、この証明書で署名されたアプリを「既知の開発者が作ったアプリ」として認識します。
Apple には
.pkgインストーラーパッケージに署名するための Developer ID Installer 証明書も別途あります。このシリーズは.dmgで配布するため、Application 証明書のみ扱います。
発行手順
最も簡単な方法は Xcode を使うことです。
- Xcode を起動 → メニュー Xcode → Settings… (
⌘,) - Accounts タブを選択 → 左側のリストでご自身の Apple ID をクリック
- 右下の Manage Certificates… ボタンをクリック
- 新しく開いたウィンドウの左下にある
+ボタンをクリック - メニューから Developer ID Application を選択
- 1〜2 秒後、リストに新しい証明書が追加されたら Done をクリック
こうして発行された証明書は、自動的に macOS キーチェーン (Keychain) に保存されます。証明書とそれに対応する秘密鍵がペアとして保存され、この秘密鍵があってこそ署名が可能になります。
発行の確認
ターミナルで次のコマンドを実行し、証明書が正しくインストールされているか確認します。
security find-identity -v -p codesigning | grep "Developer ID Application"
次のように 1 行が表示されれば成功です。
1) A1B2C3D4E5F6... "Developer ID Application: Gildong Hong (ABCDE12345)"
引用符内の文字列が証明書の正式名称です。Gildong Hong は Apple アカウントに登録された名前、括弧内の ABCDE12345 はステップ 1 でメモした Team ID です。この名前は後でコード署名を自動化する際にそのまま使われるので、もう一度確認しておいてください。
証明書の更新
Developer ID 証明書の有効期間は 5 年です。期限が近づくと、Xcode の Manage Certificates リストで Expired と表示されます。その際は、上記と全く同じ手順で新しい証明書を発行すれば大丈夫です。
良いニュースは、既存の証明書で署名・配布済みのアプリが、期限切れ直後に無効化されるわけではないという点です。今後新たに作成するビルドだけを新しい証明書で署名すれば大丈夫です。ですから、期限切れを過度に心配する必要はありません。
ステップ 3 — 公証のためのアプリ専用パスワードの登録
公証 (notarization) とは
公証は、配布前にアプリを Apple のサーバーにアップロードしてマルウェアスキャンを受ける手続きです。スキャンを通過すると Apple が「公証チケット」を発行し、このチケットがアプリに付いていることで Gatekeeper が警告なしにアプリを開けるようになります。署名が「誰が作ったか」を証明するとすれば、公証は「Apple が一度検査した」を証明する別の手続きです。
公証の提出には Apple の notarytool コマンドを使いますが、提出のたびに Apple ID のパスワードを求められます。毎回入力しなくて済むよう、アプリ専用パスワード (App-Specific Password) を作成してキーチェーンにあらかじめ保存しておきます。
3-1. アプリ専用パスワードの発行
アプリ専用パスワードは、メインの Apple ID パスワードの代わりに特定の用途だけに使う 16 桁のパスワードです。
- appleid.apple.com にアクセス → Apple Developer Program に加入している Apple ID でログイン (例では
[email protected]) - サインインとセキュリティ (Sign-In and Security) → アプリ専用パスワード (App-Specific Passwords) を選択
+ボタンをクリック → パスワードの名前を入力 (例:focustimer-notarize)- 作成 (Create) をクリック → Apple ID のパスワードをもう一度入力
abcd-efgh-ijkl-mnop形式の 16 桁のパスワードが画面に表示されます。
この画面を閉じると、パスワードを再確認することができません。 次のステップに進む前に、パスワードマネージャーなどに一時的にコピーしておいてください。
3-2. notarytool プロファイルに保存
発行されたパスワードをキーチェーンのプロファイルとして保存します。以下のコマンドの --password の値を、今取得した実際のパスワードに置き換えて実行してください。
xcrun notarytool store-credentials "focustimer-notarize" \
--apple-id "[email protected]" \
--team-id "ABCDE12345" \
--password "abcd-efgh-ijkl-mnop"
- 最初の引数
"focustimer-notarize"— このプロファイルに付ける名前。今後、公証の際にこの名前で認証情報を呼び出します。 --apple-id— Apple Developer Program アカウントのメールアドレス--team-id— ステップ 1 の Team ID--password— 3-1 で発行したアプリ専用パスワード
次の出力が表示されれば成功です。
Credentials saved to Keychain.
これでキーチェーンに認証情報が保存されたので、アプリ専用パスワードの原本はもう不要です。(ただし、他のコンピューターでもビルドする予定がある場合は、パスワードマネージャーに保管しておくと便利です。)
3-3. 確認
保存したプロファイルが実際に動作するかどうか確認します。
xcrun notarytool history --keychain-profile "focustimer-notarize"
Successfully received submission history. というメッセージが表示されれば正常です。その下の提出履歴は空の場合もあり (まだ公証を行っていないので正常)、以前の記録がある場合もあります。
重要な落とし穴 — Apple ID と GitHub アカウントは別物
直接配布を初めて設定するときに最もよく詰まる箇所です。
- Apple Developer Program アカウント — 証明書の発行、公証に使用 (例:
[email protected]) - GitHub アカウント — 3 編でアップデートファイルをホストする際に使用 (例:
[email protected])
この 2 つが異なるメールアドレスである場合がほとんどです。特に、notarytool store-credentials の --apple-id には必ず Apple Developer アカウントのメールアドレスを入力してください。GitHub アカウントのメールアドレスを入力すると認証に失敗しますが、エラーメッセージがわかりにくいため原因を特定しにくいです。
2 つのアカウントのメールアドレスが混同しやすい場合は、どちらが Apple 用でどちらが GitHub 用かをメモしておくことをお勧めします。この区別はシリーズ全体を通じて繰り返し登場します。
1 編まとめ
ここまで進んだ方は、以下が揃っているはずです。
- ✅ リリース自動化用コマンドラインツール (
gh、create-dmg) - ✅ 有効な Apple Developer Program メンバーシップ
- ✅ キーチェーンに保存された Developer ID Application 証明書
- ✅ キーチェーンに保存された公証用の認証情報プロファイル (
focustimer-notarize)
これでアプリを署名して公証する準備が整いました。ただし、ユーザーに一度届けて終わりというアプリはほとんどありません。バグを修正したり機能を追加した新しいバージョンを継続してリリースし続ける必要があります。App Store であれば自動アップデートが処理されますが、直接配布ではこれも自分で用意しなければなりません。
次の編では、macOS アプリの事実上の標準的な自動アップデートフレームワークである Sparkle のための EdDSA 署名キーを作成します。証明書とはまた別の、アップデートファイル専用の検証の仕組みです。