# 機能設計書 564-Get-DbaUserPermission

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるGet-DbaUserPermissionコマンドレットの機能設計を定義する。本機能は、DISA STIG（国防情報システム局セキュリティ技術実装ガイド）方法論に基づき、SQL Serverインスタンス全体のセキュリティ権限を包括的に監査する高度なセキュリティ分析機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：政府機関や規制産業では、DISA STIGに準拠したセキュリティ監査が要求される。本機能は、サーバーログイン、サーバーレベル権限、データベースユーザー、データベースロール、オブジェクトレベル権限を一括で分析し、直接付与された権限と継承された権限の両方を可視化する。これにより、セキュリティコンプライアンスの証跡取得、アクセスレビュー、監査報告書作成が効率化される。

**機能の利用シーン**：
- DISA STIG準拠のセキュリティ監査レポート作成
- 年次/四半期ごとのアクセス権限レビュー
- セキュリティインシデント発生時の権限状況調査
- 新規システム導入時のセキュリティベースライン確認
- 規制対応（SOX、HIPAA、PCI-DSS等）のためのエビデンス収集

**主要な処理内容**：
1. SQL Serverインスタンスへの接続確立（SQL Server 2008以降、Azure非対応）
2. tempdbにSTIGスキーマとビュー/関数を一時作成
3. masterデータベースを対象にサーバーレベル権限を取得
4. 各データベースについてSTIGオブジェクトを再作成し権限分析
5. サーバーログイン、サーバーセキュラブル、DBロールメンバー、DBセキュラブルを出力
6. 処理完了後、STIGスキーマを削除してクリーンアップ

**関連システム・外部連携**：
- bin/stig.sqlスクリプトを使用（DISA提供の権限分析スクリプト）
- tempdbにSTIGスキーマを一時作成
- Invoke-DbaQueryを使用したクエリ実行

**権限による制御**：
- 対象インスタンスへの接続権限が必要
- tempdbへのCREATE SCHEMA、CREATE FUNCTION、CREATE VIEW権限が必要
- 各データベースへのSELECT権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 71 | 権限取得 | 補助機能 | ユーザー権限の監査 |

## 機能種別

データ取得（SELECT）/ セキュリティ監査 / DISA STIG準拠

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可 |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証対応 |
| Database | object[] | No | 対象データベース名 | ワイルドカード対応 |
| ExcludeDatabase | object[] | No | 除外データベース名 | 複数指定可 |
| ExcludeSystemDatabase | switch | No | システムDBを除外 | IsSystemObject=falseでフィルタ |
| IncludePublicGuest | switch | No | public/guestの権限を含める | デフォルトは除外 |
| IncludeSystemObjects | switch | No | システムオブジェクト権限を含める | デフォルトは除外 |
| ExcludeSecurables | switch | No | オブジェクト権限を除外 | ロールメンバーシップのみ出力 |
| EnableException | switch | No | 例外を直接スローする | デフォルトは警告メッセージ |

### 入力データソース

- パイプライン入力：SqlInstanceパラメータがValueFromPipelineを受け付ける
- 外部ファイル：bin/stig.sqlスクリプトをモジュールパスから読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Object | string | スコープ（SERVERまたはデータベース名） |
| Type | string | 監査行タイプ（SERVER LOGINS/SERVER SECURABLES/DB ROLE MEMBERS/DB SECURABLES） |
| Member | string | ログインまたはプリンシパル名（ロールメンバーシップ用） |
| RoleSecurableClass | string | ロール名またはセキュラブルクラス |
| SchemaOwner | string | スキーマ/所有者名 |
| Securable | string | セキュラブルオブジェクト名 |
| GranteeType | string | 被許可者タイプ（USER/ROLE等） |
| Grantee | string | 被許可者プリンシパル名 |
| Permission | string | 権限名（SELECT/INSERT/EXECUTE等） |
| State | string | 権限状態（GRANT/DENY） |
| Grantor | string | 許可者プリンシパル名 |
| GrantorType | string | 許可者タイプ |
| SourceView | string | データ取得元STIGビュー名 |

### 出力先

- PowerShellパイプライン：PSCustomObjectとして出力
- サーバーレベルとデータベースレベルで別々のオブジェクトが出力される

## 処理フロー

### 処理シーケンス

```
1. beginブロックでSQL準備
   └─ $removeStigSQL（STIGスキーマ削除用）
   └─ $serverSQL（サーバーレベル権限取得用）
   └─ $dbSQL（データベースレベル権限取得用）
   └─ ExcludeSecurablesスイッチに応じてUNION部分を追加/除外
   └─ IncludePublicGuest/IncludeSystemObjectsに応じてSQLを書き換え

2. processブロックで各SqlInstanceに対して処理
   └─ Connect-DbaInstance（MinimumVersion 10、AzureUnsupported）

3. bin/stig.sqlを読み込み

4. サーバーレベル権限取得
   └─ 既存STIGスキーマ削除
   └─ masterを対象にSTIGスキーマ作成
   └─ $serverSQLを実行してサーバー権限出力

5. 各データベースに対してループ処理
   └─ Database/ExcludeDatabase/ExcludeSystemDatabaseでフィルタ
   └─ IsAccessible確認
   └─ STIGスキーマを現在のDBコンテキストで再作成
   └─ $dbSQLを実行してDB権限出力

6. クリーンアップ
   └─ STIGスキーマを削除
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[beginブロック: SQL準備]
    B --> C{ExcludeSecurables?}
    C -->|No| D[セキュラブルUNION追加]
    C -->|Yes| E[ロールメンバーのみ]
    D --> F{IncludePublicGuest?}
    E --> F
    F -->|Yes| G[public/guestフィルタ除去]
    F -->|No| H{IncludeSystemObjects?}
    G --> H
    H -->|Yes| I[sys除外フィルタ除去]
    H -->|No| J[インスタンスループ開始]
    I --> J
    J --> K[Connect-DbaInstance]
    K --> L{接続成功?}
    L -->|No| M[警告・次へ]
    L -->|Yes| N[stig.sql読み込み]
    N --> O[既存STIGスキーマ削除]
    O --> P[master用STIGスキーマ作成]
    P --> Q[$serverSQL実行・出力]
    Q --> R[DBループ開始]
    R --> S{IsAccessible?}
    S -->|No| T[警告・次のDB]
    S -->|Yes| U[STIGスキーマ再作成]
    U --> V[$dbSQL実行・出力]
    V --> W{次のDBあり?}
    T --> W
    W -->|Yes| R
    W -->|No| X[STIGスキーマ削除]
    X --> Y{次のインスタンスあり?}
    M --> Y
    Y -->|Yes| J
    Y -->|No| Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最低バージョン要件 | SQL Server 2008以降が必要 | MinimumVersion 10 |
| BR-002 | Azure非対応 | Azure SQL Databaseは非対応 | AzureUnsupportedフラグ |
| BR-003 | STIGスキーマ一時作成 | tempdbにSTIGスキーマを作成して分析 | 処理中 |
| BR-004 | public/guest除外デフォルト | デフォルトでpublic/guest権限を除外 | IncludePublicGuest未指定時 |
| BR-005 | sysスキーマ除外デフォルト | デフォルトでsysスキーマオブジェクトを除外 | IncludeSystemObjects未指定時 |
| BR-006 | 中断時クリーンアップ注意 | Ctrl-CでSTIGスキーマが残る可能性 | 手動削除が必要 |

### 計算ロジック

STIGスキーマ内の関数/ビューによる権限分析:
- `STIG.server_role_members`: サーバーロールメンバーシップ
- `STIG.server_permissions`: サーバーレベル権限
- `STIG.database_role_members`: データベースロールメンバーシップ
- `STIG.database_permissions`: データベースレベル権限

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

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

| 操作 | 対象テーブル/オブジェクト | 操作種別 | 概要 |
|-----|-------------|---------|------|
| STIGスキーマ作成 | tempdb.STIG | CREATE SCHEMA/VIEW/FUNCTION | 一時分析オブジェクト作成 |
| サーバー権限取得 | master.sys.syslogins等 | SELECT | サーバーレベル権限 |
| DB権限取得 | [DB].sys.database_principals等 | SELECT | データベースレベル権限 |
| STIGスキーマ削除 | tempdb.STIG | DROP SCHEMA/VIEW/FUNCTION | クリーンアップ |

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

#### tempdb（STIG一時オブジェクト）
| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| CREATE/DROP | STIG.server_role_members等 | 処理開始/終了時 | bin/stig.sqlから生成 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | インスタンス接続失敗 | 警告出力後、次のインスタンスへ継続 |
| StigCreationError | STIG作成エラー | tempdbへのSTIG作成失敗 | 警告出力後、次のインスタンスへ継続 |
| DatabaseError | DB権限取得エラー | DBへのSTIG適用失敗 | 警告出力後、次のDBへ継続 |
| CleanupError | クリーンアップエラー | STIGスキーマ削除失敗 | 警告出力後継続 |

### リトライ仕様

リトライ機能は実装されていない。エラー発生時は次のインスタンス/データベースへ処理を継続する。

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

- STIGスキーマ作成/削除は個別のDDL操作として実行
- 各クエリは暗黙的なトランザクション内で実行
- 中断時のSTIGスキーマ残留に注意が必要

## パフォーマンス要件

- 大規模データベースでは権限分析に時間がかかる可能性
- 各データベースに対してSTIGスキーマを再作成するためオーバーヘッドあり
- ExcludeSecurablesを使用するとオブジェクト権限をスキップして高速化可能

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

- 認証情報はPSCredentialオブジェクトを使用
- 出力には詳細な権限情報が含まれるため、機密扱いが必要
- tempdbへの一時オブジェクト作成権限が必要
- 中断時にSTIGスキーマが残る可能性があり、手動削除が必要

## 備考

- SQL Server 2008以降が必要（MinimumVersion 10）
- Azure SQL Databaseは非対応
- 中断（Ctrl-C）した場合、tempdbにSTIGスキーマが残るため手動削除が必要
- DISA STIG準拠の分析手法を使用

---

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

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

### 推奨読解順序

#### Step 1: STIG SQLスクリプトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | stig.sql | `bin/stig.sql` | STIGスキーマ内のビュー/関数定義 |

**読解のコツ**: `<TARGETDB>`プレースホルダーが実行時にデータベース名に置換される。主要オブジェクト:
- STIG.database_role_members（61-73行目）
- STIG.database_permissions（171-417行目）
- STIG.server_role_members（544-556行目）
- STIG.server_permissions（653-718行目）

#### Step 2: パラメータとSQL準備を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaUserPermission.ps1 | `public/Get-DbaUserPermission.ps1` | beginブロック（121-225行目） |

**主要処理フロー**:
- **122-143行目**: $removeStigSQL（STIGスキーマ削除用DDL）
- **146-161行目**: $serverSQL（サーバーログインとロール取得）
- **163-175行目**: $dbSQL（DBロールメンバー取得）
- **178-221行目**: ExcludeSecurables未指定時のセキュラブルUNION追加
- **223-224行目**: IncludePublicGuest/IncludeSystemObjectsによるSQL書き換え

#### Step 3: メイン処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaUserPermission.ps1 | `public/Get-DbaUserPermission.ps1` | processブロック（228-337行目） |

**主要処理フロー**:
- **230-234行目**: Connect-DbaInstance（MinimumVersion 10, AzureUnsupported）
- **251-253行目**: stig.sqlファイル読み込み
- **255-286行目**: サーバーレベル権限取得（master用STIGスキーマ作成・クエリ実行）
- **288-328行目**: 各データベースに対するループ処理
- **330-335行目**: STIGスキーマ削除（クリーンアップ）

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

```
Get-DbaUserPermission
    │
    ├─ Connect-DbaInstance -MinimumVersion 10 -AzureUnsupported
    │
    ├─ Join-DbaPath（stig.sqlパス構築）
    │
    ├─ [System.IO.File]::ReadAllText（stig.sql読み込み）
    │
    ├─ Invoke-DbaQuery（$removeStigSQL実行）
    │
    ├─ Invoke-DbaQuery（$createStigSQL実行 - master用）
    │
    ├─ Invoke-DbaQuery（$serverSQL実行）
    │      └─ PSCustomObject生成・出力
    │
    └─ foreach $db
           ├─ Invoke-DbaQuery（$removeStigSQL実行）
           ├─ Invoke-DbaQuery（$createStigSQL実行 - 現在のDB用）
           ├─ Invoke-DbaQuery（$dbSQL実行）
           │      └─ PSCustomObject生成・出力
           │
           └─ Invoke-DbaQuery（$removeStigSQL実行 - クリーンアップ）
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance ─────────────▶ $server
                                  │
bin/stig.sql ────────────▶ File::ReadAllText ──────────────▶ $sql
                                  │
                           Replace("<TARGETDB>") ──────────▶ $createStigSQL
                                  │
IncludePublicGuest ──────▶ $dbSQL.Replace() ───────────────▶ 条件付きSQL
IncludeSystemObjects                │
ExcludeSecurables                   │
                                    ▼
                           tempdb: STIG Schema ────────────▶ 一時オブジェクト
                                    │
                           $serverSQL実行 ─────────────────▶ SERVER権限PSCustomObject
                                    │
                           $dbSQL実行（各DB） ─────────────▶ DB権限PSCustomObject
                                    │
                           $removeStigSQL実行 ─────────────▶ クリーンアップ完了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaUserPermission.ps1 | `public/Get-DbaUserPermission.ps1` | ソース | メイン機能実装 |
| stig.sql | `bin/stig.sql` | SQL | DISA STIG権限分析スキーマ定義 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | SQLクエリ実行 |
