Snowflake

Snowflake Row Access Policiesで行レベルセキュリティを実装する

2026-03-26
更新: 2026-03-27
NicheeLab編集部

Row Access Policy(行アクセスポリシー)は、テーブルやビューの行に対して、 クエリ実行者のロールやセッション属性に基づいてフィルタを自動適用するSnowflakeのセキュリティ機能です。 ポリシーはテーブルにアタッチされ、そのテーブルを参照するすべてのクエリに対して透過的に行フィルタが適用されます。Enterprise Edition以上で利用可能です。

CREATE ROW ACCESS POLICYの基本構文

-- 基本的な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()による判定パターン

-- 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方式

大規模な組織でロール数が多い場合、ポリシー内にロール名をハードコードするのは管理が困難です。 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);

Masking Policyとの比較

比較項目Row Access PolicyMasking 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が内部的に制御するため、ユーザーが変更することはできません。

設計のベストプラクティス

  • 管理者ロールの除外:ポリシーの最初の条件でSYSADMINやACCOUNTADMINをTRUEにしておく。管理者がデータにアクセスできなくなるとトラブルシューティングが困難になる
  • IS_ROLE_IN_SESSION()の使用:CURRENT_ROLE()はSecondary Rolesを考慮しないため、IS_ROLE_IN_SESSION()を使用することでSecondary Roles有効時も正しく評価される
  • テスト時にSIMULATE:EXECUTE USING ... コマンドは存在しないため、テスト用ロールでUSE ROLEしてクエリを実行し、期待通りの行のみが返されるか確認する
  • Mapping Tableの保護:Mapping Table自体へのアクセス権限を厳格に管理する。Mapping Tableを改ざんされるとアクセス制御がバイパスされる

問題で確認

Security & Governance

問題 1

sales.ordersテーブルにRow Access Policyが適用されており、ANALYST_ROLEのユーザーはregion='APAC'の行のみ参照できる設計になっている。このユーザーがSELECT COUNT(*) FROM sales.ordersを実行した場合の結果として正しいものはどれか。

  1. テーブル全体の行数が返される(Row Access PolicyはCOUNT(*)には影響しない)
  2. region='APAC'の行数のみがカウントされて返される
  3. Row Access Policyが適用されたテーブルではCOUNT(*)は実行できずエラーになる
  4. NULLが返される

正解: 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方式より高速に動作します。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Snowflake

Snowflake資格一覧|全11試験(SnowPro)の難易度・費用

Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...

Snowflake

Snowflake試験の難易度ランキング|全11資格を徹底比較

Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...

Snowflake

Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ

Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...

Snowflake

SnowPro Core試験完全解説|出題範囲・問題例・合格戦略

SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...

Snowflake

SnowPro Platform Associate完全解説|入門試験の攻略

SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...

Snowflakeの記事一覧 (102件)
© 2026 NicheeLab All rights reserved.