# 機能設計書 32-認証認可

## 概要

本ドキュメントは、SQLiteにおける認証/認可（Authorization）機能の設計仕様を定義する。sqlite3_set_authorizer() APIを通じて、SQL操作に対するアクセス制御を実現する機能である。

### 本機能の処理概要

認証/認可機能は、SQLステートメントのコンパイル（準備）時に呼び出されるコールバック関数を通じて、各SQL操作の許可/拒否を判定する機能である。

**業務上の目的・背景**：SQLiteは組み込みデータベースとして様々なアプリケーションで使用されるが、ユーザー入力に基づくSQL実行やプラグインからのデータベースアクセスにおいて、不正な操作を防止する必要がある。本機能により、アプリケーション開発者はテーブル単位、カラム単位でのアクセス制御ポリシーを実装でき、セキュリティを強化できる。

**機能の利用シーン**：
- ユーザー権限に応じた特定テーブルへのアクセス制限
- 機密カラム（パスワード、個人情報等）の読み取り制限
- 特定DDL操作（DROP TABLE等）の禁止
- SQLインジェクション攻撃の緩和策としての操作制限

**主要な処理内容**：
1. sqlite3_set_authorizer()でコールバック関数を登録
2. SQLコンパイル時、各操作（SELECT、INSERT、CREATE TABLE等）についてコールバックを呼び出し
3. コールバックの戻り値（SQLITE_OK/SQLITE_DENY/SQLITE_IGNORE）に基づき処理を制御
4. SQLITE_DENYの場合はコンパイルエラー、SQLITE_IGNOREの場合は該当部分をスキップ/NULL化

**関連システム・外部連携**：
- SQLパーサー/コンパイラー：認可チェックポイントの埋め込み
- VDBEコード生成：SQLITE_IGNORE時のNULL置換処理
- 外部キー制約：FK検証時の親テーブル読み取り認可

**権限による制御**：
- 本機能自体がアプリケーションレベルでの権限制御を実現する機構
- コールバック関数内でアプリケーション固有の権限ロジックを実装

## 関連画面

本機能はSQLite内部機能のため、直接的な画面関連はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

セキュリティ制御 / アクセス制御 / コールバック機構

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| db | sqlite3* | Yes | データベース接続ハンドル | NULLでないこと |
| xAuth | callback | No | 認可コールバック関数（NULLで無効化） | - |
| pArg | void* | No | コールバックに渡すユーザーデータ | - |

### コールバック関数の引数

| 引数位置 | 型 | 説明 |
|---------|-----|------|
| 第1引数 | void* | sqlite3_set_authorizer()で登録したpArg |
| 第2引数 | int | アクションコード（SQLITE_CREATE_TABLE等） |
| 第3引数 | const char* | アクション依存（テーブル名等） |
| 第4引数 | const char* | アクション依存（カラム名等） |
| 第5引数 | const char* | データベース名（"main"、"temp"等） |
| 第6引数 | const char* | 認可コンテキスト（トリガー名等） |

### 入力データソース

- SQLステートメント文字列（コンパイル対象）
- データベーススキーマ情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SQLITE_OK | int | 操作を許可 |
| SQLITE_DENY | int | 操作を拒否（エラー発生） |
| SQLITE_IGNORE | int | 操作を無視（NULL値として扱う等） |
| SQLITE_AUTH | int | 認可拒否時のエラーコード |

### 出力先

- 戻り値：コールバック関数の判定結果
- pParse->rc：認可拒否時のエラーコード
- pParse->zErrMsg：エラーメッセージ

## 処理フロー

### 処理シーケンス

```
1. sqlite3_set_authorizer()でコールバック登録
   └─ db->xAuth にコールバック関数ポインタを保存
   └─ 登録時に既存のプリペアドステートメントを無効化

2. SQLコンパイル時（sqlite3_prepare等）
   ├─ パース処理中に各操作を検出
   └─ 操作ごとにsqlite3AuthCheck()を呼び出し

3. sqlite3AuthCheck()の処理
   ├─ db->xAuthがNULLなら即座にSQLITE_OK
   ├─ データベース初期化中なら即座にSQLITE_OK
   └─ コールバック関数を呼び出し

4. コールバックの戻り値処理
   ├─ SQLITE_OK: 処理続行
   ├─ SQLITE_DENY: エラーメッセージ設定、コンパイル失敗
   └─ SQLITE_IGNORE: 操作スキップまたはNULL値使用

5. カラム読み取り時（sqlite3AuthRead）
   └─ SQLITE_IGNOREの場合、TK_COLUMNをTK_NULLに変換
```

### フローチャート

```mermaid
flowchart TD
    A[SQL実行開始] --> B[sqlite3_prepare]
    B --> C{xAuth登録済?}
    C -->|No| D[通常コンパイル]
    C -->|Yes| E[パース処理]
    E --> F[操作検出]
    F --> G[sqlite3AuthCheck呼び出し]
    G --> H{コールバック結果}
    H -->|SQLITE_OK| I[操作許可]
    H -->|SQLITE_DENY| J[エラー設定]
    H -->|SQLITE_IGNORE| K[操作スキップ/NULL化]
    I --> L{次の操作?}
    K --> L
    L -->|Yes| F
    L -->|No| M[コンパイル完了]
    J --> N[コンパイル失敗]
    D --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-1 | コンパイル時検証 | 認可チェックはSQLコンパイル時に実行される | すべてのSQL準備時 |
| BR-32-2 | 操作単位制御 | テーブル操作、カラム読み取り等の操作単位で認可判定 | xAuth登録時 |
| BR-32-3 | NULL置換 | SQLITE_IGNORE時、カラム値はNULLとして扱われる | SELECT時のSQLITE_IGNORE |
| BR-32-4 | コンテキスト伝播 | トリガー内での操作は元の認可コンテキストを引き継ぐ | トリガー実行時 |

### 計算ロジック

なし（判定ロジックはコールバック関数内でアプリケーション実装）

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

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

本機能自体はデータベースへの直接操作は行わない。認可判定の結果、SQLステートメントの実行可否が制御される。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 認可チェック | - | なし | メタデータのみ参照 |

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

なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_AUTH | 認可拒否 | コールバックがSQLITE_DENYを返却 | 権限のある操作に変更 |
| SQLITE_ERROR | 不正な戻り値 | コールバックが不正な値を返却 | コールバック実装の修正 |
| access to X.Y is prohibited | 認可拒否 | カラム読み取りがSQLITE_DENY | カラムへのアクセス権限を確認 |
| not authorized | 認可拒否 | 操作がSQLITE_DENY | 操作権限を確認 |
| authorizer malfunction | 内部エラー | コールバックが不正な値を返却 | コールバック実装の修正 |

### リトライ仕様

認可拒否はセキュリティポリシーに基づくものであり、自動リトライは行わない。

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

- 認可チェックはコンパイル時に実行されるため、トランザクション状態には依存しない
- ただし、トランザクション関連操作（BEGIN、COMMIT等）に対しても認可チェックは適用される

## パフォーマンス要件

- 認可チェックはSQLコンパイル時のみ実行され、実行時のオーバーヘッドはない
- コールバック関数の実装によりコンパイル時間が増加する可能性あり
- 頻繁に実行されるSQLはプリペアドステートメントとして再利用することで認可チェックを1回に抑制可能

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

- 本機能はアプリケーションレベルのアクセス制御機構であり、OSレベルのファイルアクセス制御とは独立
- コールバック関数内でのセキュリティ判定ロジックは慎重に実装する必要がある
- SQLITE_IGNOREを使用する場合、NULL値が予期せぬ動作を引き起こす可能性に注意
- 認可コールバックを設定すると、既存のプリペアドステートメントが自動的に無効化される（再コンパイルが必要）

## 備考

- SQLITE_OMIT_AUTHORIZATION でコンパイルした場合、本機能は無効
- sqlite3_declare_vtab()内での認可チェックは無効化される
- データベース初期化中（db->init.busy）の認可チェックは無効化される

---

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

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

### 推奨読解順序

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

認可機能の中核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sqliteInt.h | `src/sqliteInt.h` | sqlite3構造体のxAuth、pAuthArgメンバー |
| 1-2 | sqliteInt.h | `src/sqliteInt.h` | AuthContext構造体の定義 |

**読解のコツ**: sqlite3構造体のxAuthは認可コールバック関数ポインタ、pAuthArgはユーザーデータ。AuthContextはトリガー内での認可コンテキスト管理に使用。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | auth.c | `src/auth.c` | sqlite3_set_authorizer()関数 |

**主要処理フロー**:
1. **70-84行目**: sqlite3_set_authorizer()の実装
2. **78-79行目**: db->xAuthとdb->pAuthArgへの設定
3. **81行目**: 既存プリペアドステートメントの無効化

#### Step 3: 認可チェック処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | auth.c | `src/auth.c` | sqlite3AuthCheck()関数 |

**主要処理フロー**:
- **193-231行目**: 汎用認可チェック関数
- **207-209行目**: 初期化中やxAuth未設定時のスキップ
- **222行目**: コールバック関数の呼び出し
- **223-229行目**: 戻り値の処理（DENY/不正値）

#### Step 4: カラム読み取り認可を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | auth.c | `src/auth.c` | sqlite3AuthReadCol()、sqlite3AuthRead()関数 |

**主要処理フロー**:
- **104-125行目**: カラム読み取り認可チェック
- **115行目**: SQLITE_READアクションでコールバック呼び出し
- **116-120行目**: SQLITE_DENY時のエラーメッセージ生成
- **136-185行目**: TK_COLUMN式に対する認可チェックとNULL変換
- **182-184行目**: SQLITE_IGNORE時のTK_NULL変換

#### Step 5: 認可コンテキスト管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | auth.c | `src/auth.c` | sqlite3AuthContextPush()、sqlite3AuthContextPop()関数 |

**主要処理フロー**:
- **238-247行目**: 認可コンテキストのプッシュ（トリガー入口等）
- **253-258行目**: 認可コンテキストのポップ（トリガー出口等）

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

```
sqlite3_set_authorizer()
    │
    ├─ db->xAuth に関数ポインタを設定
    └─ sqlite3ExpirePreparedStatements() 既存ステートメント無効化

[SQLコンパイル時]
sqlite3_prepare_v2()
    │
    └─ sqlite3RunParser()
           │
           ├─ sqlite3AuthCheck()  ────▶ xAuth コールバック呼び出し
           │      └─ 各種SQL操作の認可判定
           │
           └─ sqlite3AuthRead()   ────▶ xAuth コールバック呼び出し
                  └─ カラム読み取りの認可判定
                  └─ SQLITE_IGNOREでTK_NULL変換

[トリガー処理時]
sqlite3CodeRowTrigger()
    │
    ├─ sqlite3AuthContextPush()  ────▶ コンテキスト保存
    │
    └─ sqlite3AuthContextPop()   ────▶ コンテキスト復元
```

### データフロー図

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

xAuth(コールバック) ──────▶ sqlite3_set_authorizer() ────▶ db->xAuth
pArg(ユーザーデータ)        コールバック登録                  db->pAuthArg

SQLステートメント ────────▶ sqlite3_prepare_v2() ─────────▶ sqlite3_stmt*
                           │                               または
                           └─ sqlite3AuthCheck() ─────────▶ SQLITE_AUTH
                              認可チェック                   (エラー)

TK_COLUMN式 ─────────────▶ sqlite3AuthRead() ────────────▶ TK_COLUMN
                           カラム認可                       または
                                                           TK_NULL
                                                           (SQLITE_IGNORE時)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| auth.c | `src/auth.c` | ソース | 認可機能のメイン実装 |
| sqliteInt.h | `src/sqliteInt.h` | ヘッダー | sqlite3構造体、AuthContext定義 |
| sqlite3.h | `src/sqlite3.h` | ヘッダー | 公開APIとアクションコード定義 |
| select.c | `src/select.c` | ソース | SELECT文コンパイル時の認可チェック呼び出し |
| insert.c | `src/insert.c` | ソース | INSERT文コンパイル時の認可チェック呼び出し |
| update.c | `src/update.c` | ソース | UPDATE文コンパイル時の認可チェック呼び出し |
| delete.c | `src/delete.c` | ソース | DELETE文コンパイル時の認可チェック呼び出し |
| build.c | `src/build.c` | ソース | DDL文コンパイル時の認可チェック呼び出し |
| trigger.c | `src/trigger.c` | ソース | トリガー認可コンテキスト管理 |
| prepare.c | `src/prepare.c` | ソース | プリペアドステートメント無効化処理 |
