Wails 実践講座 #5 署名と公証 — デプロイしたアプリが信頼される仕組み

#4 まででノートアプリは機能が完成しました。次は他人の端末で実行されるようにする番ですが、ここで多くの個人開発者が詰まります。署名していないアプリは macOS と Windows があからさまに警告を出して実行を止めるからです。この記事は、デプロイしたアプリが信頼されるようにするコード署名と公証を扱います。

全 10 編(2 部構成)のうち 5 番目の記事です。

なぜ署名が必要か #

入門 #6 でビルドしたバイナリをそのまま他人に送ると、受け取る人の OS が立ちはだかります。

  • macOS Gatekeeper: 署名・公証されていないアプリを「確認されていない開発者」として開くのを拒否します。ユーザーが右クリックで強制実行はできますが、一般ユーザーにその手順を案内するのは配布として失敗です。
  • Windows SmartScreen: 署名されていないか評判が積まれていない実行ファイルに「Windows によって PC が保護されました」の青い警告を出します。

署名はこのアプリを誰が作ったかを保証し、公証は Apple が悪意あるコードがないか検査したという確認です。両方を通せば警告が消え、配布後にファイルが改ざんされていないことも保証されます。

macOS: 署名してから公証 #

macOS の配布は 2 段階です。まず Apple Developer 証明書で署名し、その後 Apple のサーバーにアップロードして公証を受けます。有料の Apple Developer Program 登録(年 $99)が前提です。

1) コード署名 — Developer ID Application 証明書で
codesign --deep --force --options runtime \
  --sign "Developer ID Application: Your Name (TEAMID)" \
  build/bin/ノート.app

--options runtime は公証の前提条件であるハードンドランタイムを有効にします。署名したアプリを zip か dmg にまとめて Apple に提出し、公証を待ちます。現在のツールは notarytool です(過去の資料の altool は廃止されました)。

2) 公証 — notarytool で提出してステープル
# アプリを zip にまとめて提出 (完了まで待機)
xcrun notarytool submit ノート.zip \
  --apple-id "you@example.com" --team-id TEAMID \
  --password "アプリ専用パスワード" --wait

# 公証の結果をアプリに付け、オフラインでも検証されるようにする
xcrun stapler staple build/bin/ノート.app

--wait は公証が終わるまで待ちます。最後の stapler staple は公証チケットをアプリに埋め込み、ユーザーがインターネットなしで実行しても検証されるようにします。この段階を抜かすと、オフラインのユーザーに警告が再び出ることがあります。

注記
過去には mitchellh/gon のようなツールで署名・公証をまとめて処理しましたが、gon はメンテナンスが停止しました。現在は上のように codesign と notarytool を直接使う方式が標準です。Wails 公式ドキュメントの署名ガイドもこの流れに従います。

Windows: 証明書の種類が体験を分ける #

Windows のコード署名は証明書で .exe やインストーラーに署名します。signtool で署名する手順自体は単純ですが、証明書の種類がユーザー体験を大きく分けます。

証明書おおよその費用SmartScreen の警告
OV(組織検証)年に数十〜百ドル台初期に出るが、ダウンロード・評判が積まれると消える
EV(拡張検証)より高価、HSM・トークンが必要即座に信頼、評判の蓄積待ちなし

個人・小規模なら OV で始めて評判が積まれるのを待つのが現実的です。即座に警告をなくす必要があれば EV が必要ですが、費用とハードウェアの要件が大きいです。

signtool で署名 (タイムスタンプ付き)
signtool sign /fd SHA256 /a `
  /tr http://timestamp.digicert.com /td SHA256 `
  build\bin\ノート.exe

/tr のタイムスタンプは必ず入れます。タイムスタンプがあれば証明書が後で期限切れになっても、署名時点で有効だったことが保証され、署名が引き続き認められます。

秘密はローカルに置かない #

署名には証明書・パスワード・アプリ専用パスワードのような機微な値が必要です。これらをコードやリポジトリに入れるとそのまま漏洩します。ローカルで手動署名するときは環境変数か OS のキーチェーンに置き、#6 で CI に渡すときは GitHub Secrets に暗号化して保存します。証明書ファイル自体も base64 でエンコードして Secret に入れ、ワークフローで復元する方式が標準です。この分離ができていてこそ、次の記事の自動化が安全です。

まとめ #

  • 署名していないアプリは macOS Gatekeeper と Windows SmartScreen が警告でブロックします。署名は作成者を保証し、公証は Apple の悪意あるコード検査の確認です。
  • macOS は codesign でハードンドランタイムを有効にして署名した後、notarytool で公証し stapler staple でチケットを埋め込みます。メンテナンスが停止した gon の代わりにこの方式が現行です。
  • Windows は signtool で署名しますが、タイムスタンプを必ず入れます。OV は評判が積まれると警告が消え、EV は即座に信頼されますが高価です。
  • 証明書・パスワードはローカルに置かず、環境変数・キーチェーン・GitHub Secrets に置きます。この分離が次の記事の CI 自動化の前提です。
  • 次の記事では、この署名・公証を GitHub Actions に入れ、タグ一つで 3 プラットフォームのリリースが自動生成されるようにします。
X