diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cadf2f6..da4a82e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,6 +64,28 @@ jobs: -output libflip_native.dylib lipo -info libflip_native.dylib + - name: Sign native library + run: | + CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12" + KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db" + + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o "$CERTIFICATE_PATH" + + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + + security import "$CERTIFICATE_PATH" -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" + security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security list-keychain -d user -s "$KEYCHAIN_PATH" + + codesign --sign "Developer ID Application" --force --timestamp flip-native/libflip_native.dylib + codesign --verify --verbose flip-native/libflip_native.dylib + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} + P12_PASSWORD: ${{ secrets.P12_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + - name: Upload native library uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 with: diff --git a/documentation/codesign_ja.md b/documentation/codesign_ja.md new file mode 100644 index 0000000..37ee553 --- /dev/null +++ b/documentation/codesign_ja.md @@ -0,0 +1,106 @@ +# macOS ネイティブライブラリの署名について + +macOS では、署名されていないダイナミックライブラリ(`.dylib`)を実行しようとすると、Gatekeeper によってブロックされることがあります。このドキュメントでは、開発時のアドホック署名と、配布用の Apple Developer Program 証明書による署名方法を説明します。 + +## 1. 開発時のアドホック署名 + +開発中や CI で正式な証明書が利用できない場合は、アドホック署名を使用できます。 + +### 手順 + +1. NuGet パッケージ(`.nupkg`)をダウンロード +2. 解凍(`.nupkg` は ZIP 形式) +3. 以下のコマンドでアドホック署名を実行 + +```bash +codesign --sign - runtimes/osx/native/libflip_native.dylib +``` + +`--sign -` の `-` はアドホック署名を意味します。これにより、ローカル環境での実行が可能になります。 + +### 署名の確認 + +```bash +codesign --verify --verbose runtimes/osx/native/libflip_native.dylib +``` + +## 2. Apple Developer Program 証明書による署名 + +配布用のビルドでは、Apple Developer Program の「Developer ID Application」証明書で署名することで、Gatekeeper の警告なしに実行できるようになります。 + +### 前提条件 + +GitHub Actions で署名を行うには、以下のシークレットをリポジトリまたは Organization に設定してください。 + +| シークレット名 | 説明 | +|---|---| +| `BUILD_CERTIFICATE_BASE64` | Developer ID Application 証明書を `.p12` 形式でエクスポートし、Base64 エンコードしたもの | +| `P12_PASSWORD` | `.p12` ファイルのエクスポート時に設定したパスワード | +| `KEYCHAIN_PASSWORD` | CI 上で作成する一時キーチェーンのパスワード(任意のランダムな文字列で可) | + +> **Note:** App Store への配布ではないため、プロビジョニングプロファイルは不要です。 + +### 証明書の準備手順 + +1. **Keychain Access で証明書をエクスポート** + - Keychain Access を開く + - 「Developer ID Application: (チーム名)」証明書を選択 + - 右クリック → 「書き出す...」で `.p12` 形式で保存 + - パスワードを設定(これが `P12_PASSWORD` になる) + +2. **Base64 エンコード** + ```bash + base64 -i certificate.p12 -o certificate_base64.txt + ``` + +3. **GitHub Secrets に登録** + - `BUILD_CERTIFICATE_BASE64`: `certificate_base64.txt` の内容 + - `P12_PASSWORD`: エクスポート時のパスワード + - `KEYCHAIN_PASSWORD`: 任意のランダムな文字列 + +## 3. GitHub Actions ビルドワークフロー + +`.github/workflows/build.yml` では、macOS ネイティブライブラリのビルドと署名を自動化しています。 + +### ワークフローの流れ + +`build-native-osx` ジョブで以下の処理を行います: + +1. **ネイティブライブラリのビルド** + - arm64 と x86_64 それぞれのアーキテクチャでビルド + - `lipo` コマンドで Universal Binary を作成 + +2. **証明書のインストール**(シークレットが設定されている場合のみ) + - Base64 エンコードされた証明書をデコード + - 一時キーチェーンを作成し、証明書をインポート + +3. **コード署名**(シークレットが設定されている場合のみ) + - `codesign` コマンドでライブラリに署名 + +### codesign コマンドの証明書指定について + +ワークフローでは以下のように署名しています: + +```bash +codesign --sign "Developer ID Application" --force --timestamp flip-native/libflip_native.dylib +``` + +`"Developer ID Application"` はプレースホルダーではありません。`codesign` コマンドは証明書名の**部分一致**で検索するため、この指定で正しく動作します。 + +実際の証明書の正式名は以下のような形式です: +``` +Developer ID Application: チーム名 (チームID) +``` + +キーチェーンにインポートされた証明書の中から「Developer ID Application」を含むものが自動的に選択されます。 + +> **Note:** キーチェーンに複数の「Developer ID Application」証明書がある場合は、より具体的な名前(例:`"Developer ID Application: CyberAgent, Inc. (XXXXXXXXXX)"`)を指定する必要があります。CI 環境では通常1つしかインストールしないため、この指定で問題ありません。 + +### シークレットが未設定の場合 + +シークレットが設定されていない場合、署名ステップはスキップされます。これにより、フォークしたリポジトリや証明書を持たない環境でもビルドは成功します。ただし、生成されたライブラリは署名されていないため、使用時にはアドホック署名が必要です。 + +## 参考リンク + +- [Xcode 開発用の macOS ランナーに Apple 証明書をインストールする - GitHub Docs](https://docs.github.com/ja/actions/how-tos/deploy/deploy-to-third-party-platforms/sign-xcode-applications) +- [[macOS] ライブラリをコード署名する (codesign)](https://qiita.com/Arime/items/e1df2a8c3d4c2ce75069)