# 機能設計書 29-認可（AuthorizationStrategy）

## 概要

本ドキュメントは、JenkinsのAuthorizationStrategy機能の設計仕様を定義する。AuthorizationStrategyは、Jenkins全体およびオブジェクト単位のアクセス制御を行うためのプラグイン可能な抽象化レイヤーを提供する。

### 本機能の処理概要

AuthorizationStrategyは、認証済みユーザーに対してJenkinsの各機能・オブジェクトへのアクセス権限を制御する機能である。

**業務上の目的・背景**：エンタープライズ環境では、ユーザーやグループごとに異なる権限を付与する必要がある。AuthorizationStrategyは、ロールベースアクセス制御（RBAC）やプロジェクトベースの権限制御など、様々な認可モデルをプラグインとして実装可能にする拡張ポイントを提供する。

**機能の利用シーン**：
- 管理者と一般ユーザーの権限分離
- プロジェクトごとのアクセス制御
- ロールベースの権限管理
- 読み取り専用ユーザーの設定
- ジョブの実行権限制御

**主要な処理内容**：
1. ルートACL（getRootACL）による全体的なアクセス制御
2. オブジェクト固有のACL（getACL(Job)等）による細粒度制御
3. グループ/ロール情報の提供（getGroups）
4. 権限チェック（ACL.hasPermission）

**関連システム・外部連携**：SecurityRealm（認証）、ACL、Permission、各種プラグイン（Role Strategy Plugin、Project-based Matrix Authorization等）。

**権限による制御**：AuthorizationStrategyの設定はAdminister権限を持つユーザーのみが変更可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | セキュリティ設定 | 主画面 | AuthorizationStrategyの選択・設定 |
| 12 | ジョブ設定 | 関連 | ジョブ単位の権限確認 |

## 機能種別

拡張ポイント / セキュリティ・認可

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| authentication | Authentication | Yes | 認証情報 | null不可 |
| permission | Permission | Yes | チェック対象権限 | null不可 |

### 入力データソース

SecurityContextHolderからの認証情報。各操作時にACL.hasPermission()で権限チェック。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ACL | ACL | アクセス制御リスト |
| hasPermission | boolean | 権限有無の判定結果 |
| groups | Collection<String> | 使用されているグループ/ロール名のリスト |

### 出力先

各APIエンドポイント、画面表示でのアクセス制御判定。

## 処理フロー

### 処理シーケンス

```
1. ユーザーがリソースにアクセス
   └─ ACL.checkPermission(Permission) 呼び出し
2. AuthorizationStrategy.getACL(target) で対象ACL取得
   └─ 対象タイプに応じたACLを返却
3. ACL.hasPermission(Authentication, Permission) で権限チェック
   └─ 実装固有の権限判定ロジック
4. 権限なしの場合
   └─ AccessDeniedException送出
5. 権限ありの場合
   └─ 処理続行
```

### フローチャート

```mermaid
flowchart TD
    A[リソースアクセス] --> B[checkPermission呼び出し]
    B --> C{対象タイプ判定}
    C -->|Job| D[getACL Job]
    C -->|View| E[getACL View]
    C -->|Node| F[getACL Node]
    C -->|その他| G[getRootACL]
    D --> H[ACL.hasPermission]
    E --> H
    F --> H
    G --> H
    H --> I{権限あり?}
    I -->|Yes| J[処理続行]
    I -->|No| K[AccessDeniedException]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | RootACL継承 | 各オブジェクトのACLはデフォルトでRootACLを返す | getACL()デフォルト実装 |
| BR-002 | View可視性 | ViewはREAD権限またはCONFIGURE権限、または子アイテムがある場合に表示 | View.READ判定時 |
| BR-003 | UNSECURED | 全アクセスを許可する認可なしモード | UNSECUREDシングルトン |

### 計算ロジック

```java
// View可視性の判定例（AuthorizationStrategy.getACL(View)）
public @NonNull ACL getACL(final @NonNull View item) {
    return ACL.lambda2((a, permission) -> {
        ACL base = item.getOwner().getACL();
        boolean hasPermission = base.hasPermission2(a, permission);
        if (!hasPermission && permission == View.READ) {
            return base.hasPermission2(a, View.CONFIGURE) || !item.getItems().isEmpty();
        }
        return hasPermission;
    });
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | config.xml | INSERT/UPDATE | AuthorizationStrategy設定の永続化 |

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

#### config.xml（Jenkins設定ファイル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | authorizationStrategy | AuthorizationStrategy設定 | XMLシリアライズ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | AccessDeniedException | 権限なしでのアクセス試行 | エラーページ表示 |

### リトライ仕様

権限エラーに対するリトライは行わない。

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

トランザクション管理はない。権限チェックは状態を変更しない純粋な判定処理。

## パフォーマンス要件

- 権限チェックは高頻度で呼び出されるため、高速に実行される必要がある
- 複雑な権限設定でもO(1)またはO(log n)での判定が望ましい

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

- 権限チェックのバイパスは許可されない
- UNSECURED認可はセキュリティリスクとして警告される
- ACLの実装は正確に権限を判定する責任がある

## 備考

- UNSECUREDは認可なしモードのシングルトン（全アクセス許可）
- 具体的な認可実装はプラグインで提供（Role Strategy Plugin等）
- Jenkinsと一緒に永続化される

---

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

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

### 推奨読解順序

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

AuthorizationStrategyの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | 抽象クラス定義 |

**読解のコツ**: AuthorizationStrategyは抽象クラスで、getRootACL()とgetGroups()が主要な抽象メソッド。各オブジェクトタイプ用のgetACL()メソッドはデフォルトでRootACLを返す。

#### Step 2: 主要メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | getRootACL()、getACL()系メソッド |

**主要処理フロー**:
- **73行目**: AuthorizationStrategy - クラス定義（Describable, ExtensionPoint実装）
- **80行目**: getRootACL() - 抽象メソッド、ルートACL取得
- **91-93行目**: getACL(Job) - ジョブ用ACL（デフォルトはRootACL）
- **105-116行目**: getACL(View) - ビュー用ACL（可視性判定ロジック付き）
- **127-129行目**: getACL(AbstractItem) - アイテム用ACL
- **140-142行目**: getACL(User) - ユーザー用ACL
- **153-155行目**: getACL(Computer) - コンピュータ用ACL
- **182-184行目**: getACL(Cloud) - クラウド用ACL
- **186-188行目**: getACL(Node) - ノード用ACL
- **204行目**: getGroups() - 抽象メソッド、グループ一覧取得

#### Step 3: Unsecuredクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | Unsecured内部クラス |

**主要処理フロー**:
- **229行目**: UNSECURED - 認可なしモードのシングルトン
- **231-264行目**: Unsecured - 全アクセスを許可する実装
- **249行目**: UNSECURED_ACL - 常にtrueを返すACL

#### Step 4: 拡張ポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | all() |

**主要処理フロー**:
- **209-211行目**: all() - 全登録AuthorizationStrategyのDescriptor取得

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

```
リソースアクセス
    │
    └─ AccessControlled.checkPermission(Permission)
           │
           ├─ AccessControlled.getACL()
           │      │
           │      └─ AuthorizationStrategy.getACL(target)
           │             │
           │             ├─ [Job] getACL(Job)
           │             ├─ [View] getACL(View)
           │             ├─ [Node] getACL(Node)
           │             └─ [Other] getRootACL()
           │
           └─ ACL.hasPermission2(Authentication, Permission)
                  │
                  └─ [実装依存] 権限判定
                         │
                         ├─ 権限あり → 処理続行
                         └─ 権限なし → AccessDeniedException
```

### データフロー図

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

Authentication       AuthorizationStrategy
├─ Principal       ├─ getACL(target) ───────────▶     ACL
├─ Authorities     │
└─ ...             └─ getRootACL() ─────────────▶     Root ACL

Permission           ACL
├─ name            ├─ hasPermission2() ──────────▶     boolean
├─ impliedBy       │
└─ ...             └─ checkPermission() ─────────▶     void or Exception
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AuthorizationStrategy.java | `core/src/main/java/hudson/security/AuthorizationStrategy.java` | ソース | 認可戦略抽象基底クラス |
| ACL.java | `core/src/main/java/hudson/security/ACL.java` | ソース | アクセス制御リスト |
| Permission.java | `core/src/main/java/hudson/security/Permission.java` | ソース | 権限定義 |
| PermissionGroup.java | `core/src/main/java/hudson/security/PermissionGroup.java` | ソース | 権限グループ |
| AccessControlled.java | `core/src/main/java/hudson/security/AccessControlled.java` | ソース | アクセス制御対象インターフェース |
| AccessDeniedException.java | `org.springframework.security.access` | 外部 | アクセス拒否例外 |
