Contents
macOS 向け Tauri ビルド設定とパッケージ生成
macOS で配布する Tauri アプリは、ユニバーサル バイナリ(Intel と Apple Silicon の両方)を生成し、適切に署名・公証して初めて Gatekeeper を通過します。本セクションでは tauri.conf.json の基本設定から、x86_64 と arm64 両ターゲットを同時にビルドする方法までを解説します。
tauri.conf.json の基本設定
tauri.conf.json は macOS アプリのメタ情報を一元管理する重要なファイルです。ここで正しいバンドル ID・アプリアイコン・Entitlements への参照先を指定しておくことで、後続の署名や notarization がスムーズに進みます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "tauri": { "bundle": { "identifier": "com.acme.superapp", "icon": ["icons/app.icns"], "resources": [], "copyright": "© 2026 Acme Corp." }, "windows": [ { "title": "SuperApp", "width": 1024, "height": 768 } ] } } |
- identifier は逆ドメイン形式でユニークにする(例:
com.acme.superapp)。 - icon には macOS 用
.icnsを指定し、16 px〜512 px の各サイズが含まれることを確認。
Apple Silicon と Intel 両方を対象にしたビルドコマンド
macOS は Apple Silicon (arm64) が主流ですが、依然として Intel 搭載 Mac も多く存在します。そのため ユニバーサル アプリ を作るか、各アーキテクチャごとにバイナリを生成して配布するかを選択できます。以下は代表的なビルドパターンです。
| ビルド対象 | コマンド例 | 出力ディレクトリ |
|---|---|---|
| Intel (x86_64) | cargo tauri build --release --target x86_64-apple-darwin |
src-tauri/target/x86_64-apple-darwin/release/bundle/macos/ |
| Apple Silicon (arm64) | cargo tauri build --release --target aarch64-apple-darwin |
src-tauri/target/aarch64-apple-darwin/release/bundle/macos/ |
| ユニバーサル(両方同時) | cargo tauri build --release --targets x86_64-apple-darwin,aarch64-apple-darwin |
src-tauri/target/universal-apple-darwin/release/bundle/macos/ |
ポイント
- --targets オプションは Tauri CLI ≥ 1.5 で利用可能です。古いバージョンを使用している場合は、個別にビルドした後に lipo -create でユニバーサル実行ファイルを手作業で結合できます。
- ビルドが完了すると .app, .dmg, .zip が自動生成されるので、次章の コード署名 にすぐ進めます。
Developer ID 証明書取得と安全なコード署名
macOS 配布に必須となる「Developer ID Application」証明書は、Apple の Gatekeeper を通過させるための鍵です。本章では 証明書作成から Keychain へのインポート までを一度だけ実行すれば以降再利用できる手順にまとめました。
証明書の作成・Keychain インポート手順(共通)
以下の手順は GitHub Actions、Azure Pipelines いずれでも流用できます。Acme Corp. と SuperApp は実際の組織名・アプリ名に置き換えてください。
- Apple Developer ポータルで CSR を作成
bash
openssl req -new -newkey rsa:2048 -nodes \
-keyout acme_superapp.key -out acme_superapp.csr \
-subj "/CN=Acme Corp./OU=Development/O=Acme Corp./C=JP" - ポータルに CSR をアップロードし、
Developer ID Application証明書(.cer)を取得。 - 証明書とプライベートキーを PKCS#12 形式に変換(CI 用に Base64 エンコードしてシークレット化)
bash
openssl pkcs12 -export \
-inkey acme_superapp.key \
-in DeveloperID_Application.cer \
-out acme_superapp.p12 -passout pass:YOUR_PASSWORD
base64 < acme_superapp.p12 > acme_superapp.p12.b64 - CI ランナーでデコードし、Keychain にインポート(GitHub Actions の例は後述)。
重要:証明書ファイルは絶対にリポジトリに平文でコミットしないこと。必ず CI のシークレット機能を利用してください。
codesign と productsign の実践例
codesign は .app ディレクトリ全体、productsign は .pkg インストーラを対象とします。以下は Entitlements ファイル(次章で作成)を使用したサンプルです。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# .app のコード署名 codesign --deep --force \ --options runtime \ --entitlements ./entitlements.plist \ --sign "Developer ID Application: Acme Corp. (TEAMID)" \ target/release/bundle/macos/SuperApp.app # pkg インストーラの署名(必要な場合) productsign --sign "Developer ID Installer: Acme Corp. (TEAMID)" \ target/release/bundle/macos/SuperApp.pkg \ SuperApp-signed.pkg |
--options runtimeは Hardened Runtime を有効化し、Apple の公式ガイドでも必須とされています。- 証明書名は Team ID(例:
TEAMID)を正確に記載してください。
Entitlements の正しい設定と公式根拠
Hardened Runtime が有効なアプリでは、JIT コンパイルや外部ライブラリのロードに必要な権限(Entitlement)を明示しないと notarization に失敗します。本節では 必須 Entitlement とその公式ドキュメントへのリンクを添えて解説します。
必要最低限の entitlements.plist
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?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> <!-- WebView の JavaScript エンジンが JIT を利用できるようにする --> <key>com.apple.security.cs.allow-jit</key><true/> <!-- 外部ネイティブモジュール(例: SQLite)をロード可能にする --> <key>com.apple.security.cs.disable-library-validation</key><true/> <!-- ネットワーク通信のクライアント権限 --> <key>com.apple.security.network.client</key><true/> </dict> </plist> |
- allow‑jit:Apple の Hardened Runtime ガイド(Hardened Runtime Entitlements – allow-jit)で必須と明記。
- disable-library-validation:外部ダイナミックライブラリを使用する場合に必要です(disable‑library‑validation)。
ベストプラクティス:不要な権限は付与しない。Entitlement が増えるほど審査リスクが高まります。
Notarization(公証)プロセスとツール選択
macOS 13 Ventura 以降は高速かつシンプルな xcrun notarytool が推奨されています。従来の altool はレガシー環境向けに残っているだけです。本章では ツール比較 と、notarize → staple のフローを具体的に示します。
notarytool と altool の比較と推奨使用法
| 項目 | notarytool (macOS 13+) | altool (レガシー) |
|---|---|---|
| 認証情報管理 | JSON キーチェーンプロファイルで永続化可能 | Apple ID とパスワードを毎回指定 |
| 出力形式 | json / plist(機械可読) |
プレーンテキスト(人間向け) |
| CI での利用容易性 | --wait オプションで自動待機、ステータス取得が簡単 |
手作業で UUID を保存し別コマンドで確認 |
| 推奨対象 | 新規プロジェクト・macOS Ventura 以降 | macOS 12 以下の古いビルドサーバ |
結論:新規プロジェクトは必ず notarytool を採用し、レガシー環境が必要な場合にのみ altool にフォールバックしてください。
notarize & staple 実装フロー(共通)
- 認証情報をキーチェーンプロファイルへ保存(一度だけ実行)
bash
xcrun notarytool store-credentials "my-notary" \
--apple-id "$APPLE_ID" \
--team-id "$TEAM_ID" \
--password "@keychain:AC_PASSWORD" - パッケージ(DMG/ZIP)を送信し、完了まで待機
bash
xcrun notarytool submit ./SuperApp.dmg \
--keychain-profile "my-notary" \
--wait \
--output-format json > notarize_result.json - staple(公証チケットの埋め込み)
bash
xcrun stapler staple ./SuperApp.dmg
# 検証
xcrun stapler validate ./SuperApp.dmg - エラーログ取得(失敗時)
bash
LOG_URL=$(jq -r .logFileURL notarize_result.json)
curl -O "$LOG_URL"
CI/CD パイプラインでの自動化(GitHub Actions・Azure Pipelines 共通)
手作業で行うと証明書漏洩やステップ抜けが起きやすくなります。ここでは シークレット管理 を中心に、両主要 CI プラットフォーム向けのワークフロー例を示します。
証明書とシークレットの安全な取り扱い
| 項目 | 推奨方法 |
|---|---|
証明書ファイル (.p12) |
Base64 エンコードして GitHub Secrets / Azure Variable Group に保存 |
| パスフレーズ・Apple ID の App‑Specific Password | 別々のシークレットに分割し、環境変数で注入 |
| 一時キーチェーン | ビルド後は必ず security delete-keychain で削除 |
| ログ出力 | 証明書情報を含むコマンドは set -x を外すか mask オプションで隠蔽 |
ポイント:CI ランナー上に残る証明書はビルド完了後に必ず削除し、ランナーの再利用時に情報が流出しないようにします。
GitHub Actions ワークフロー例(Apple Silicon 対応)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
name: Build & Notarize macOS (Universal) on: push: tags: - 'v*' # バージョンタグ時のみ実行 jobs: build-notarize: runs-on: macos-latest env: APP_NAME: SuperApp BUNDLE_ID: com.acme.superapp steps: - uses: actions/checkout@v4 # Rust と Tauri CLI のセットアップ(Universal 対応) - name: Setup toolchain uses: dtolnay/rust-toolchain@stable with: targets: x86_64-apple-darwin,aarch64-apple-darwin - name: Install Tauri CLI run: cargo install tauri-cli # 証明書の復号化とキーチェーン作成 - name: Import Developer ID certificate env: CERT_B64: ${{ secrets.DEV_ID_CERT_B64 }} CERT_PASS: ${{ secrets.DEV_ID_CERT_PASS }} run: | echo "$CERT_B64" | base64 --decode > dev_id.p12 security create-keychain -p ghactions build.keychain security import dev_id.p12 -k ~/Library/Keychains/build.keychain \ -P "$CERT_PASS" -T /usr/bin/codesign security list-keychains -s ~/Library/Keychains/build.keychain security set-key-partition-list -S apple-tool:,apple: -s -k ghactions build.keychain # ユニバーサルビルド - name: Build universal binary run: | cargo tauri build --release \ --targets x86_64-apple-darwin,aarch64-apple-darwin # アプリ署名(Entitlements はリポジトリに含めておく) - name: Sign .app bundle run: | codesign --deep --force \ --options runtime \ --entitlements ./entitlements.plist \ --sign "Developer ID Application: Acme Corp. (${{ secrets.TEAM_ID }})" \ target/release/bundle/macos/${APP_NAME}.app # notarize & staple - name: Notarize DMG and staple env: NOTARY_PROFILE: my-notary APPLE_ID: ${{ secrets.APPLE_ID }} TEAM_ID: ${{ secrets.TEAM_ID }} AC_PASSWORD: ${{ secrets.AC_PASSWORD }} run: | xcrun notarytool store-credentials "$NOTARY_PROFILE" \ --apple-id "$APPLE_ID" \ --team-id "$TEAM_ID" \ --password "@keychain:$AC_PASSWORD" xcrun notarytool submit target/release/bundle/macos/${APP_NAME}.dmg \ --keychain-profile "$NOTARY_PROFILE" --wait xcrun stapler staple target/release/bundle/macos/${APP_NAME}.dmg - name: Upload notarized artifact uses: actions/upload-artifact@v4 with: name: ${{ env.APP_NAME }}-macos-universal path: target/release/bundle/macos/*.dmg |
Azure Pipelines の設定例(共通ロジック)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
trigger: tags: include: - v* pool: vmImage: 'macos-latest' variables: APP_NAME: SuperApp BUNDLE_ID: com.acme.superapp steps: - checkout: self - task: UseRust@0 inputs: rustVersion: stable targets: x86_64-apple-darwin,aarch64-apple-darwin - script: cargo install tauri-cli displayName: Install Tauri CLI # 証明書のデコードとキーチェーン登録(GitHub と同様) - script: | echo "$(DEV_ID_CERT_B64)" | base64 --decode > dev_id.p12 security create-keychain -p $(KEYCHAIN_PASS) build.keychain security import dev_id.p12 -k ~/Library/Keychains/build.keychain \ -P "$(DEV_ID_CERT_PASS)" -T /usr/bin/codesign security list-keychains -s ~/Library/Keychains/build.keychain security set-key-partition-list -S apple-tool:,apple: -s -k $(KEYCHAIN_PASS) build.keychain env: DEV_ID_CERT_B64: $(DEV_ID_CERT_B64) DEV_ID_CERT_PASS: $(DEV_ID_CERT_PASS) KEYCHAIN_PASS: $(KEYCHAIN_PASS) - script: cargo tauri build --release --targets x86_64-apple-darwin,aarch64-apple-darwin displayName: Build universal binary - script: | codesign --deep --force \ --options runtime \ --entitlements ./entitlements.plist \ --sign "Developer ID Application: Acme Corp. ($(TEAM_ID))" \ target/release/bundle/macos/$(APP_NAME).app displayName: Sign .app - script: | xcrun notarytool store-credentials "az-notary" \ --apple-id $(APPLE_ID) \ --team-id $(TEAM_ID) \ --password $(AC_PASSWORD) xcrun notarytool submit target/release/bundle/macos/$(APP_NAME).dmg \ --keychain-profile "az-notary" --wait xcrun stapler staple target/release/bundle/macos/$(APP_NAME).dmg env: APPLE_ID: $(APPLE_ID) TEAM_ID: $(TEAM_ID) AC_PASSWORD: $(AC_PASSWORD) displayName: Notarize & Staple - publish: target/release/bundle/macos/*.dmg artifact: $(APP_NAME)-macos-universal |
トラブルシューティングとベストプラクティスチェックリスト
実務で遭遇しやすいエラーをまとめ、原因特定の手順 と 予防策 を提示します。CI に組み込むことで失敗を早期に検出できます。
代表的なエラーパターンと対処法
| エラー | 主な原因 | 推奨対策 |
|---|---|---|
resource fork, Finder information not allowed |
署名対象に拡張属性が残っている | xattr -rc <app>.app で全属性を削除してから再署名 |
entitlements mismatch |
Entitlement キーの綴りミス、または不要キーが含まれる | plutil -lint entitlements.plist で構文検証し、Apple の公式リストと照合 |
certificate not found in keychain |
Keychain 名が違う、パスフレーズ不一致 | security list-keychains で有効キーチェーンを確認、インポート手順を再実行 |
The signature of the binary is invalid. |
署名後にファイルが変更された(例:ZIP 圧縮時の属性付与) | 署名 → notarize の順序を守り、ditto -c -k --sequesterRsrc --keepParent で ZIP を作成 |
notarytool not found |
Xcode Command Line Tools が古い | xcode-select --install または最新の Xcode に更新 |
ベストプラクティスチェックリスト
| 項目 | 確認方法 |
|---|---|
tauri.conf.json のバンドル ID が Developer アカウントと一致 |
手動で文字列比較 |
| 証明書が Keychain の login キーリングに存在 | security find-identity -v -p codesigning |
| Entitlements に必須キーだけが含まれる | plutil -lint entitlements.plist と codesign --display --entitlements :- <app>.app で実装内容を比較 |
| 署名後に拡張属性が残っていない | xattr -lr SuperApp.app が空であること |
| notarization が成功し、staple が付与されている | xcrun stapler validate SuperApp.dmg が PASS を返す |
| CI のシークレットは暗号化されたまま保存されている | GitHub/ Azure の「Secrets」画面でマスク表示を確認 |
最終的なポイント:
1. ユニバーサルビルド → --targets で両アーキテクチャ対応。
2. コード署名 は Hardened Runtime と Entitlement の組み合わせが必須。公式ドキュメントを参照し、不要権限は付与しない。
3. 公証 → notarytool + stapler が標準フロー。失敗時はログ URL を取得して原因分析。
4. CI/CD → 証明書・パスワードはシークレット化、ビルド後にキーチェーンを必ず削除。
これらの手順とチェックリストをプロジェクトに組み込めば、macOS 13+ の最新環境でも安全かつスムーズに Tauri アプリを配布できるようになります。