# セキュリティ設計書

## 概要

本ドキュメントは、Windows Terminal プロジェクトにおけるセキュリティ設計を定義する。Windows Terminal は C++/WinRT で実装されたデスクトップアプリケーションであり、Azure Cloud Shell 接続機能、SSH接続機能、およびコンソールホスト機能を含む。本書では、認証・認可、通信セキュリティ、データ保護、入出力対策、監査ログの各領域におけるセキュリティ設計方針を記載する。

## 認証設計

### 認証方式

Windows Terminal は Azure Cloud Shell 接続において **OAuth 2.0 Device Authorization Grant（デバイスコードフロー）** を採用している。

**処理フロー:**

1. アプリケーションが Azure AD の `/devicecode` エンドポイントにリクエストを送信し、デバイスコードとユーザーコードを取得する
2. ユーザーは表示された URL（`https://microsoft.com/devicelogin`）にブラウザでアクセスし、ユーザーコードを入力して認証を完了する
3. アプリケーションは `/token` エンドポイントをポーリングし、認証完了後にアクセストークンとリフレッシュトークンを取得する
4. 取得したアクセストークンは `Bearer` スキームで HTTP Authorization ヘッダーに設定される

**実装箇所:**
- `src/cascadia/TerminalConnection/AzureConnection.cpp` — `_RunDeviceFlowState()` (行 611-658)
- トークン設定: `_setAccessToken()` (行 855-859)
- トークン更新: `_RefreshTokens()` (行 953-970)

**SSH接続:**
- システムにインストールされた OpenSSH クライアントを利用する
- SSH ホスト設定は `~/.ssh/config` を解析して自動検出する（`src/cascadia/TerminalSettingsModel/SshHostGenerator.cpp`）

### セッション管理

| 項目 | 設定値 | 備考 |
| --- | --- | --- |
| トークン有効期限猶予 | 2700秒（45分） | `_expireLimit` 定数で定義。有効期限の45分前にリフレッシュを試行 |
| セッションID管理 | GUID（自動生成） | `Utils::CreateGuid()` で生成。設定から `sessionId` を取得、未設定時は新規生成 |
| リフレッシュトークン | OAuth 2.0 `refresh_token` grant type | `_RefreshTokens()` でアクセストークンの自動更新を実施 |
| 資格情報永続化 | Windows Credential Manager | `PasswordVault` API を使用。テナント情報とリフレッシュトークンを安全に保存 |

## 認可設計

### 権限体系

| ロール | 権限 | 説明 |
| --- | --- | --- |
| Azure テナントユーザー | Cloud Shell アクセス | Azure AD 認証済みユーザーが対象テナントの Cloud Shell に接続可能 |
| コンソールクライアントプロセス | 出力バッファ読取 / 入力バッファ書込 | `ConsoleProcessPolicy` により AppModel ポリシーおよび Integrity Level に基づいて制御 |
| 管理者（Elevated） | 設定ファイル書込 | High Integrity Level で実行時、SDDL によるファイルアクセス制御が適用 |

### アクセス制御

**プロセスレベルのアクセス制御:**

Windows Terminal のコンソールホストは、接続プロセスに対して以下の多層的なアクセス制御を実施する。

1. **AppModel ポリシーチェック**: UWP/MSIX パッケージモデルに基づくアクセス可否判定（`ProcessPolicy::CheckAppModelPolicy`）
2. **Integrity Level ポリシーチェック**: Windows Mandatory Integrity Control（MIC）に基づくプロセス信頼レベル検証（`ProcessPolicy::CheckIntegrityLevelPolicy`）
3. **ハンドルベースのアクセス制御**: コンソール API の各操作に対して、要求されたアクセス権（読取/書込）がハンドルに付与された権限に含まれるかを検証し、不足時は `E_ACCESSDENIED` を返却

**実装箇所:**
- `src/server/ProcessPolicy.h` / `ProcessPolicy.cpp` — ポリシーチェックフレームワーク
- `src/server/ObjectHandle.cpp` (行 149, 169) — `RETURN_HR_IF(E_ACCESSDENIED, ...)`

## 通信セキュリティ

| 項目 | 対策 |
| --- | --- |
| HTTPS | Azure Cloud Shell への全通信は HTTPS（ポート443）を強制使用。`WinHttpConnect` に `INTERNET_DEFAULT_HTTPS_PORT` を指定し、`WinHttpOpenRequest` に `WINHTTP_FLAG_SECURE` フラグを設定 |
| WebSocket Secure (WSS) | Cloud Shell のターミナルセッションは HTTPS 接続をアップグレードした WSS で通信。`WinHttpSetOption` で `WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET` を設定 |
| HSTS | クライアントアプリケーションのため直接的な HSTS ヘッダー実装はなし。接続先 Azure サービス側で HSTS が有効 |
| TLS | WinHTTP ライブラリのデフォルト設定に依存。OS の TLS 設定（TLS 1.2 以上）が適用される |

**実装箇所:**
- `src/cascadia/TerminalConnection/AzureConnection.cpp` (行 790-801)

## データセキュリティ

### 暗号化

| 対象 | 暗号化方式 |
| --- | --- |
| 通信 | TLS（WinHTTP ライブラリ経由、OS の暗号化スイート設定に準拠） |
| 保存データ（資格情報） | Windows DPAPI（Data Protection API）。`PasswordVault` API を通じて OS レベルの暗号化が適用される |
| トークン（メモリ上） | `winrt::hstring` による管理。スコープ終了時に自動破棄されるが、明示的なメモリワイプは未実装 |

### 機密情報管理

**資格情報の安全な保存:**

Azure 接続のリフレッシュトークンおよびテナント情報は、Windows Credential Manager（`PasswordVault`）に保存される。

- **リソース名**: `"Terminal"` として一元管理
- **バージョン管理**: `CurrentCredentialVersion = 2` により、古い形式の資格情報は自動的に削除・移行される
- **ユーザー名フィールド**: テナント情報を JSON 形式で格納（テナントID、表示名、デフォルトドメイン、バージョン番号）
- **パスワードフィールド**: リフレッシュトークンを格納

**環境変数による設定管理:**
- `WT_SETTINGS_DIR` 環境変数で設定ディレクトリを指定
- `.env` ファイルは使用しない

**実装箇所:**
- `src/cascadia/TerminalConnection/AzureConnection.cpp` (行 467, 494-500, 1077-1079)

## 入出力対策

| 脅威 | 対策 |
| --- | --- |
| XSS | デスクトップアプリケーションであるため、Web ベースの XSS リスクは該当しない。ターミナル出力は ANSI エスケープシーケンスで制御し、任意のスクリプト実行は不可 |
| SQLインジェクション | データベースを使用しないため該当なし |
| CSRF | Azure Device Code Flow を採用しており、ブラウザベースのセッション Cookie を使用しないため、CSRF リスクは設計上緩和されている |
| コマンドインジェクション | コマンドライン引数のエスケープ処理を実装。`QuoteAndEscapeCommandlineArg()` により、バックスラッシュ・セミコロン・ダブルクォートを適切にエスケープ |
| 入力境界チェック | Azure テナント選択時のインデックス範囲検証を実施。範囲外入力時はエラーメッセージを表示して再入力を促す |
| JSON パースエラー | `JsonObject::Parse` による安全な JSON 解析。キー存在チェック（`HasKey`）を実施し、不正データによる例外を防止 |

**実装箇所:**
- コマンドラインエスケープ: `src/cascadia/WinRTUtils/inc/WtExeUtils.h` (行 123-147)
- テナント選択検証: `src/cascadia/TerminalConnection/AzureConnection.cpp` (行 683-690)

## 監査ログ

| ログ種別 | 記録内容 | 保持期間 |
| --- | --- | --- |
| TraceLogging（ETW） | アプリケーションイベント、接続状態変化、エラー発生。`g_hTerminalConnectionProvider` プロバイダを通じて Windows イベントトレーシングに記録 | OS の ETW 設定に準拠 |
| 例外ログ | `LOG_CAUGHT_EXCEPTION()` / `CATCH_LOG()` マクロにより、捕捉された例外を WIL（Windows Implementation Library）のログ基盤に記録 | アプリケーションセッション中 |
| スレッド記述 | デバッグ用途で各スレッドに説明文字列を設定（`SetThreadDescription`）。障害調査時のスレッド識別に活用 | プロセスライフタイム中 |

**実装箇所:**
- TraceLogging 宣言: `src/cascadia/TerminalConnection/pch.h` (行 35-36)
- 例外ログ: `src/cascadia/TerminalConnection/AzureConnection.cpp` (行 125, 273, 507, 1106)

## ファイルアクセス保護

### Mandatory Integrity Label (MIL)

管理者権限（Elevated）で実行時、設定ファイルの作成に SDDL（Security Descriptor Definition Language）ベースの整合性ラベルを適用する。

| SDDL 文字列 | 意味 | 適用箇所 |
| --- | --- | --- |
| `S:(ML;;NW;;;HI)` | High Integrity Level、No Write Up | 一般的な設定ファイル保護 |
| `S:(ML;;NRNW;;;HI)` | High Integrity Level、No Read/Write Up | 機密性の高い設定ファイル保護 |

低い Integrity Level のプロセスからの書込み（および必要に応じて読取り）を防止し、設定ファイルの改ざんを防ぐ。

**実装箇所:**
- `src/inc/til/io.h` (行 171-189)
- `src/cascadia/WindowsTerminal/WindowEmperor.cpp` (行 1120-1128)

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

| ライブラリ | バージョン | 用途 |
| --- | --- | --- |
| fmt | 11.1.4 | 文字列フォーマット |
| ms-gsl | 3.1.0 | Guidelines Support Library（安全なコーディング支援） |
| jsoncpp | 1.9.5 | JSON パース |
| cli11 | 2.4.2 | コマンドライン引数パース |
| cmark | 0.30.3 | Markdown パース |

依存関係は `vcpkg.json` で管理されており、バージョン固定による再現性を確保している。

## 備考

- Windows Terminal はデスクトップアプリケーションであるため、Web アプリケーション固有のセキュリティ対策（CORS、CSP、Cookie セキュリティ等）は設計上不要である
- 暗号化処理は Windows OS の標準 API（DPAPI、WinHTTP の TLS、Credential Manager）に委譲しており、アプリケーション独自の暗号化実装は持たない
- Azure 接続機能は `AzureConnection` クラスに集約されており、セキュリティ境界が明確に定義されている
- SSH 接続はシステムインストール済みの OpenSSH クライアントに委譲しており、鍵管理・暗号化は OpenSSH の実装に依存する
