# バッチ設計書 62-osx-codesign.sh

## 概要

本ドキュメントは、Node.jsプロジェクトにおけるmacOS向けコード署名スクリプト（osx-codesign.sh）の設計仕様を記載したものである。

### 本バッチの処理概要

osx-codesign.shは、macOS向けNode.jsリリースにおいて、node実行ファイルにAppleのコード署名を付与するためのシェルスクリプトである。Hardened Runtimeを有効化した署名を行い、macOS Catalina以降のGatekeeperセキュリティ要件を満たすことを目的としている。

**業務上の目的・背景**：macOS Catalina（10.15）以降、Gatekeeperはより厳格なセキュリティチェックを行うようになり、Hardened Runtimeが有効化されたコード署名がないアプリケーションは実行がブロックされる。Node.jsをmacOSユーザーに安全に配布するため、Apple Developer ID証明書による署名とHardened Runtimeの有効化が必須となっている。entitlements（権限）ファイルを使用して、JITコンパイルや動的ライブラリ読み込みなどNode.jsに必要な特殊権限を宣言している。

**バッチの実行タイミング**：Node.jsの新バージョンリリース時、macOS向けバイナリのビルド完了後に実行される。リリースパイプラインの一部として自動実行される。

**主要な処理内容**：
1. SIGN環境変数の存在確認（未設定の場合はスキップ）
2. codesignコマンドによるコード署名の実行
3. entitlementsファイル（osx-entitlements.plist）の適用
4. Hardened Runtimeオプション（--options runtime）の有効化
5. タイムスタンプの付与

**前後の処理との関連**：ビルド処理が完了し、パッケージディレクトリ（$PKGDIR）にnode実行ファイルが配置された後に実行される。署名完了後はosx-productsign.shによるインストーラー署名、osx-notarize.shによる公証処理へと続く。

**影響範囲**：macOS向けNode.jsリリースバイナリ。署名がない場合、macOS Catalina以降でGatekeeperによりブロックされる可能性がある。

## バッチ種別

署名処理（コード署名・セキュリティ）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | リリース時（随時） |
| 実行時刻 | リリースビルド完了後 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | リリースCI/CDパイプライン |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| SIGN環境変数 | Apple Developer ID証明書の識別子が設定されていること |
| PKGDIR環境変数 | パッケージディレクトリのパスが設定されていること |
| codesignコマンド | Xcodeコマンドラインツールがインストールされていること |
| entitlementsファイル | tools/osx-entitlements.plistが存在すること |
| 署名対象ファイル | $PKGDIR/bin/nodeが存在すること |

### 実行可否判定

1. SIGN環境変数が設定されているかを確認
2. 未設定の場合は「Skipping codesign.」メッセージを出力してスキップ（正常終了）
3. 設定されている場合はcodesign処理を実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| SIGN | 環境変数 | No | なし | Apple Developer ID証明書の識別子 |
| PKGDIR | 環境変数 | Yes | なし | パッケージディレクトリのパス |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| $PKGDIR/bin/node | バイナリ（Mach-O） | 署名対象のNode.js実行ファイル |
| tools/osx-entitlements.plist | XML（plist） | 署名時に適用する権限（entitlements）定義 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 署名済みファイル | バイナリ（Mach-O） | コード署名が付与された$PKGDIR/bin/node |
| 標準エラー出力 | テキスト | スキップ時のメッセージ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | node（変更なし） |
| 出力先 | $PKGDIR/bin/node |
| 文字コード | N/A（バイナリ） |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. SIGN環境変数チェック
   └─ 未設定の場合: メッセージ出力後、終了コード0で終了（スキップ）
2. codesignコマンド実行
   └─ --sign: SIGN環境変数の証明書識別子を使用
   └─ --entitlements: tools/osx-entitlements.plistを適用
   └─ --options runtime: Hardened Runtimeを有効化
   └─ --timestamp: タイムスタンプを付与
   └─ 対象: $PKGDIR/bin/node
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト開始] --> B{SIGN環境変数設定確認}
    B -->|未設定| C[Skipping codesign メッセージ出力]
    C --> D[終了コード0で終了]
    B -->|設定済み| E[codesign実行]
    E --> F{署名成功?}
    F -->|成功| D
    F -->|失敗| G[エラーで終了]
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベースを使用しない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

N/A

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 0 | 正常スキップ | SIGN環境変数が未設定 | 署名が不要な場合は正常動作。署名が必要な場合はSIGN環境変数を設定 |
| 非0 | 署名エラー | codesignコマンドが失敗 | 証明書の有効性、Keychain設定、ファイルアクセス権限を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. set -eにより、codesignコマンド失敗時は即座にスクリプトが終了
2. エラーメッセージを確認し、原因を特定
3. 証明書が期限切れの場合: Apple Developer Programで更新
4. Keychainアクセスエラーの場合: security unlock-keychainでロック解除
5. ファイルが見つからない場合: $PKGDIRパスとnode実行ファイルの存在を確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイル操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1ファイル/実行 |
| 目標処理時間 | 30秒以内 |
| メモリ使用量上限 | N/A |

## 排他制御

同一ファイルに対する同時署名は不可。リリース環境では順次実行される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| デバッグログ | 常時 | set -xによりすべてのコマンドが標準エラーに出力される |
| スキップログ | SIGN未設定時 | "No SIGN environment var.  Skipping codesign." |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 署名失敗 | 1回 | リリース担当者 |

## 備考

- https://github.com/nodejs/node/pull/31459 に関連する変更
- Hardened Runtimeを有効化することで、macOS Catalina以降のGatekeeper要件を満たす
- entitlementsファイルでJITコンパイル、未署名実行可能メモリ、ライブラリバリデーション無効化などの権限を宣言
- entitlements内の主要な権限：
  - com.apple.security.cs.allow-jit: JITコンパイル許可
  - com.apple.security.cs.allow-unsigned-executable-memory: 未署名実行可能メモリ許可
  - com.apple.security.cs.disable-library-validation: ライブラリバリデーション無効化
  - com.apple.security.get-task-allow: デバッグ許可
