Row Access Policy(行アクセスポリシー)は、テーブルやビューの行に対して、 クエリ実行者のロールやセッション属性に基づいてフィルタを自動適用するSnowflakeのセキュリティ機能です。 ポリシーはテーブルにアタッチされ、そのテーブルを参照するすべてのクエリに対して透過的に行フィルタが適用されます。Enterprise Edition以上で利用可能です。
-- 基本的なRow Access Policy(ロールベース)
CREATE OR REPLACE ROW ACCESS POLICY rap_region_filter
AS (region_val VARCHAR) RETURNS BOOLEAN ->
CASE
WHEN IS_ROLE_IN_SESSION('ADMIN') THEN TRUE
WHEN IS_ROLE_IN_SESSION('APAC_ANALYST')
AND region_val = 'APAC' THEN TRUE
WHEN IS_ROLE_IN_SESSION('EMEA_ANALYST')
AND region_val = 'EMEA' THEN TRUE
ELSE FALSE
END;
-- テーブルにポリシーをアタッチ
ALTER TABLE sales.transactions
ADD ROW ACCESS POLICY rap_region_filter ON (region);
-- ポリシーの解除
ALTER TABLE sales.transactions
DROP ROW ACCESS POLICY rap_region_filter;ポリシーの引数はテーブルの列にマッピングされます。RETURNS BOOLEANで、TRUEを返した行のみがクエリ結果に含まれます。 FALSEまたはNULLを返した行は結果から除外されます。
-- CURRENT_ROLE()ベースの判定(Primary Roleのみ評価)
CREATE OR REPLACE ROW ACCESS POLICY rap_dept_filter
AS (dept_val VARCHAR) RETURNS BOOLEAN ->
CURRENT_ROLE() IN ('SYSADMIN', 'HR_ADMIN')
OR dept_val = (
SELECT department
FROM hr.user_department_mapping
WHERE user_name = CURRENT_USER()
);
-- IS_ROLE_IN_SESSION()ベース(Secondary Roles対応)
CREATE OR REPLACE ROW ACCESS POLICY rap_dept_filter_v2
AS (dept_val VARCHAR) RETURNS BOOLEAN ->
IS_ROLE_IN_SESSION('SYSADMIN')
OR IS_ROLE_IN_SESSION('HR_ADMIN')
OR dept_val = (
SELECT department
FROM hr.user_department_mapping
WHERE user_name = CURRENT_USER()
);大規模な組織でロール数が多い場合、ポリシー内にロール名をハードコードするのは管理が困難です。 Mapping Table(マッピングテーブル)を使うと、アクセス制御の条件をテーブルデータとして管理でき、ポリシーの変更なしにアクセス制御を更新できます。
-- マッピングテーブルの作成
CREATE TABLE security.region_access_mapping (
role_name VARCHAR,
region VARCHAR,
access_level VARCHAR -- 'FULL' or 'RESTRICTED'
);
-- マッピングデータの投入
INSERT INTO security.region_access_mapping VALUES
('APAC_ANALYST', 'APAC', 'FULL'),
('EMEA_ANALYST', 'EMEA', 'FULL'),
('GLOBAL_ANALYST', 'APAC', 'FULL'),
('GLOBAL_ANALYST', 'EMEA', 'FULL'),
('GLOBAL_ANALYST', 'AMER', 'FULL');
-- Mapping Tableを参照するRow Access Policy
CREATE OR REPLACE ROW ACCESS POLICY rap_region_mapping
AS (region_val VARCHAR) RETURNS BOOLEAN ->
IS_ROLE_IN_SESSION('ADMIN')
OR EXISTS (
SELECT 1
FROM security.region_access_mapping m
WHERE IS_ROLE_IN_SESSION(m.role_name)
AND m.region = region_val
);
-- テーブルにアタッチ
ALTER TABLE sales.transactions
ADD ROW ACCESS POLICY rap_region_mapping ON (region);| 比較項目 | Row Access Policy | Masking Policy |
|---|---|---|
| 制御対象 | 行(レコード)の可視性 | 列(カラム値)のマスキング |
| 戻り値の型 | BOOLEAN(TRUE=表示/FALSE=非表示) | 引数と同じデータ型(マスク済み値を返す) |
| アタッチ単位 | テーブル/ビューに1つ | 列ごとに1つ |
| Edition要件 | Enterprise以上 | Enterprise以上 |
| COUNT(*)への影響 | フィルタされた行はカウントされない | 行数に影響なし(値がマスクされるのみ) |
| 同時適用 | Masking Policyと併用可能 | Row Access Policyと併用可能 |
| Tag-based適用 | タグベースでの自動アタッチ可能 | タグベースでの自動アタッチ可能 |
-- Row Access Policyの管理に必要な権限
-- ポリシーの作成
GRANT CREATE ROW ACCESS POLICY ON SCHEMA security
TO ROLE policy_admin;
-- ポリシーのアタッチ(テーブルへの適用)
GRANT APPLY ROW ACCESS POLICY ON ACCOUNT
TO ROLE policy_admin;
-- または特定のテーブルにのみ適用権限を付与
GRANT APPLY ROW ACCESS POLICY ON TABLE sales.transactions
TO ROLE policy_admin;
-- ポリシーのOWNERSHIPを持つロールはポリシーの変更・削除が可能
-- APPLY権限を持つロールはアタッチ・デタッチが可能
-- この2つの権限を分離することで職務分掌を実現Row Access PolicyとMasking Policyが同じテーブルに適用されている場合、Row Access Policyが先に評価され、フィルタを通過した行に対してMasking Policyが適用されます。 この順序はSnowflakeが内部的に制御するため、ユーザーが変更することはできません。
Security & Governance
問題 1
sales.ordersテーブルにRow Access Policyが適用されており、ANALYST_ROLEのユーザーはregion='APAC'の行のみ参照できる設計になっている。このユーザーがSELECT COUNT(*) FROM sales.ordersを実行した場合の結果として正しいものはどれか。
正解: B
Row Access Policyは、クエリの種類に関係なくテーブルへのすべてのアクセスに対して行フィルタを適用します。COUNT(*)もフィルタ後の行数を返すため、ANALYST_ROLEのユーザーにはregion='APAC'の行数のみがカウントされます。これはMasking Policy(値をマスクするが行数には影響しない)とは異なる重要な特性です。
Row Access PolicyとSecure Viewはどちらを使うべきですか?
Row Access Policyはテーブルに直接アタッチし、そのテーブルを参照するすべてのクエリ・ビュー・ストアドプロシージャに対して一元的に行フィルタを適用します。Secure ViewはView定義自体にフィルタ条件を含めるため、Viewごとに個別のフィルタ設計が必要です。複数のViewやクエリから同一テーブルにアクセスする場合はRow Access Policyの方が管理が容易です。一方、ビュー定義自体を秘匿する必要がある場合はSecure Viewが適しています。両者は併用可能です。
1つのテーブルに複数のRow Access Policyを適用できますか?
1つのテーブルまたはビューにアタッチできるRow Access Policyは1つのみです。複数のフィルタ条件が必要な場合は、1つのポリシー内でCASE式やIF文を使って条件を組み合わせます。異なるテーブルには異なるRow Access Policyをアタッチできるため、テーブルごとにポリシーを設計します。
Row Access Policyの中でサブクエリやMapping Tableを使うとパフォーマンスに影響しますか?
Row Access Policy内のサブクエリやMapping Table参照は、クエリ実行時に毎回評価されるためパフォーマンスに影響する可能性があります。特にMapping Tableが大規模な場合、結合コストが増大します。対策として、Mapping Tableにはクラスタリングキーの設定やサイズの最小化を検討します。また、CURRENT_ROLE()やIS_ROLE_IN_SESSION()のみで完結するシンプルなポリシーは、Mapping Table方式より高速に動作します。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Snowflake資格一覧|全11試験(SnowPro)の難易度・費用
Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...
Snowflake試験の難易度ランキング|全11資格を徹底比較
Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...
Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ
Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...
SnowPro Core試験完全解説|出題範囲・問題例・合格戦略
SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...
SnowPro Platform Associate完全解説|入門試験の攻略
SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...