# 機能設計書 59-パスワードパラメータ

## 概要

本ドキュメントは、Jenkinsのパスワードパラメータ（PasswordParameterDefinition）機能の設計を記述する。パスワードパラメータは、機密情報（パスワード、APIキー等）をビルドパラメータとして安全に受け取るための機能を提供し、入力値はマスク表示され、内部的には暗号化されて保存される。

### 本機能の処理概要

**業務上の目的・背景**：ビルド実行時に、データベースパスワード、APIトークン、SSHキーフレーズなどの機密情報を渡す必要がある場面がある。通常の文字列パラメータでは、これらの値がビルドログやUI上に平文で表示されてしまう。パスワードパラメータにより、機密情報をマスク表示し、暗号化して保存することで、セキュリティリスクを軽減する。

**機能の利用シーン**：
- データベース接続パスワードをビルドに渡す際
- 外部APIのアクセストークンを指定する際
- SSHキーのパスフレーズを入力する際
- 暗号化キーやシークレットを渡す際

**主要な処理内容**：
1. パラメータ名とデフォルト値（Secret暗号化）の設定
2. パスワード入力フィールド（マスク表示）の表示
3. 入力値のSecret暗号化
4. デフォルト値表示時の特殊処理（`<DEFAULT>`プレースホルダ）
5. PasswordParameterValue生成

**関連システム・外部連携**：
- SimpleParameterDefinition: 親クラス
- PasswordParameterValue: 実際の値を保持するクラス
- Secret: Jenkinsの暗号化ユーティリティクラス
- Pipeline DSL: `password`シンボルで参照

**権限による制御**：パラメータ入力にはJob.BUILD権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ジョブ設定 | 主機能 | パスワードパラメータの定義 |
| 20 | パラメータ入力 | 主機能 | パスワード入力フィールドの表示 |

## 機能種別

セキュリティ / データ入力 / パラメータ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | パラメータの名前 | 非null |
| defaultValueAsSecret | Secret | No | デフォルト値（暗号化済み） | - |
| description | String | No | パラメータの説明 | - |

### 入力データソース

- ジョブ設定画面: PasswordParameterDefinitionのconfig.jelly
- ビルド実行画面: PasswordParameterDefinitionのindex.jelly（パスワード入力フィールド）
- CLI/REST API: 平文パスワード文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PasswordParameterValue | PasswordParameterValue | 暗号化されたパラメータ値 |
| value | Secret | 暗号化されたパスワード値 |

### 出力先

- XMLファイル: ジョブのconfig.xml内に暗号化されたデフォルト値を永続化
- PasswordParameterValue: ビルドのParametersActionに格納
- 環境変数: ビルド中に`$パラメータ名`で復号化された値として参照可能（ログ出力時はマスク）

## 処理フロー

### 処理シーケンス

```
1. ジョブ設定でPasswordParameterDefinitionを追加
   └─ name, defaultValueAsSecret, descriptionを設定
2. デフォルト値の暗号化
   └─ Secret.fromString()で暗号化
3. パラメータ定義の保存
   └─ ジョブのconfig.xmlに暗号化された状態で永続化
4. ビルド実行時のパラメータ入力
   └─ パスワード入力フィールドを表示（type="password"）
   └─ デフォルト値がある場合は<DEFAULT>プレースホルダを表示
5. ユーザー入力処理
   └─ createValue(req, jo)でPasswordParameterValue生成
   └─ <DEFAULT>の場合はデフォルト値を使用
6. ビルドへのパラメータ渡し
   └─ ParametersAction経由でビルドに関連付け
7. ログ出力時
   └─ 値はマスク表示される
```

### フローチャート

```mermaid
flowchart TD
    A[パラメータ入力画面] --> B[パスワードフィールド表示]
    B --> C{ユーザー入力?}
    C -->|デフォルト維持| D[<DEFAULT>のまま]
    C -->|新規入力| E[入力値を取得]
    D --> F{value == <DEFAULT>?}
    E --> G[Secret.fromString]
    F -->|Yes| H[デフォルト値を使用]
    F -->|No| G
    G --> I[PasswordParameterValue生成]
    H --> I
    I --> J[ビルドに渡す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-59-01 | デフォルト値プレースホルダ | UIでは`<DEFAULT>`がプレースホルダとして表示され、変更がなければデフォルト値を使用 | パラメータ入力時 |
| BR-59-02 | 暗号化保存 | デフォルト値はSecret暗号化された状態でconfig.xmlに保存 | 設定保存時 |
| BR-59-03 | ログマスク | パスワード値はビルドログ出力時にマスクされる | ビルド実行時 |
| BR-59-04 | 環境変数復号 | 環境変数として参照する際は復号化された平文が使用される | ビルド実行時 |

### 計算ロジック

暗号化処理:
- `Secret.fromString(plainText)`: 平文からSecretを生成（暗号化）
- `Secret.toString(secret)`: Secretから平文を取得（復号化）

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

本機能はデータベースを直接操作しない。

### ファイル永続化

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| パラメータ定義保存 | `jobs/{jobName}/config.xml` | WRITE | defaultValueが暗号化された状態で保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IllegalArgumentException | パラメータ名がnull | 例外スロー（親クラスで処理） |

### リトライ仕様

リトライは行わない。

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

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- 暗号化/復号化処理: O(n)（文字列長に比例するが、通常は小さい）

## セキュリティ考慮事項

- デフォルト値はJenkinsのmaster keyで暗号化されてconfig.xmlに保存される
- ビルドログへの出力時は自動的にマスクされる
- config.xmlへのアクセス権限があれば暗号化された値を見ることは可能
- 復号化にはJenkinsのmaster keyが必要
- Pipeline内でのecho出力時もマスクされる

## 備考

- Pipeline DSLでは`password(name: 'DB_PASS', defaultValue: 'secret', description: 'Database password')`で定義
- `@Symbol("password")`でPipeline DSLから参照可能
- `DEFAULT_VALUE = "<DEFAULT>"`は内部的なプレースホルダで、ユーザーがこの値を入力した場合はデフォルト値が使用される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、PasswordParameterDefinitionのフィールド構造と暗号化の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PasswordParameterDefinition.java | `core/src/main/java/hudson/model/PasswordParameterDefinition.java` | クラス定義、defaultValueフィールド（Secret型） |
| 1-2 | SimpleParameterDefinition.java | `core/src/main/java/hudson/model/SimpleParameterDefinition.java` | 親クラスの機能 |
| 1-3 | Secret.java | `core/src/main/java/hudson/util/Secret.java` | 暗号化ユーティリティ |

**読解のコツ**: `defaultValue`フィールドが`Secret`型であることに注目。これにより、config.xml上では暗号化された状態で保存される。

#### Step 2: エントリーポイントを理解する

コンストラクタとcreateValueメソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PasswordParameterDefinition.java | `core/src/main/java/hudson/model/PasswordParameterDefinition.java` | コンストラクタ、createValue()メソッド |

**主要処理フロー**:
1. **49-51行目**: `DEFAULT_VALUE = "<DEFAULT>"`定数定義
2. **54-58行目**: 非推奨の文字列コンストラクタ（Secret.fromString使用）
3. **61-65行目**: `@DataBoundConstructor`付きSecretコンストラクタ
4. **78-80行目**: `createValue(String)`で平文からPasswordParameterValue生成
5. **83-90行目**: `createValue(StaplerRequest2, JSONObject)`で`<DEFAULT>`判定
6. **93-95行目**: `getDefaultParameterValue()`でデフォルトPasswordParameterValue生成

#### Step 3: デフォルト値の特殊処理を理解する

`<DEFAULT>`プレースホルダの処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PasswordParameterDefinition.java | `core/src/main/java/hudson/model/PasswordParameterDefinition.java` | createValue()のDEFAULT_VALUE判定 |

**主要処理フロー**:
- **85-87行目**: `<DEFAULT>`の場合はデフォルト値を使用
- **102-105行目**: `getDefaultValueAsSecret()`でJellyからSecret取得

#### Step 4: Descriptorを理解する

パラメータ型のメタデータを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PasswordParameterDefinition.java | `core/src/main/java/hudson/model/PasswordParameterDefinition.java` | ParameterDescriptorImpl内部クラス |

**主要処理フロー**:
- **139行目**: `@Extension @Symbol("password")`でシンボル名定義
- **141-145行目**: `getDisplayName()`で表示名返却

### プログラム呼び出し階層図

```
パラメータ入力フォーム送信
    │
    ├─ PasswordParameterDefinition.createValue(req, jo)
    │      │
    │      └─ req.bindJSON(PasswordParameterValue.class, jo)
    │             │
    │             └─ PasswordParameterValue生成
    │
    ├─ value == "<DEFAULT>"判定
    │      │
    │      ├─ true: new PasswordParameterValue(name, getDefaultValue())
    │      └─ false: 入力値を使用
    │
    └─ setDescription()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

パスワード入力         PasswordParameterDefinition     PasswordParameterValue
(index.jelly)  ───▶    .createValue()          ───▶    .value (Secret)
      │                      │                              │
      ▼                      ▼                              ▼
"<DEFAULT>"            DEFAULT_VALUE判定              暗号化保存
または平文                   │                         config.xml
                            ▼
                     Secret.fromString()            マスク表示
                     (暗号化)                       ビルドログ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PasswordParameterDefinition.java | `core/src/main/java/hudson/model/PasswordParameterDefinition.java` | ソース | パスワードパラメータ定義 |
| PasswordParameterValue.java | `core/src/main/java/hudson/model/PasswordParameterValue.java` | ソース | パスワードパラメータ値 |
| Secret.java | `core/src/main/java/hudson/util/Secret.java` | ソース | 暗号化ユーティリティ |
| SimpleParameterDefinition.java | `core/src/main/java/hudson/model/SimpleParameterDefinition.java` | ソース | 親クラス |
| config.jelly | `core/src/main/resources/hudson/model/PasswordParameterDefinition/config.jelly` | ビュー | 設定フォーム |
| index.jelly | `core/src/main/resources/hudson/model/PasswordParameterDefinition/index.jelly` | ビュー | 入力フォーム（パスワード） |
