uechi.io/_posts/2019-06-05-sign-and-notarize-electron-app.md
2019-06-05 14:28:30 +09:00

5.5 KiB

title date
Electronアプリをコード署名してApple 公証 (Notary) を通過する手順 2019-06-05 00:00:00 +09:00

electron-builderを利用してmacOS向けElectronアプリをコード署名し、公証を通過させます。

Code Sign

アプリのコード署名はelectron-builderによって自動で行われます。内部的にはelectron-osx-signが使用されます。

リリース用のアプリにコード署名をするには、Keychainに有効なDeveloper ID Certificateが格納されている必要があります。macOS Developer Certificateは開発用のコード署名のみ可能なので、アプリを配布する場合には必ずDeveloper ID Certificateが必要です。

まだ証明書を発行していない場合は、Apple Developerで証明書の追加ウィザードに進み、Developer ID Applicationを選択して証明書を発行しKeychainに追加してください。

Notarize

コード署名済みのアプリをelectron-notarizeを使用してApple Notary Serviceに提出します。

const { notarize } = require('electron-notarize')
notarize({
  appBundleId,
  appPath,
  appleId,
  appleIdPassword,
  ascProvider,
})
  • appBundleId: アプリのBundle IDです。package.jsonbuild.appIdと同じものを使います。
  • appPath: .appの絶対パスを指定します。
  • appleId: Apple Developerとして登録しているApple IDを指定します。
  • appleIdPassword: Apple IDのパスワードです。2要素認証を必要としないパスワードが必要なので、Apple IDにアクセスしてApp-specific Passwordを発行してください。
  • ascProvider: Apple DeveloperのMembershipに記載されているTeam IDを指定します。

electron-builderのafterSignフック

electron-builderのafterSignフックを使用して、コード署名が済んだアプリを自動でNotaryに提出します。

フックスクリプトを./scripts/after-sign-mac.jsに置きます。

const path = require('path')
const { notarize } = require('electron-notarize')

const appleId = process.env.APPLE_ID
const appleIdPassword = process.env.APPLE_PASSWORD
const ascProvider = process.env.ASC_PROVIDER

const configPath = path.resolve(__dirname, '../package.json')
const appPath = path.resolve(__dirname, '../dist/mac/App.app')
const config = require(configPath)
const appBundleId = config.build.appId

async function notarizeApp() {
  console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`)
  await notarize({
    appBundleId,
    appPath,
    appleId,
    appleIdPassword,
    ascProvider,
  })
  console.log('afterSign: Notarized')
}

exports.default = async () => {
  await notarizeApp()
}

package.jsonbuildafterSignを追加してコード署名が終わった後にスクリプトが実行されるようにします。

"build": {
	"afterSign": "./scripts/after-sign-mac.js"
}

Enable Hardened Runtime

このままでは公証に失敗します。デフォルトで書き出されるバイナリでは、セキュリティの強化されたHardened Runtimeが有効になっていないためです。以下のようなエラーメッセージを貰います。

{
  // ...
  "status": "Invalid",
  "statusSummary": "Archive contains critical validation errors",
  "statusCode": 4000,
  "issues": [
    {
      "severity": "error",
      "code": null,
      "path": "App.zip/App.app/Contents/MacOS/App",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
  }
}

package.jsonbuild.mac.hardenedRuntimetrueにしてHardened Runtimeを有効にすることでこの問題を解決します。

"build": {
  "mac": {
    "hardenedRuntime": true
  }
}

詳細

Verify Notary Status

ただしく公証を得られたかどうかはaltoolで調べることができます。

公証通過後に送られてくるメールにRequest Identifierが記載されているのでメモします。

Dear Yasuaki,

Your Mac software has been notarized. You can now export this software and distribute it directly to users.

Bundle Identifier: <Bundle ID>
Request Identifier: <UUID>

For details on exporting a notarized app, visit Xcode Help or the notarization guide.
Best Regards,
Apple Developer Relations

xcrun altool --notarization-infoコマンドにUUIDとApple ID、パスワードを指定して公証ステータスを確認します。

xcrun altool --notarization-info <UUID> -u $APPLE_ID -p $APPLE_PASSWORD

正しく公証が得られている場合は以下のようなメッセージが表示されます。おめでとうございます!

2019-06-05 13:51:18.236 altool[5944:261201] No errors getting notarization info.

   RequestUUID: <UUID>
          Date: 2019-06-05 04:45:54 +0000
        Status: success
    LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/<Log file identifier>
   Status Code: 0
Status Message: Package Approved