# 機能設計書 31-権限管理

## 概要

本ドキュメントは、Jenkinsにおける権限管理機能の設計を記載したものである。権限管理機能は、アクション毎の権限定義と制御を担当し、Jenkinsのセキュリティモデルの基盤を構成する。

### 本機能の処理概要

本機能は、Jenkinsにおけるユーザーのアクセス権限を管理し、各種操作に対する許可・拒否の制御を行う。

**業務上の目的・背景**：CI/CDシステムでは多数のユーザーやチームが共同で作業を行うため、適切なアクセス制御が不可欠である。本機能により、管理者は「誰が」「何を」できるかを細かく制御でき、不正アクセスや誤操作によるシステム破壊を防止できる。これにより、セキュリティポリシーの遵守と運用効率の向上を両立する。

**機能の利用シーン**：
- 新規ユーザーに対してジョブの閲覧のみを許可し、ビルド実行は禁止する場合
- プロジェクトチームごとに異なるアクセス権限を設定する場合
- 管理者権限を特定のユーザーのみに限定する場合
- プラグインが独自の権限を定義・登録する場合

**主要な処理内容**：
1. Permission（権限）オブジェクトの定義と登録
2. PermissionGroup（権限グループ）による権限の分類管理
3. ACL（Access Control List）による権限チェックの実行
4. 権限の階層構造（impliedBy）による包含関係の管理
5. PermissionScopeによる権限適用範囲の制御

**関連システム・外部連携**：認可戦略（AuthorizationStrategy）と連携して権限チェックを実行。SecurityRealmで認証されたユーザー情報を基に権限判定を行う。

**権限による制御**：本機能自体が権限制御の基盤であり、Jenkins.ADMINISTER権限を持つユーザーのみが権限設定を変更可能。SYSTEM認証は全ての権限チェックをバイパスする。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | アクセス拒否 | 結果表示画面 | 権限不足時のアクセス拒否表示、必要な権限の確認処理 |
| 10 | 現在のユーザー情報（Who Am I） | 参照画面 | ユーザー権限の表示 |

## 機能種別

アクセス制御 / 認可処理 / セキュリティ基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Permission | Permission | Yes | チェック対象の権限オブジェクト | null不可 |
| Authentication | Authentication | Yes | 認証情報（ユーザーのプリンシパル） | null不可 |
| owner | Class | Yes | 権限を所有するクラス | null不可 |
| name | String | Yes | 権限の名前 | Javaの識別子として有効であること |
| impliedBy | Permission | No | この権限を包含する上位権限 | 存在する権限であること |

### 入力データソース

- SecurityContextHolder: 現在の認証情報を取得
- PermissionGroup: 登録済み権限グループから権限を検索

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| hasPermission | boolean | 権限チェック結果（true=許可、false=拒否） |
| Permission.id | String | 権限の一意識別子（owner.name形式） |
| ALL | List<Permission> | 登録済みの全権限リスト |

### 出力先

- 権限チェック結果: 各種処理の実行可否判定に使用
- AccessDeniedException: 権限不足時に例外をスロー

## 処理フロー

### 処理シーケンス

```
1. 権限チェック要求受信
   └─ checkPermission(Permission)またはhasPermission(Permission)が呼び出される
2. 認証情報取得
   └─ Jenkins.getAuthentication2()で現在の認証情報を取得
3. SYSTEM認証チェック
   └─ SYSTEM認証の場合は即座にtrue（全権限許可）
4. 権限継承チェック
   └─ impliedByチェーン（上位権限）を辿って権限を確認
5. ACL判定
   └─ AuthorizationStrategyから取得したACLで実際の権限判定
6. 結果返却/例外スロー
   └─ 許可の場合は処理続行、拒否の場合はAccessDeniedException3をスロー
```

### フローチャート

```mermaid
flowchart TD
    A[権限チェック開始] --> B{SYSTEM認証?}
    B -->|Yes| C[即座に許可]
    B -->|No| D[hasPermission2呼び出し]
    D --> E{権限あり?}
    E -->|Yes| C
    E -->|No| F{impliedBy存在?}
    F -->|Yes| G[上位権限でチェック]
    G --> E
    F -->|No| H[AccessDeniedException3をスロー]
    C --> I[処理続行]
    H --> J[アクセス拒否画面表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | SYSTEM認証バイパス | SYSTEM認証は全ての権限チェックをバイパスする | Authentication.equals(SYSTEM2)の場合 |
| BR-31-02 | 権限継承 | impliedByで指定された上位権限を持つ場合、下位権限も自動的に持つ | 権限定義時にimpliedByが設定されている場合 |
| BR-31-03 | 無効権限スキップ | enabled=falseの権限はimpliedByを辿って有効な権限で判定 | Permission.enabled=falseの場合 |
| BR-31-04 | 権限一意性 | 同一PermissionGroupに同名の権限は登録不可 | 新規Permission登録時 |

### 計算ロジック

権限ID生成: `owner.getName() + '.' + name`

例: `hudson.model.Item.Build`

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

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

権限管理機能自体はデータベースを直接操作しない。権限定義はJavaコード（static final フィールド）として定義され、実行時にメモリ上で管理される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | AccessDeniedException3 | 権限チェック失敗時 | ログインユーザーの権限を確認、必要に応じて管理者に権限付与を依頼 |
| - | IllegalArgumentException | 無効な権限名で登録試行時 | Java識別子として有効な名前を使用する |
| - | IllegalStateException | 重複する権限の登録試行時 | 既存の権限定義を確認し、重複を避ける |

### リトライ仕様

権限チェックはリトライ不要。失敗時は即座にエラーを返却する。

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

権限管理はメモリ上のオブジェクトで管理されるため、トランザクション管理は不要。権限定義は起動時に静的に登録され、実行時に変更されない。

## パフォーマンス要件

- 権限チェックは頻繁に実行されるため、高速な応答が必要（数ミリ秒以内）
- CopyOnWriteArrayListを使用してスレッドセーフかつ読み取り性能を確保

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

- 権限チェックは必ずサーバーサイドで実行
- SYSTEM認証は内部処理専用であり、外部からの偽装は不可能
- 権限不足時のエラーメッセージで詳細な情報を漏洩しない
- 匿名ユーザー（ANONYMOUS）も明示的に権限制御対象

## 備考

- Permission.HUDSON_ADMINISTERはJenkins.ADMINISTERに移行済み（後方互換性のため残存）
- PermissionScopeにより権限の適用範囲（JENKINS全体/ITEM_GROUP/ITEM等）を制御可能

---

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

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

### 推奨読解順序

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

権限管理の中核となるPermissionクラスの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Permission.java | `core/src/main/java/hudson/security/Permission.java` | 権限の定義方法、impliedByによる継承関係 |

**主要処理フロー**:
- **49-110行目**: Permissionクラスのフィールド定義（owner, group, name, description, impliedBy, enabled, scopes）
- **142-158行目**: コンストラクタでの権限登録処理（group.add、ALL.add）
- **218-223行目**: getId()メソッドによる権限ID生成ロジック
- **240-253行目**: fromId()による文字列から権限オブジェクトへの変換

**読解のコツ**: Permissionは不変オブジェクトとして設計されており、一度作成されると変更されない。staticフィールドとして定義されることが多い。

#### Step 2: 権限グループを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Permission.java | `core/src/main/java/hudson/security/Permission.java` | PermissionGroupの参照（297-358行目の定義済み権限グループ） |

**主要処理フロー**:
- **297行目**: HUDSON_PERMISSIONS - Jenkins全体の権限グループ
- **318行目**: GROUP - Permission.classに関連付けられた汎用権限グループ
- **333-358行目**: READ, WRITE, CREATE, UPDATE, DELETE, CONFIGURE - 汎用権限定義

#### Step 3: ACLによる権限チェックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ACL.java | `core/src/main/java/hudson/security/ACL.java` | 実際の権限チェックロジック |

**主要処理フロー**:
- **70-81行目**: checkPermission()メソッド - 権限チェックとAccessDeniedException3のスロー
- **132-138行目**: hasPermission()メソッド - 権限チェック（boolean返却）
- **175-181行目**: hasPermission2()メソッド - 実際の権限判定（抽象メソッド）
- **339-358行目**: EVERYONE, ANONYMOUS, SYSTEM2などの特殊Sid定義
- **374行目**: SYSTEM2認証定義 - 全権限をバイパスする特殊認証

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

```
AccessControlled.checkPermission(Permission)
    │
    └─ ACL.checkPermission(Permission)
           │
           ├─ Jenkins.getAuthentication2()
           │
           ├─ [SYSTEM2チェック] → 即座にreturn
           │
           └─ ACL.hasPermission2(Authentication, Permission)
                  │
                  └─ AuthorizationStrategy.getACL().hasPermission2()
                         │
                         └─ 具体的な認可戦略による判定
```

### データフロー図

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

Authentication ────────▶ ACL.checkPermission() ───────▶ void（成功時）
     │                         │                              │
Permission ────────────▶ hasPermission2() ────────────▶ AccessDeniedException3（失敗時）
                               │
                    AuthorizationStrategy
                               │
                         ACL判定結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Permission.java | `core/src/main/java/hudson/security/Permission.java` | ソース | 権限オブジェクトの定義 |
| ACL.java | `core/src/main/java/hudson/security/ACL.java` | ソース | アクセス制御リスト、権限チェック実行 |
| PermissionGroup.java | `core/src/main/java/hudson/security/PermissionGroup.java` | ソース | 権限のグループ化管理 |
| PermissionScope.java | `core/src/main/java/hudson/security/PermissionScope.java` | ソース | 権限の適用範囲定義 |
| AccessControlled.java | `core/src/main/java/hudson/security/AccessControlled.java` | ソース | 権限チェック対象のインターフェース |
| AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | ソース | 認可戦略の基底クラス |
| AccessDeniedException3.java | `core/src/main/java/hudson/security/AccessDeniedException3.java` | ソース | 権限不足時の例外クラス |
