# 機能設計書 139-監査イベント

## 概要

本ドキュメントは、GitLabにおける監査イベント機能の設計について記述する。ユーザーや管理者によるシステム操作を記録し、コンプライアンスやセキュリティ監査を支援する機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：企業のガバナンス、リスク管理、コンプライアンス（GRC）要件を満たすため、システム内で行われる重要な操作を追跡可能な形で記録する必要がある。監査イベント機能により、誰が、いつ、何を、どのように変更したかを記録し、セキュリティインシデントの調査や規制対応を可能にする。

**機能の利用シーン**：
- ユーザー認証（ログイン/ログアウト）の追跡
- プロジェクト/グループ設定変更の記録
- メンバー権限変更の追跡
- 機密情報へのアクセス記録
- セキュリティポリシー変更の監査
- APIアクセスの追跡

**主要な処理内容**：
1. 監査対象イベントの検知
2. 監査イベントの構築（author, scope, target, message）
3. データベースへの永続化
4. ファイルへのログ出力
5. 外部ストリームへの配信（EE機能）

**関連システム・外部連携**：
- データベース（月次パーティショニング）
- ファイルログ（JSON形式）
- 外部監査ログ配信（EE: HTTP/Google Cloud等）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 80 | 監査ログ | 主機能 | 監査ログの表示 |
| 81 | セキュリティダッシュボード | 補助機能 | セキュリティイベントの表示 |

## 機能種別

ログ記録 / コンプライアンス / セキュリティ追跡 / 監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| author | User/String | Yes | イベント実行者 | - |
| scope | User/Project/Group | Yes | 監査スコープ | validate_scope! |
| target | Object | Yes | 監査対象オブジェクト | - |
| message | String | Yes | イベント説明 | - |
| additional_details | Hash | No | 追加詳細情報 | - |
| ip_address | String | No | クライアントIPアドレス | ip_address検証 |

### 入力データソース

- 各種サービス/コントローラーからの監査呼び出し
- 認証イベントからのトリガー

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | 監査イベントID |
| author_id | Integer | 実行者ID |
| author_name | String | 実行者名 |
| entity_id | Integer | スコープID |
| entity_type | String | スコープタイプ |
| entity_path | String | エンティティパス |
| target_id | Integer | ターゲットID |
| target_type | String | ターゲットタイプ |
| target_details | String | ターゲット詳細 |
| details | JSON | 詳細情報 |
| ip_address | String | IPアドレス |
| created_at | DateTime | 作成日時 |

### 出力先

- audit_eventsテーブル（月次パーティショニング）
- JSONログファイル
- 外部ストリーム（EE機能）

## 処理フロー

### 処理シーケンス

```
1. 監査対象イベント発生
   └─ Gitlab::Audit::Auditor.auditが呼ばれる
2. イベントタイプ検証
   └─ YAML定義ファイルの存在確認
3. イベント構築
   └─ AuditEvents::BuildServiceでイベント生成
4. データベース永続化
   └─ AuditEvent.save!またはbulk_insert!
5. ファイルログ出力
   └─ Gitlab::AuditJsonLogger経由
6. ストリーム配信（EE）
   └─ 外部宛先への送信
```

### フローチャート

```mermaid
flowchart TD
    A[監査対象イベント発生] --> B[Gitlab::Audit::Auditor.audit]
    B --> C{YAML定義存在?}
    C -->|No| D[StandardError発生]
    C -->|Yes| E{ブロック指定?}
    E -->|Yes| F[multiple_audit]
    E -->|No| G[single_audit]
    F --> H[イベント構築]
    G --> H
    H --> I{stream_only?}
    I -->|Yes| J[send_to_stream]
    I -->|No| K[log_events_and_stream]
    K --> L[log_authentication_event]
    L --> M[log_to_database]
    M --> N[log_to_new_tables]
    N --> O[log_to_file]
    O --> J
    J --> P[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-139-01 | YAML定義必須 | 監査イベントはYAML定義ファイルが必須 | イベント作成時 |
| BR-139-02 | スコープ検証 | User/Project/Groupのみスコープとして有効 | イベント作成時 |
| BR-139-03 | 読取専用スキップ | データベースが読取専用の場合はDB保存をスキップ | DB保存時 |
| BR-139-04 | 月次パーティション | audit_eventsテーブルは月次でパーティション分割 | DB設計 |
| BR-139-05 | 並列永続化 | 一部カラムはdetailsと同時に保存 | DB保存時 |

### 計算ロジック

- **Author種別**: User, ImpersonatedAuthor, UnauthenticatedAuthor(-1), DeployTokenAuthor(-2), DeployKeyAuthor(-3), DeletedAuthor, CiRunnerTokenAuthor
- **保存タイプ**: :database, :stream, :database_and_stream

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イベント作成 | audit_events | INSERT | 監査イベント保存 |
| 認証イベント作成 | authentication_events | INSERT | 認証イベント保存 |
| イベント取得 | audit_events | SELECT | 監査ログ表示 |

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

#### audit_events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | author_id, entity_id, entity_type, details, ip_address, created_at | イベント情報 | パーティションキー: created_at |
| SELECT | entity_type, entity_id, created_at | フィルタ条件 | id降順 |

#### authentication_events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id, user_name, ip_address, result, provider | 認証情報 | 成功時のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | StandardError | YAML定義ファイルがない | YAML定義ファイルを作成 |
| - | RecordInvalid | バリデーションエラー | ErrorTrackingでログ記録 |
| - | ArgumentError | 無効なスコープ | User/Project/Groupを指定 |

### リトライ仕様

- エラー発生時はErrorTrackingに記録
- 開発環境では例外を再raise

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

- 監査イベントは独立したトランザクションで保存
- メイン処理の成功/失敗に関わらず監査記録は保持

## パフォーマンス要件

- 月次パーティショニングによるクエリ最適化
- 単一イベントは直接save、複数イベントはbulk_insert
- BatchLoaderによる著者情報の遅延読み込み

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

- 監査ログは改ざん防止のため追記のみ
- IPアドレスの検証（ip_address: true）
- detailsのcustom_messageはサニタイズ
- センシティブ情報のマスキング

## 備考

- AuditEventServiceは非推奨、新規実装はGitlab::Audit::Auditorを使用
- EE機能では外部ストリーム配信が利用可能
- 監査イベントタイプはYAMLファイルで定義

---

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

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

### 推奨読解順序

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

監査イベントの中核となるモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | audit_event.rb | `app/models/audit_event.rb` | 監査イベントのデータ構造 |

**読解のコツ（audit_event.rb）**:
- **10-16行目**: PARALLEL_PERSISTENCE_COLUMNS - 並列永続化カラム
- **20行目**: partitioned_by :created_at, strategy: :monthly - 月次パーティション
- **22行目**: serialize :details, type: Hash - 詳細情報のシリアライズ
- **26-29行目**: バリデーション定義（author_id, entity_id, entity_type, ip_address）
- **31-35行目**: スコープ定義（by_entity_type, by_entity_id等）
- **67-69行目**: author_nameメソッド
- **77-87行目**: authorメソッドとlazy_author（BatchLoader）
- **109-115行目**: sanitize_messageメソッド - カスタムメッセージのサニタイズ
- **121-128行目**: parallel_persistメソッド - 並列永続化

#### Step 2: 監査サービスを理解する

新しい監査APIであるGitlab::Audit::Auditorを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | auditor.rb | `lib/gitlab/audit/auditor.rb` | 監査サービス本体 |

**読解のコツ（auditor.rb）**:
- **10-12行目**: PERMITTED_TARGET_CLASSES - 許可されたターゲットクラス
- **52-64行目**: audit静的メソッド - エントリーポイント
- **66-90行目**: initializeメソッド - コンテキスト検証
- **92-96行目**: single_auditメソッド
- **103-105行目**: recordメソッド - 記録処理の振り分け
- **107-117行目**: log_events_and_streamメソッド - メイン処理フロー
- **124-126行目**: audit_enabled?メソッド
- **144-151行目**: log_authentication_eventメソッド - 認証イベント記録
- **174-189行目**: build_eventメソッド - イベント構築
- **191-203行目**: log_to_databaseメソッド - DB永続化

#### Step 3: Author種別を理解する

様々な著者タイプの扱いを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | null_author.rb | `lib/gitlab/audit/null_author.rb` | Null著者パターン |

**読解のコツ（null_author.rb）**:
- **18-35行目**: forメソッド - 著者IDに基づく適切な著者クラスの選択
  - -1: UnauthenticatedAuthor
  - -2: DeployTokenAuthor
  - -3: DeployKeyAuthor
  - その他: DeletedAuthor

#### Step 4: 旧サービスを理解する（参考）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | audit_event_service.rb | `app/services/audit_event_service.rb` | 旧監査サービス（非推奨） |

**読解のコツ（audit_event_service.rb）**:
- **25-36行目**: initializeメソッド - パラメータ設定
- **43-54行目**: for_authenticationメソッド - 認証イベント設定
- **59-63行目**: security_eventメソッド - セキュリティイベント記録
- **74-81行目**: build_authorメソッド - 著者構築

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

```
Gitlab::Audit::Auditor.audit(context)
    │
    ├─ new(context)
    │      ├─ YAML定義チェック (Gitlab::Audit::Type::Definition.defined?)
    │      └─ validate_scope!
    │
    ├─ audit_enabled?
    │      ├─ authentication_event?
    │      └─ permitted_target?
    │
    ├─ single_audit / multiple_audit
    │      └─ build_event
    │             └─ AuditEvents::BuildService.execute
    │
    └─ record(events)
           │
           ├─ stream_only? → send_to_stream (EE)
           │
           └─ log_events_and_stream
                  │
                  ├─ log_authentication_event
                  │      └─ AuthenticationEvent.new.save!
                  │
                  ├─ log_to_database
                  │      ├─ AuditEvent.save! (単一)
                  │      └─ AuditEvent.bulk_insert! (複数)
                  │
                  ├─ log_to_new_tables
                  │
                  └─ log_to_file_and_stream
                         ├─ log_to_file
                         │      └─ Gitlab::AuditJsonLogger.build.info
                         │
                         └─ send_to_stream (EE)

AuditEvent (モデル)
    │
    ├─ partitioned_by :created_at, strategy: :monthly
    │
    ├─ author (BatchLoader経由)
    │      └─ lazy_author
    │             └─ NullAuthor.for (削除済み/未認証著者)
    │
    └─ parallel_persist (detailsとカラムの同期)
```

### データフロー図

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

監査対象操作 ────────────────▶ Gitlab::Audit::Auditor ───────▶ audit_events テーブル
(ログイン、設定変更等)              │                              │
                                   ▼                              ▼
                          YAML定義チェック              authentication_events
                                   │                    (認証イベントのみ)
                                   ▼                              │
                          AuditEvents::BuildService               ▼
                                   │                     JSONログファイル
                                   ▼                              │
                          AuditEvent生成                          ▼
                                   │                    外部ストリーム (EE)
                                   ▼
                          log_to_database
                          (save!/bulk_insert!)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| audit_event.rb | `app/models/audit_event.rb` | モデル | 監査イベントモデル |
| auditor.rb | `lib/gitlab/audit/auditor.rb` | サービス | 監査サービス本体 |
| audit_event_service.rb | `app/services/audit_event_service.rb` | サービス | 旧監査サービス（非推奨） |
| null_author.rb | `lib/gitlab/audit/null_author.rb` | ユーティリティ | Null著者パターン |
| unauthenticated_author.rb | `lib/gitlab/audit/unauthenticated_author.rb` | ユーティリティ | 未認証著者 |
| deleted_author.rb | `lib/gitlab/audit/deleted_author.rb` | ユーティリティ | 削除済み著者 |
| deploy_token_author.rb | `lib/gitlab/audit/deploy_token_author.rb` | ユーティリティ | デプロイトークン著者 |
| deploy_key_author.rb | `lib/gitlab/audit/deploy_key_author.rb` | ユーティリティ | デプロイキー著者 |
| scope_validation.rb | `lib/gitlab/audit/scope_validation.rb` | バリデーション | スコープ検証 |
| target.rb | `lib/gitlab/audit/target.rb` | ユーティリティ | ターゲット処理 |
| definition.rb | `lib/gitlab/audit/type/definition.rb` | 定義 | YAML定義管理 |
| build_service.rb | `app/services/audit_events/build_service.rb` | サービス | イベント構築 |
| audit_json_logger.rb | `lib/gitlab/audit_json_logger.rb` | ログ | JSONログ出力 |
