macOS アプリをリリースしようとして、コード署名と Notarization の壁にぶつかった経験はありませんか。
Xcode でビルドまではスムーズに進んでいたのに、いざ配布用の .dmg や .zip を作ろうとしたとたんに xcrun notarytool のエラーメッセージの海に飲み込まれてしまう。しかも毎回少しずつエラーの内容が違って、どれが根本原因なのかわからない——私もこれで何時間も溶かしてきました。
Antigravity はこの問題に対して驚くほど実用的に機能します。エラーログをそのまま貼り付けるだけで「この証明書設定が間違っています」「entitlements.plist にこのキーが不足しています」と具体的に指摘してくれるからです。今回は、コード署名から Notarization まで一連のフローを Antigravity と GitHub Actions で自動化する方法を紹介します。
macOS コード署名の基礎と、なぜ複雑に感じるのか
macOS の配布には大きく2つの証明書が存在します。
Mac App Store 用 (3rd Party Mac Developer Application):App Store Connect 経由で配布するアプリ用。Apple が配布を管理します。
直接配布用 (Developer ID Application):自社サイトや GitHub から直接配布するアプリ用。こちらは Notarization が必須です。
個人開発でよく使われるのは「直接配布」のほうです。Developer ID Application 証明書を取得し、アプリに署名し、Apple サーバーに送信して Notarization を受ける。最後に受け取った Ticket をアプリに埋め込む(Staple)。この4つのステップを毎回手動でやるのが煩雑で、しかもどこかでミスをするとユーザーの Mac で「悪質なソフトウェア」ダイアログが表示されてしまいます。
失敗した経験から言うと、最も多い落とし穴は「証明書はあるのに entitlements が不完全」というパターンです。特に Hardened Runtime を有効にするとデフォルトで多くの機能がブロックされるため、例えばカメラ・マイク・ネットワークへのアクセス権を一つひとつ entitlements.plist に追加する必要があります。これを Antigravity に任せるとアプリの機能要件を伝えるだけで雛形ファイルを生成してくれます。
Step 1:証明書とキーチェーンの設定を Antigravity に確認させる
まずは手元の環境チェックから始めます。ターミナルで以下を実行してください。
# 署名に使える Developer ID 証明書を一覧表示
security find-identity -v -p codesigning | grep "Developer ID"この出力を Antigravity のチャットに貼り付けて「Developer ID Application 証明書があるか確認して」と聞くのが最初のステップです。証明書が見つかれば Antigravity がそのまま次の署名コマンドを生成してくれます。
証明書が見つからない場合は、以下の手順で設定します。
# Apple Developer ポータルからダウンロードした .p12 ファイルをインポート
security import ~/Downloads/DeveloperIDApplication.p12 \
-k ~/Library/Keychains/login.keychain-db \
-P "YOUR_P12_PASSWORD" \
-T /usr/bin/codesignここで Antigravity に「このコマンドの -T オプションの意味と、複数の証明書がある場合の選択方法」を聞くと、コード署名の仕組みをその場で学びながら作業を進められます。
Step 2:Antigravity でコード署名スクリプトを生成する
環境が整ったら、Antigravity に署名スクリプトの生成を依頼します。私がよく使うプロンプトはこのような形です。
macOS の .app バンドルに Developer ID Application 証明書で署名して、
Notarization まで一気通貫で行うシェルスクリプトを作ってください。
アプリはネットワーク接続とカメラを使います。
証明書のハッシュは [証明書の SHA-1] です。
Antigravity が生成するスクリプトはおおむね以下の構造になります。
#!/bin/bash
set -euo pipefail
APP_PATH="MyApp.app"
ENTITLEMENTS="entitlements.plist"
BUNDLE_ID="com.example.myapp"
TEAM_ID="XXXXXXXXXX"
# 証明書名は security find-identity の出力から取得
CERT_NAME="Developer ID Application: Your Name (XXXXXXXXXX)"
# Step 1: Deep sign(フレームワーク・プラグインから順番に署名)
find "${APP_PATH}/Contents" \( -name "*.dylib" -o -name "*.framework" \) \
-exec codesign --force --sign "${CERT_NAME}" \
--options runtime --entitlements "${ENTITLEMENTS}" {} \;
# Step 2: メインの .app に署名
codesign --force --deep --sign "${CERT_NAME}" \
--options runtime \
--entitlements "${ENTITLEMENTS}" \
"${APP_PATH}"
# Step 3: 署名の検証
codesign --verify --deep --strict "${APP_PATH}"
spctl --assess --type execute "${APP_PATH}" && echo "✅ 署名検証 OK"
# Step 4: .zip 化して Notarization 送信
ditto -c -k --keepParent "${APP_PATH}" "${APP_PATH%.app}.zip"
xcrun notarytool submit "${APP_PATH%.app}.zip" \
--apple-id "${APPLE_ID}" \
--password "${APP_SPECIFIC_PASSWORD}" \
--team-id "${TEAM_ID}" \
--wait
# Step 5: Staple(Ticket の埋め込み)
xcrun stapler staple "${APP_PATH}"
echo "🎉 Notarization 完了"このスクリプトをそのままコピーして使うのではなく、生成後に Antigravity に「--deep オプションは推奨されなくなったと聞いたが、このスクリプトで問題ないか」と確認するのがおすすめです。実は --deep フラグは Apple が非推奨化していて、フレームワークやプラグインは個別に署名するほうが安全です。Antigravity はこのような最新の best practice もきちんと把握しています。
Step 3:entitlements.plist を正確に生成する
Notarization でエラーになる最大の原因は、entitlements.plist の不備です。Hardened Runtime 有効時にアプリが実行時に使う機能を宣言しなければなりません。
Antigravity へのプロンプト例:
以下の機能を使う macOS アプリの entitlements.plist を生成してください:
- インターネット接続(クライアント)
- カメラ
- マイク
- ユーザーの「書類」フォルダへの読み書き
Hardened Runtime を有効にします。
生成される entitlements.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Hardened Runtime: インターネット接続 -->
<key>com.apple.security.network.client</key>
<true/>
<!-- カメラへのアクセス -->
<key>com.apple.security.device.camera</key>
<true/>
<!-- マイクへのアクセス -->
<key>com.apple.security.device.microphone</key>
<true/>
<!-- 書類フォルダへの読み書き -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>entitlements が不完全だと Notarization はパスしても、ユーザーの Mac でアプリを初回起動したときにクラッシュします。Antigravity にアプリの機能を正確に伝えれば、こうした見落としを防げます。
Step 4:GitHub Actions で CI 化する
手動の署名・Notarization は1回こっきりでは問題ありませんが、リリースのたびに実行するのはストレスです。GitHub Actions に組み込みましょう。
Antigravity に「上記のシェルスクリプトを GitHub Actions ワークフローに変換してください。証明書は secrets に格納します」と依頼すると、以下のような .github/workflows/release.yml を生成してくれます。
name: macOS Release Build
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: 証明書のインポート
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
run: |
# Base64 → .p12 デコード
echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode \
> /tmp/cert.p12
# 一時キーチェーン作成
security create-keychain -p "temp_password" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "temp_password" build.keychain
# 証明書インポート
security import /tmp/cert.p12 \
-k build.keychain \
-P "$P12_PASSWORD" \
-T /usr/bin/codesign
security set-key-partition-list \
-S apple-tool:,apple: \
-s -k "temp_password" build.keychain
- name: ビルド & 署名 & Notarization
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
TEAM_ID: ${{ secrets.TEAM_ID }}
run: bash ./scripts/sign_and_notarize.sh
- name: リリースアセットのアップロード
uses: actions/upload-artifact@v4
with:
name: MyApp-release
path: MyApp.appGitHub Secrets に登録すべき値の一覧と取得方法も、Antigravity に「この GitHub Actions で必要な secrets の設定方法をすべて教えてください」と聞けば一覧で説明してくれます。特に BUILD_CERTIFICATE_BASE64 の生成方法(base64 -i cert.p12 | tr -d '\n')や APP_SPECIFIC_PASSWORD の Apple ID での発行手順も含めて案内してくれるので、ドキュメントを探し回る手間が省けます。
より詳しい Xcode Cloud を使った iOS/macOS の CI/CD パイプライン構築については、Antigravity × Xcode Cloud で iOS CI/CD を自動化する も参考になります。
よくあるエラーと Antigravity を使った診断方法
エラー1:The signature for binary ... is invalid
これは --deep で署名する際に内部バイナリの順番が間違っているケースです。Antigravity にエラーメッセージを貼り付けると「このフレームワーク/バイナリを先に署名し直してください」と特定してくれます。
エラー2:The binary is not signed with a valid Developer ID certificate
証明書がキーチェーンにあるのに認識されない場合は、security set-key-partition-list の設定不足が原因のことが多いです。Antigravity に CI 環境のログを渡すと、キーチェーンの partition list 設定コマンドを補完してくれます。
エラー3:Notarization が invalid で返ってくる
xcrun notarytool log <submission-id> でログを取得して Antigravity に貼り付けましょう。JSON 形式のログを解析して、問題のある entitlement キーや署名済みバイナリを特定してくれます。私が経験した中では「外部ライブラリが署名されていない」というケースが最多でした。
エラー4:Staple 後もユーザーの環境でガテーキーパー警告が出る
spctl -a -t open --context context:primary-signature -v MyApp.app でオフライン検証を確認してください。これを Antigravity のターミナルで実行して結果を共有すると、Staple が正しく適用されているかどうかをすぐに判断できます。
macOS のコード署名と Notarization は、一度正しく自動化してしまえばその後はほぼ意識しなくて済みます。Antigravity を使うと「エラーメッセージを貼り付けて診断してもらう」→「修正案を適用する」→「再実行」のサイクルが明確に速くなります。
まずは手元のアプリで security find-identity -v -p codesigning を実行して、今の証明書状況を Antigravity に見せるところから始めてみてください。macOS アプリのメニューバーアプリ開発と組み合わせた開発フローについては Antigravity で macOS メニューバーアプリを作る完全ガイド も参考にどうぞ。