# セキュリティ設計書

## 概要

本ドキュメントは、InvenTree モバイルアプリケーション（Flutter製）のセキュリティ設計について記載する。本アプリはInvenTree在庫管理サーバーのクライアントアプリケーションであり、REST APIを介してサーバーと通信する。

## 認証設計

### 認証方式

本アプリケーションは**トークンベース認証**を採用している。

| 項目 | 内容 |
| --- | --- |
| 認証方式 | Token Authentication（InvenTree API Token） |
| 初期認証 | ユーザー名・パスワードによるBasic認証でトークン取得 |
| トークン取得エンドポイント | `user/token/` |
| 認証ヘッダー形式 | `Authorization: Token {token}` |

**認証フロー:**
1. ユーザーがサーバーURL、ユーザー名、パスワードを入力
2. `fetchToken()` メソッドでBasic認証ヘッダー（`Basic base64(username:password)`）を使用してトークンを要求
3. サーバーから返されたトークンをユーザープロファイルに保存
4. 以降のAPI呼び出しでは `Token {token}` ヘッダーを使用

### セッション管理

| 項目 | 設定値 | 備考 |
| --- | --- | --- |
| セッション有効期限 | サーバー側で管理 | クライアント側での有効期限管理なし |
| トークン無効化対策 | 認証失敗時にトークンをクリア | `_checkAuth()` で401/403時にトークン削除 |
| 自動再接続 | なし | ユーザーが手動で再認証が必要 |

## 認可設計

### 権限体系

本アプリケーションはサーバー側のRole-Based Access Control (RBAC) を利用している。

| 項目 | 説明 |
| --- | --- |
| 権限取得エンドポイント | `user/roles/` |
| 権限チェック方式 | `checkRole(role, permission)` メソッド |

**主要な権限モデル:**

| ロール | 権限タイプ | 説明 |
| --- | --- | --- |
| part | view, add, change, delete | 部品管理 |
| stock | view, add, change, delete | 在庫管理 |
| purchase_order | view, add, change, delete | 発注管理 |
| sales_order | view, add, change, delete | 受注管理 |

### アクセス制御

クライアント側でのアクセス制御は以下の方法で実装されている:

1. **UIレベル制御**: `canEdit`, `canCreate`, `canDelete`, `canView` プロパティによる画面要素の表示/非表示制御
2. **APIレベル制御**: サーバー側で403エラーを返却、クライアントはエラーメッセージを表示

```dart
// 権限チェックの例
bool get canEdit {
  for (String role in rolesRequired) {
    if (InvenTreeAPI().checkRole(role, "change")) {
      return true;
    }
  }
  return false;
}
```

## 通信セキュリティ

| 項目 | 対策 |
| --- | --- |
| HTTPS | 標準でHTTPS通信をサポート |
| Strict HTTPS | `INV_STRICT_HTTPS` 設定による証明書検証の強制オプション |
| 自己署名証明書 | Strict HTTPSが無効の場合、自己署名証明書を許容（`badCertificateCallback`） |
| 接続タイムアウト | 30秒（HttpClient.connectionTimeout） |
| リクエストタイムアウト | 10秒（API呼び出し時） |

**証明書検証の実装:**
```dart
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
  if (strictHttps) {
    showServerError(url, L10().serverCertificateError, L10().serverCertificateInvalid);
    return false;
  }
  // Strict HTTPs not enforced, so we'll ignore the bad cert
  return true;
};
```

## データセキュリティ

### 暗号化

| 対象 | 暗号化方式 |
| --- | --- |
| 通信 | HTTPS（TLS）によるトランスポート層暗号化 |
| 保存データ（トークン） | 暗号化なし（sembastデータベースに平文保存） |
| 保存データ（設定） | 暗号化なし（sembastデータベースに平文保存） |

### 機密情報管理

| 項目 | 保存場所 | 保護状態 |
| --- | --- | --- |
| APIトークン | sembast DB（`profiles` store） | 平文保存 |
| サーバーURL | sembast DB（`profiles` store） | 平文保存 |
| ユーザー設定 | sembast DB（`settings` store） | 平文保存 |
| パスワード | 保存しない | 認証時のみメモリ上で使用 |

**注意事項:**
- パスワードはトークン取得後に破棄され、ローカルには保存されない
- トークンはアプリケーションドキュメントディレクトリ（`getApplicationDocumentsDirectory()`）内のsembastデータベースに保存される
- OS標準のセキュアストレージ（Keychain/Keystore）は使用されていない

## 入出力対策

| 脅威 | 対策 |
| --- | --- |
| XSS | クライアントアプリのため、サーバー側で対策（クライアントはFlutter UIで描画） |
| SQLインジェクション | NoSQL（sembast）使用、サーバー側で対策 |
| CSRF | トークンベース認証のため該当なし |
| 入力検証 | フォームバリデーション（`validator` プロパティ） |
| JSONパース | `json.decode()` 使用、FormatException処理実装 |

**入力検証の実装例:**
```dart
validator: (value) {
  if (required && (value == null || value.isEmpty)) {
    return L10().valueCannotBeEmpty;
  }
  return null;
}
```

## 監査ログ

| ログ種別 | 記録内容 | 保持期間 |
| --- | --- | --- |
| エラーログ | サーバーエラー、例外情報 | セッション中のみ |
| Sentryレポート | エラー情報、デバイス情報、アプリ情報 | Sentryサーバーで管理 |
| APIレスポンスエラー | ステータスコード、エラーメッセージ | セッション中のみ |

**Sentryによるエラー報告:**
- `INV_REPORT_ERRORS` 設定でユーザーが有効/無効を制御可能
- URLからサーバーアドレスを除去し、パスとクエリパラメータのみ送信（プライバシー保護）
- デバッグモードでは送信しない

```dart
// URL情報のサニタイズ
if (context.containsKey("url")) {
  final String url = context["url"] ?? "";
  final uri = Uri.parse(url);
  context["url"] = uri.path + "?" + uri.query;
}
```

## セキュリティ設定一覧

| 設定キー | デフォルト値 | 説明 |
| --- | --- | --- |
| `INV_STRICT_HTTPS` | false | HTTPS証明書の厳格な検証を有効化 |
| `INV_REPORT_ERRORS` | true | Sentryへのエラーレポート送信 |

## 備考

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

1. **トークンの平文保存**: APIトークンがsembastデータベースに平文で保存されている。セキュアストレージ（flutter_secure_storage等）の使用を推奨。

2. **自己署名証明書の許容**: デフォルトで自己署名証明書を許容する設定となっている。本番環境では`Strict HTTPS`を有効化することを推奨。

3. **通知タイマー**: 60秒間隔で通知をポーリングしており、バックグラウンドでの通信が発生する。

4. **キャッシュ管理**: 画像キャッシュにおいても認証ヘッダーが付与され、キャッシュマネージャーで管理されている。

### 依存ライブラリのセキュリティ

| ライブラリ | 用途 | セキュリティ関連 |
| --- | --- | --- |
| http | HTTP通信 | HTTPS通信の基盤 |
| sembast | ローカルデータ保存 | 平文保存（暗号化なし） |
| sentry_flutter | エラー報告 | リモートサーバーへのデータ送信 |
| cached_network_image | 画像キャッシュ | 認証ヘッダー付きリクエスト |
