Snowflakeのデータ保護機能の中核をなすMasking PolicyとRow Access Policyは、 どちらもEnterprise Edition以上で利用できるポリシーベースのアクセス制御ですが、制御の対象と動作が根本的に異なります。 Masking Policyは列の値を変換して返し、Row Access Policyは行の可視性をフィルタします。 両者を正しく使い分け、必要に応じて同時適用する設計が、SnowPro Security試験でも実務でも求められます。
| 比較項目 | Masking Policy | Row Access Policy |
|---|---|---|
| 制御対象 | 列の値(カラム値の変換) | 行の可視性(レコードのフィルタ) |
| 戻り値の型 | 引数と同じデータ型(マスク済み値を返す) | BOOLEAN(TRUE=表示 / FALSE=非表示) |
| アタッチ対象 | 列(Column)ごとに1つ | テーブル/ビューに1つ |
| SELECT *の挙動 | マスクされた値が返される | フィルタされた行のみ返される |
| COUNT(*)への影響 | 影響なし(行数は変わらない) | フィルタ後の行数が返される |
| WHERE句での動作 | マスク前の値でフィルタが実行される | ポリシー条件でフィルタされた後にWHERE句が適用される |
| Tag-based適用 | ALTER TAG SET MASKING POLICY で自動適用可能 | ALTER TAG SET ROW ACCESS POLICY で自動適用可能 |
| 必要権限 | CREATE MASKING POLICY + APPLY MASKING POLICY | CREATE ROW ACCESS POLICY + APPLY ROW ACCESS POLICY |
-- メールアドレスのマスキング
CREATE OR REPLACE MASKING POLICY mask_email
AS (val VARCHAR) RETURNS VARCHAR ->
CASE
WHEN IS_ROLE_IN_SESSION('HR_ADMIN') THEN val
WHEN IS_ROLE_IN_SESSION('MANAGER') THEN
CONCAT(LEFT(val, 2), '****@', SPLIT_PART(val, '@', 2))
ELSE '****@****.***'
END;
-- 列にアタッチ
ALTER TABLE hr.employees
ALTER COLUMN email
SET MASKING POLICY mask_email;
-- 数値型の給与マスキング
CREATE OR REPLACE MASKING POLICY mask_salary
AS (val NUMBER) RETURNS NUMBER ->
CASE
WHEN IS_ROLE_IN_SESSION('HR_ADMIN') THEN val
WHEN IS_ROLE_IN_SESSION('MANAGER') THEN
ROUND(val, -4) -- 万単位に丸め
ELSE NULL
END;
ALTER TABLE hr.employees
ALTER COLUMN salary
SET MASKING POLICY mask_salary;-- 部署ベースの行フィルタ
CREATE OR REPLACE ROW ACCESS POLICY rap_department
AS (dept_val VARCHAR) RETURNS BOOLEAN ->
IS_ROLE_IN_SESSION('HR_ADMIN')
OR dept_val = (
SELECT department FROM hr.user_dept_mapping
WHERE user_name = CURRENT_USER()
);
-- テーブルにアタッチ
ALTER TABLE hr.employees
ADD ROW ACCESS POLICY rap_department ON (department);Masking PolicyとRow Access Policyは同一テーブルに同時に適用可能です。 この場合、Row Access Policy → Masking Policyの順で評価されます。
-- シナリオ: hr.employeesテーブルに両方を適用
-- Row Access Policy: 自部署の社員のみ表示
-- Masking Policy: salary列をロールに応じてマスク
-- Step 1: Row Access Policyをアタッチ
ALTER TABLE hr.employees
ADD ROW ACCESS POLICY rap_department ON (department);
-- Step 2: Masking Policyをアタッチ
ALTER TABLE hr.employees
ALTER COLUMN salary
SET MASKING POLICY mask_salary;
ALTER TABLE hr.employees
ALTER COLUMN email
SET MASKING POLICY mask_email;
-- 結果(MANAGERロールの場合):
-- 1. Row Access Policyで自部署の社員のみに絞られる
-- 2. salary列は万単位に丸められる
-- 3. email列は先頭2文字+マスクされた形で返される| 比較項目 | Masking / Row Access Policy | Secure View |
|---|---|---|
| 適用範囲 | テーブルへの全アクセス経路に適用 | View経由のアクセスのみ |
| View定義の秘匿 | ポリシーロジックはOWNERのみ確認可能 | GET_DDLでView定義が見えない |
| オプティマイザ最適化 | 通常の最適化が適用される | 一部の最適化が制限される |
| 管理コスト | テーブル+ポリシーで管理 | ロールごとにView作成が必要な場合がある |
| Data Sharingとの相性 | ポリシーは共有先でも有効 | Secure ViewはData Sharingで推奨される |
要件: 特定のユーザー/ロールにデータを制限したい
│
├─ 行単位で制限したい(例: 自部署の社員のみ表示)
│ └─ → Row Access Policy
│
├─ 列の値を変換して返したい(例: SSNの一部をマスク)
│ └─ → Masking Policy
│
├─ 列自体を完全に非表示にしたい
│ ├─ クエリ結果から列を除外 → Projection Policy
│ └─ View定義で列を除外 → Secure View
│
└─ 行制限 + 列マスクの両方
└─ → Row Access Policy + Masking Policy を併用-- 他の列の値に基づいてマスクを切り替え
CREATE OR REPLACE MASKING POLICY mask_salary_by_region
AS (salary_val NUMBER, region_val VARCHAR) RETURNS NUMBER ->
CASE
WHEN IS_ROLE_IN_SESSION('HR_ADMIN') THEN salary_val
WHEN IS_ROLE_IN_SESSION('APAC_MANAGER')
AND region_val = 'APAC' THEN salary_val
ELSE NULL
END;
-- 2つの列をマッピングしてアタッチ
ALTER TABLE hr.employees
ALTER COLUMN salary
SET MASKING POLICY mask_salary_by_region
USING (salary, region);Security & Governance
問題 1
hr.employeesテーブルにRow Access Policy(department列で自部署のみ表示)とMasking Policy(salary列をNULL化)が同時に適用されている。ANALYST_ROLE(Engineering部署)のユーザーがSELECT department, salary, COUNT(*) OVER() FROM hr.employeesを実行した場合の結果として正しいものはどれか。
正解: B
Row Access PolicyとMasking Policyは同時に適用可能です。まずRow Access Policyが評価され、Engineering部署の行のみが残ります。次にMasking Policyが適用され、salary列がNULLに変換されます。COUNT(*) OVER()はRow Access Policy適用後の行数(Engineering部署の人数)を返します。この評価順序(Row Access → Masking)はSnowflakeが内部的に制御しています。
Masking PolicyとRow Access Policyを同時に適用した場合、どちらが先に評価されますか?
SnowflakeはRow Access Policyを先に評価し、フィルタを通過した行に対してMasking Policyを適用します。この順序はSnowflake内部で固定されており、ユーザーが変更することはできません。例えば、ある行がRow Access Policyでフィルタされた場合、その行に対するMasking Policyは評価されません(行自体が結果に含まれないため)。
Masking PolicyとRow Access Policyの権限管理は分離すべきですか?
はい。SnowflakeではAPPLY MASKING POLICYとAPPLY ROW ACCESS POLICYは別々の権限として管理されます。ポリシーのOWNERSHIP(作成・変更権限)とAPPLY権限(テーブルへのアタッチ権限)も分離することで、職務分掌を実現できます。例えばセキュリティチームがポリシーを作成(OWNERSHIP)し、データエンジニアが個別テーブルに適用(APPLY)する運用が可能です。
Secure ViewでMasking PolicyやRow Access Policyの代替はできますか?
Secure Viewは列の除外やWHERE句での行フィルタを実現できますが、テーブルを直接クエリする場合やView経由以外のアクセスには制御が効きません。Masking Policy/Row Access Policyはテーブルにアタッチされるため、直接クエリ・View・ストアドプロシージャなど全てのアクセス経路に適用されます。Secure ViewはView定義の秘匿が必要な場合に併用し、データ保護の主軸はポリシーベースで設計するのが推奨されます。
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)を徹底解説。最も簡単...