# 機能設計書 140-監査ログ表示

## 概要

本ドキュメントは、GitLabにおける監査ログ表示機能の設計について記述する。記録された監査イベントをユーザーインターフェースやAPI経由で閲覧・検索し、コンプライアンス監査やセキュリティ調査を支援する機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：セキュリティ監査やコンプライアンス対応において、過去に発生したイベントを効率的に検索・閲覧できることが重要である。監査ログ表示機能により、管理者やセキュリティ担当者が必要な情報を迅速に取得し、インシデント調査や規制対応を行うことができる。

**機能の利用シーン**：
- セキュリティインシデント発生時の調査
- コンプライアンス監査への対応
- 不正アクセスの検出と追跡
- 設定変更履歴の確認
- ユーザー行動の監視
- 定期的なセキュリティレビュー

**主要な処理内容**：
1. 監査イベントの一覧表示
2. フィルタリング（日付、エンティティ、著者等）
3. ページネーション
4. 詳細情報の表示
5. CSV/JSONエクスポート（EE機能）

**関連システム・外部連携**：
- GraphQL API
- REST API
- Webインターフェース

**権限による制御**：
- インスタンスレベル：管理者のみ閲覧可能
- グループレベル：グループオーナーのみ閲覧可能
- プロジェクトレベル：プロジェクトメンテナー以上が閲覧可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 80 | 監査ログ | 主機能 | 監査ログの表示・検索 |
| 141 | グループ詳細 | 補助機能 | グループ監査ログへのアクセス |
| 24 | プロジェクト詳細 | 補助機能 | プロジェクト監査ログへのアクセス |
| 119 | 管理者ダッシュボード | 補助機能 | インスタンス監査ログへのアクセス |

## 機能種別

データ表示 / 検索・フィルタリング / ページネーション / エクスポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| entity_type | String | No | エンティティタイプ | User/Project/Group |
| entity_id | Integer | No | エンティティID | - |
| author_id | Integer | No | 著者ID | - |
| created_after | DateTime | No | 開始日時 | - |
| created_before | DateTime | No | 終了日時 | - |
| sort | String | No | ソート順 | created_asc/created_desc |
| page | Integer | No | ページ番号 | デフォルト: 1 |
| per_page | Integer | No | 1ページあたり件数 | デフォルト: 25, 最大: 100 |

### 入力データソース

- GraphQL クエリ
- REST API リクエスト
- Web UIフィルタ設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | 監査イベントID |
| created_at | DateTime | 作成日時 |
| author | Object | 実行者情報 |
| event_name | String | イベント名 |
| details | JSON | 詳細情報 |
| target_type | String | ターゲットタイプ |
| target_details | String | ターゲット詳細 |
| target_id | Integer | ターゲットID |
| ip_address | String | IPアドレス |
| entity_path | String | エンティティパス |
| entity_id | Integer | エンティティID |
| entity_type | String | エンティティタイプ |
| project | Object | 関連プロジェクト |
| group | Object | 関連グループ |
| user | Object | 関連ユーザー |

### 出力先

- Web UIでの一覧表示
- GraphQL APIレスポンス
- REST APIレスポンス
- CSV/JSONエクスポートファイル（EE機能）

## 処理フロー

### 処理シーケンス

```
1. 監査ログ閲覧リクエスト受信
   └─ 権限チェック実行
2. クエリパラメータ解析
   └─ フィルタ条件、ページネーション情報を取得
3. データベースクエリ実行
   └─ AuditEventモデルからデータ取得
4. データ整形
   └─ GraphQL Type / Serializerで変換
5. レスポンス返却
```

### フローチャート

```mermaid
flowchart TD
    A[監査ログ閲覧リクエスト] --> B{権限チェック}
    B -->|OK| C[クエリパラメータ解析]
    B -->|NG| D[403 Forbidden]
    C --> E[フィルタ条件構築]
    E --> F[AuditEvent.where]
    F --> G{entity_type指定?}
    G -->|Yes| H[by_entity_type]
    G -->|No| I[全エンティティ]
    H --> J{author_id指定?}
    I --> J
    J -->|Yes| K[by_author_id]
    J -->|No| L[全著者]
    K --> M[日付フィルタ]
    L --> M
    M --> N[ソート適用]
    N --> O[ページネーション]
    O --> P[GraphQL Type変換]
    P --> Q[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-140-01 | 権限制御 | スコープに応じた閲覧権限チェック | 全クエリ |
| BR-140-02 | デフォルトソート | 作成日時降順でソート | ソート未指定時 |
| BR-140-03 | ページサイズ制限 | 最大100件/ページ | ページネーション |
| BR-140-04 | Keysetページネーション | 大量データ対応のKeysetページネーション | APIクエリ |
| BR-140-05 | 日付範囲制限 | パーティションを考慮した日付フィルタ推奨 | クエリ最適化 |

### 計算ロジック

- **ソート順**: id:asc / id:desc（Keysetページネーション対応）
- **デフォルト件数**: 25件/ページ
- **最大件数**: 100件/ページ

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イベント取得 | audit_events | SELECT | 監査ログ取得 |
| 著者情報取得 | users | SELECT | BatchLoader経由 |

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

#### audit_events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | entity_type, entity_id, author_id, created_at | フィルタ条件 | インデックス利用 |
| SELECT | * | id降順 | Keysetページネーション |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | Unauthorized | 未認証 | ログインが必要 |
| 403 | Forbidden | 権限なし | 適切な権限を取得 |
| 422 | Unprocessable | 不正なパラメータ | パラメータを修正 |

### リトライ仕様

該当なし（読み取り専用操作）

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

- 読み取り専用のためトランザクション不要
- BatchLoaderによる効率的なN+1クエリ回避

## パフォーマンス要件

- 監査ログ一覧取得は25件で200ms以内
- 月次パーティションを活用した効率的なクエリ
- Keysetページネーションによる大量データ対応

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

- 閲覧権限の厳格なチェック
- センシティブ情報のマスキング
- IPアドレス情報の適切な表示制御

## 備考

- EE機能ではCSV/JSONエクスポートが利用可能
- 月次パーティションを考慮した日付フィルタ推奨
- BatchLoaderによるN+1クエリ回避

---

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

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

### 推奨読解順序

#### Step 1: データモデルを理解する

監査イベントのデータ構造は139-監査イベントで説明済みのため、表示に関連する部分に焦点を当てる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | audit_event.rb | `app/models/audit_event.rb` | スコープとソート定義 |

**読解のコツ（audit_event.rb）**:
- **31-35行目**: スコープ定義（by_entity_type, by_entity_id, by_author_id等）
- **48-50行目**: supported_keyset_orderings - Keysetページネーション対応
- **52-59行目**: order_byメソッド - ソート処理
- **77-87行目**: authorメソッドとBatchLoader - N+1クエリ回避
- **89-93行目**: as_jsonメソッド - JSON変換

#### Step 2: GraphQL APIを理解する

GraphQL経由での監査ログ取得を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | audit_event_type.rb | `app/graphql/types/audit_events/audit_event_type.rb` | GraphQL型定義 |

**読解のコツ（audit_event_type.rb）**:
- **10-11行目**: id フィールド
- **13-14行目**: created_at フィールド
- **16-17行目**: author フィールド - ユーザー情報
- **19-20行目**: event_name フィールド - イベント名
- **22-23行目**: details フィールド - 詳細情報（JSON文字列）
- **25-29行目**: target_type, target_details, target_id フィールド
- **34-35行目**: ip_address フィールド
- **37-44行目**: entity_path, entity_id, entity_type フィールド
- **46-53行目**: project, group, user フィールド - 関連オブジェクト
- **55-59行目**: detailsメソッド - Hash to JSON変換

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

```
GraphQL Query / REST API
    │
    ├─ 権限チェック
    │      ├─ インスタンスレベル: admin?
    │      ├─ グループレベル: owner?
    │      └─ プロジェクトレベル: maintainer?
    │
    ├─ AuditEventsFinder (EE) / AuditEvent直接クエリ
    │      │
    │      ├─ スコープ適用
    │      │      ├─ by_entity_type
    │      │      ├─ by_entity_id
    │      │      ├─ by_author_id
    │      │      └─ created_at範囲
    │      │
    │      ├─ ソート適用
    │      │      └─ order_by (id:desc/id:asc)
    │      │
    │      └─ ページネーション
    │             └─ Keyset Pagination
    │
    └─ レスポンス変換
           │
           ├─ GraphQL: AuditEventType
           │      ├─ author (BatchLoader)
           │      ├─ details (to_json)
           │      ├─ project / group / user
           │      └─ その他フィールド
           │
           └─ REST: AuditEventSerializer

AuditEvent (モデル)
    │
    ├─ author (BatchLoader)
    │      └─ User.select(:id, :name, :username, :email)
    │
    ├─ as_json
    │      └─ ip_address.to_s
    │
    └─ formatted_details
           └─ details + author_email
```

### データフロー図

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

閲覧リクエスト ──────────────▶ 権限チェック ───────────────▶ audit_events SELECT
(GraphQL/REST/Web)                │                              │
                                   ▼                              ▼
                          パラメータ解析              BatchLoader (author)
                          (filters, sort, page)           │
                                   │                       ▼
                                   ▼                  AuditEventType
                          AuditEvent.where                 │
                                   │                       ▼
                                   ▼                  JSON/HTML レスポンス
                          order_by
                                   │
                                   ▼
                          Keyset Pagination
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| audit_event.rb | `app/models/audit_event.rb` | モデル | 監査イベントモデル |
| audit_event_type.rb | `app/graphql/types/audit_events/audit_event_type.rb` | GraphQL型 | 監査イベント型 |
| definition_type.rb | `app/graphql/types/audit_events/definition_type.rb` | GraphQL型 | 監査イベント定義型 |
| query_type.rb | `app/graphql/types/query_type.rb` | GraphQL型 | ルートクエリ |
| audit_json_logger.rb | `lib/gitlab/audit_json_logger.rb` | ログ | JSONログ |
| null_author.rb | `lib/gitlab/audit/null_author.rb` | ユーティリティ | Null著者 |

### 補足: GraphQL AuditEventType フィールド一覧

| フィールド | 型 | 説明 |
|-----------|-----|------|
| id | ID! | 監査イベントID |
| created_at | Time! | 作成日時 |
| author | User | 実行者 |
| event_name | String | イベント名 |
| details | String | 詳細情報（JSON文字列） |
| target_type | String | ターゲットタイプ |
| target_details | String | ターゲット詳細 |
| target_id | ID | ターゲットID |
| ip_address | String | IPアドレス |
| entity_path | String | エンティティパス |
| entity_id | ID | エンティティID |
| entity_type | String | エンティティタイプ |
| project | Project | 関連プロジェクト |
| group | Group | 関連グループ |
| user | User | 関連ユーザー |
