この記事は、以下の記事のアップデート版 (2023) です。
まずは前提から
macOS 10.14.5 Mojave 以降では、App Store 経由ではないアプリ(いわゆる野良アプリ)であっても、コード署名に加え、Apple 社による「公証 (notary)」を受けていない場合には、以下(↓)のような警告が表示され、原則としてそのままでは実行できません。
この制限は Electron 製アプリにとっても変わりありません。これをクリアするために必要な条件が以下の 2 つです。
- 有効な「Developer ID Application 証明書」でコード署名する
- コード署名と公証に electron-builder を利用する
本稿では electron-builder を利用しますが、他のツールを利用する場合であっても同様の処理を行う必要があります。
以下の記述は、すでに Xcode がインストール済みであることを前提としています。
有効な Developer ID でコード署名する
アプリへコード署名を施すには、有効な「Developer ID Application 証明書」がその Mac へインストールされている必要があります。そして、electron-builder は自動的に「キーチェーンアクセス.app」内のその証明書を利用します。
📸 キーチェーンアクセスに取り込んだ Developer ID 証明書:
そのためには Apple Devloper Program で購入した Apple Developer アカウントが必要で、その ID の証明書をキーチェーンアクセスへ登録しておかなければなりません。
その手順は:
- Apple Devloper Program で開発者アカウントを購入する(年間 99 ドル)
- そのアカウントの "Certificates, Identifiers & Profiles" ページ → "Certificates" タブで Developer ID Application 証明書を作成
- その証明書をダウンロードし、ダブルクリックでキーチェーンアクセスへインストール
という流れになります。
📸 Developer ID Application を選択:
📸 作成した証明書のページから Developer ID Application 証明書をダウンロード:
📸 証明書のダブルクリックでキーチェーンアクセスへインストール:
electron-builder でコード署名し、公証を受ける
- electron-builder のインストール
npm install --save-dev electron-builder
有効な Developer ID Application 証明書がインストールされている場合、electron-builder (厳密には、これに含まれる @electron/osx-sign パッケージ)は自動でその証明書を使ってアプリにコード署名を行います。
逆に言えば、あえてコード署名したくない場合には、パッケージスクリプト内の mac.identity
エントリへ null
を明示的に指定する必要があります。
- パッケージスクリプトの例
require("dotenv").config(); // 環境変数の展開(後述)
// パッケージスクリプト本体
require("electron-builder").build({
config: {
productName: "Sample",
artifactName: "${productName}-${version}-${platform}-${arch}.${ext}",
copyright: "© 2023 sprout2000",
files: ["dist/**/*"], // 対象アプリの置き場所
directories: {
output: "release", // パッケージの出力先
},
mac: {
appId: "jp.sprout2000.Sample", // アプリID
category: "public.app-category.developer-tools", // カテゴリ
target: ["default"], // dmg と zip
icon: "assets/icon.icns", // アイコンには icns ファイルが必要
/**
* 公証の設定(後述)
*/
notarize: {
teamId: "369RBS5M6E",
},
// identity: null, // コード署名しない場合はアンコメント
},
},
});
パッケージスクリプトの詳細については electron-builder のドキュメントを参照してください。
また、mac.category
エントリの値については Apple のドキュメントを参照してください。
アプリへ公証を受ける
アプリはコード署名がなされたあと、dmg と zip へパッケージされる前に公証を受けなければいけません。この間の一連の処理は、electron-builder の mac.notarize
エントリ以下の設定が自動で行ってくれます。
mac: {
// ...
notarize: {
teamId: "369RBS5M6E",
},
},
-
teamId
の値には Apple ID に割り振られた Team ID が入ります。Team ID は大文字と数字からなる 10 桁の文字列です。
dotenv を導入する
アプリへの公証を受けるためには、electron-builder へ秘匿情報を環境変数として渡す必要があります。しかし、これらはビルドスクリプトへベタ書きできないようになっています。GitHub などへコードをアップロードするとこれらの情報が他者にも晒されてしまうからです。
環境変数を記述した .env
ファイルをスクリプト内で展開してくれるツール、dotenv を導入しましょう。
npm install --save-dev dotenv
.env
ファイルを作成する
electron-builder へ渡す環境変数は以下の 2 つです。これらの値を .env
ファイルへ記述しておきます。
- APPLE_ID
- APPLE_APP_SPECIFIC_PASSWORD
-
APPLE_ID
の値は、その名の通り、Developer program に登録したアカウント名(=メールアドレス)です。 -
APPLE_APP_SPECIFIC_PASSWORD
(=アプリ固有のパスワード)は、Apple ID そのものの代わりに、そのアプリに固有のパスワードを与えたものです。これは、Apple Developer ID では 2 要素認証が必須とされているため、スクリプトで認証を受けることができないことに由来します。アプリ固有のパスワードは、appleid.apple.com で作成します(以下の画像を参照)。
-
.env
ファイルの例
APPLE_ID="sprout2000@example.jp"
APPLE_APP_SPECIFIC_PASSWORD="hhcd-aemv-kkor-hzes"
.env
ファイルは必ず .gitignore
内にそのパスを指定してください。
git に管理(= GitHub などへアップロード)させてしまうと秘匿情報が漏えいしてしまいます。
- ビルドスクリプトの例 (2)
// dotenv で ".env" ファイル内の環境変数を展開
+ require("dotenv").config();
require("electron-builder").build({ /** */ });
コード署名&公証の実行
パッケージスクリプトを実行し、コード署名と公証のプロセスを開始します。Apple の notary サーバーの状況にもよりますが、全ての処理が完了するまでに 5~10 分の時間を要します。
node ./builder.js
% node ./builder.js
• electron-builder version=24.4.0 os=22.4.0
• writing effective config file=release/builder-effective-config.yaml
• executing @electron/rebuild arch=arm64 version=24.2.0 appDir=/Users/taro/sample
• packaging platform=darwin arch=arm64 electron=24.2.0 appOutDir=release/mac-arm64
• signing file=release/mac-arm64/Sample.app identityName=Developer ID Application: Taro Nippon
• building target=macOS zip arch=arm64 file=release/Sample-0.1.0-darwin-arm64.zip
• building target=DMG arch=arm64 file=release/Sample-0.1.0-darwin-arm64.dmg
• building block map blockMapFile=release/Sample-0.1.0-darwin-arm64.dmg.blockmap
• building block map blockMapFile=release/Sample-0.1.0-darwin-arm64.zip.blockmap
なお、コード署名&公証に成功しているか否かは、spctl
コマンドを用いて確認できます。
% spctl -a -vvv -t install release/mac-arm64/Sample.app
release/mac-arm64/Sample.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Taro Nippon (369RBS5M6E)
また、いったんクラウドストレージへアップロードした dmg または zip をダウンロードし、自分で開いてみる方法も有効です。その場合は、「インターネットからダウンロードされたアプリケーション」である旨の警告のみが表示されます。
おまけ:署名も公証もされていないアプリを開くには?
以下の手順でアプリを開いた結果は自己責任でお願いします。
xattr
コマンドを利用してアプリを Apple Gate Keeper の対象外とします。
% xattr -rc /hoge/foo/Sample.app