Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
106 changes: 106 additions & 0 deletions documentation/codesign_ja.md
Original file line number Diff line number Diff line change
@@ -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)