# 論理ビューのセキュリティモード

論理ビューは、ビューによって参照されるテーブルへのアクセス時に権限がどのように評価されるかを制御する2つのセキュリティモードをサポートしています: **DEFINER**と**INVOKER**です。

## 概要

セキュリティモードは、ビューが基盤となるテーブルにアクセスする際に、誰の権限が使用されるかを決定します。

- **DEFINERモード**: ビューはビュー**オーナー**の権限で実行されます
- **INVOKERモード**: ビューは**クエリ実行者**の権限で実行されます


デフォルトのセキュリティモードは**DEFINER**で、これはほとんどのデータベースシステムで使用される標準規約に従っています。

ビューがビューと同じデータベースに保存されているテーブルのみを参照する場合、セキュリティモードは重要ではありません。これは、アクセス制御がデータベースレベルで実行されるためです。セキュリティモードは、ビューが異なるデータベース間でテーブルを参照する場合に関連します。

## DEFINERモード（デフォルト）

DEFINERモードでは、ビューに対するクエリは、クエリを実行するユーザーではなく、ビューを作成した（所有する）ユーザーの権限を使用して実行されます。

### DEFINERモードを使用する場合

以下の場合にDEFINERモードを使用します:

- **機密データへの制御されたアクセスを提供**: 基盤となるテーブルへの直接アクセスを許可することなく、ユーザーが特定の列またはフィルタリングされた行をクエリできるようにします
- **パーミッション管理を簡素化**: ビューをクエリする必要があるすべてのユーザーに権限を付与する代わりに、ビューオーナーに一度だけ権限を付与します
- **抽象化レイヤーを作成**: 複雑なセキュリティロジックをシンプルなビューインターフェースの背後に隠します


### 例


```sql
CREATE VIEW filtered_data.customers
SECURITY DEFINER
AS
SELECT customer_id, customer_name, country
FROM source_data.customers
WHERE country IN ('US', 'CA', 'MX');
```

この例では:

- ビューは`filtered_data`データベースに作成され、参照されるテーブルは`source_data`データベースにあります
- ビューオーナーは`source_data.customers`テーブルへのアクセス権限を持っています
- `filtered_data.customers`をクエリするユーザーは、`source_data`データベースまたは`source_data.customers`テーブルへの直接的な権限は**不要**です
- すべてのユーザーは、自身の権限に関係なく、US、CA、またはMXの顧客のみを表示します
- ビューはオーナーの権限で実行されます。この権限には、`source_data.customers`テーブル全体へのアクセスが含まれます


アクセス制御はデータベースレベルで行われるため、DEFINERセキュリティモードを効果的に活用するには、ビューは参照テーブルが保存されているデータベースとは異なるデータベースに定義する必要があります。

### ネストされたビューでのDEFINERモード

ビューが他のビューを参照する場合、各ビューのセキュリティモードは独立して評価されます:


```sql
-- view_aはtable_cを参照
CREATE VIEW view_a
SECURITY DEFINER
AS SELECT * FROM table_c;

-- view_bはview_aを参照
CREATE VIEW view_b
SECURITY DEFINER
AS SELECT * FROM view_a;
```

クエリが`SELECT * FROM view_b`を実行すると:

1. `view_b`は、view_bのオーナーの権限でアクセスされます（DEFINERモード）
2. `view_a`は、view_aのオーナーの権限でアクセスされます（DEFINERモード）
3. `table_c`は、view_aのオーナーの権限でアクセスされます（DEFINERモード）


## INVOKERモード

INVOKERモードでは、ビューに対するクエリは、ビューオーナーではなく、クエリを実行しているユーザーの権限を使用して実行されます。

### INVOKERモードを使用する場合

以下の場合にINVOKERモードを使用します:

- **ユーザーレベルの権限を強制**: 各ユーザーが、自身の権限に基づいてアクセスを許可されたデータのみを表示できるようにします
- **セキュリティを変更せずにクエリロジックを簡素化**: 既存の権限モデルを維持しながら、再利用可能なクエリテンプレートを提供します
- **誰が何にアクセスしたかを監査**: ビューオーナーではなく、実際のクエリ実行者に基づいてアクセスを追跡します


### 例


```sql
CREATE VIEW analytics.all_customer_orders
SECURITY INVOKER
AS
SELECT o.order_id, o.customer_id, o.amount, c.customer_name
FROM source_data.orders o
JOIN source_data.customers c ON o.customer_id = c.customer_id;
```

この例では:

- ビューは`analytics`データベースに作成され、参照されるテーブルは`source_data`データベースにあります
- ユーザーは、`source_data.orders`テーブルと`source_data.customers`テーブルの両方へのアクセス権限を持っている必要があります
- 各ユーザーは、自身の権限に基づいてアクセスを許可されたデータのみを表示します
- ユーザーが`source_data.customers`テーブルへの権限を持っていない場合、クエリは失敗します


### ネストされたビューでのINVOKERモード

ビューがINVOKERモードで他のビューを参照する場合:


```sql
-- view_aはtable_cを参照
CREATE VIEW view_a
SECURITY INVOKER
AS SELECT * FROM table_c;

-- view_bはview_aを参照
CREATE VIEW view_b
SECURITY INVOKER
AS SELECT * FROM view_a;
```

クエリが`SELECT * FROM view_b`を実行すると:

1. `view_b`は、クエリ実行者の権限でアクセスされます（INVOKERモード）
2. `view_a`は、クエリ実行者の権限でアクセスされます（INVOKERモード）
3. `table_c`は、クエリ実行者の権限でアクセスされます（INVOKERモード）


## ネストされたビューの制限事項

DEFINERセキュリティモードの論理ビューは、INVOKERセキュリティモードの論理ビューを参照すべきではありません。この組み合わせは予期しない権限動作を引き起こす可能性があり、推奨されません。

## 比較表

| 側面 | DEFINERモード | INVOKERモード |
|  --- | --- | --- |
| **使用される権限** | ビューオーナーの権限 | クエリ実行者の権限 |
| **ユースケース** | 機密データへの制御されたアクセス | ユーザーレベルの権限強制 |
| **権限設定** | ビューオーナーにのみ権限を付与 | すべてのユーザーに権限を付与 |
| **セキュリティ上のメリット** | 特定の列/行へのデータアクセスを制限 | 既存の権限モデルを強制 |
| **デフォルト** | はい | いいえ |


## セキュリティモードの指定

### ビュー作成時

ビューを作成する際は、CREATE VIEWステートメントでセキュリティモードを指定します:


```sql
-- DEFINERモード（デフォルト）
CREATE VIEW view_name
SECURITY DEFINER
AS
SELECT * FROM table_name;

-- INVOKERモード
CREATE VIEW view_name
SECURITY INVOKER
AS
SELECT * FROM table_name;
```

セキュリティモードを指定しない場合、デフォルトでDEFINERが使用されます。

### セキュリティモードの変更

セキュリティモードは、Data Workbench UIまたはSQLを使用して変更できます。

**UIを使用する場合:**

1. Data Workbenchでビュー詳細ページに移動します
2. メニュー（⋯）を選択し、**詳細を編集**を選択します
3. **論理ビューの詳細を編集**ダイアログで、以下を選択します:
  - **Definer**: ビュー作成者の権限を使用します
  - **Invoker**: 現在のユーザーの権限を使用します
4. **確認**を選択して変更を適用します


![論理ビューの詳細を編集ダイアログ](/assets/logical-view-edit-details-dialog.e55c3c71ef4577f32e40badcd4c2eb9904ce516dcade6a1ff89fe06a9b57e635.4c190181.png)

**SQLを使用する場合:**

セキュリティモードをSQLで変更するには、CREATE OR REPLACE VIEWを使用します:


```sql
-- INVOKERモードに変更
CREATE OR REPLACE VIEW view_name
SECURITY INVOKER
AS
SELECT * FROM table_name;
```

CREATE OR REPLACE VIEWを使用する場合、完全なクエリ定義を再指定する必要があります。

## 重要な考慮事項

### DEFINERモードではビューのオーナーシップが重要

- DEFINERモードを使用する場合、ビューオーナーの権限が重要です
- ビューオーナーが削除されると、DEFINERモードのビューは機能しなくなります
- DEFINERビューを所有するユーザーを削除する前に、適切な権限を持つ別のユーザーにオーナーシップを委譲してください


### 列レベルセキュリティの制限

- 論理ビューの列には、データ分類のタグを付けることはできません
- ユーザーがカラムパーミッション（タグ付けされていない列を表示できない）を持っている場合、クエリで論理ビューを使用できません
- この制限は、セキュリティモードに関係なく適用されます


## 次のステップ

- [論理ビュー](/ja/products/customer-data-platform/data-workbench/databases/logical-views) - 論理ビューの作成、表示、管理に関する完全ガイド