「同じ1つのテーブルを、経理には全部見せ、営業には給与を伏字にして自部門の行だけ、社外パートナーには最小限だけ」——データ基盤の現場でほぼ必ず出てくる要件です。テーブルを分割してビューを量産する運用はすぐ破綻します。Snowflakeはこれを、列レベルの Dynamic Data Masking と行レベルの Row Access Policy という宣言的なポリシーで解きます。実データは1つのまま、クエリ時に見る人のロールへ合わせて結果が変わる。本記事では両者の仕組み、タグベースでの自動適用、AWS側との連携、そしてEMWが検証段階で先に踏み抜いて本番では防いだ落とし穴までを、現場目線で整理します。

01なぜ「役割で見せ分ける」のか

Snowflakeのアクセス制御はロール(RBAC)でテーブルやビュー単位に権限を配るのが基本です。しかし実務では「同じ売上テーブルを、経理は全列・全行、営業は自部門の行だけでメールと給与は伏字」といった、列単位・行単位の細かい制御が求められます。要件ごとにテーブルを複製したり限定ビューを量産したりする運用は、列が増えるたびに漏れが生まれ破綻します。Snowflakeは、これを2つの宣言的なポリシーで解決します。列レベルの Dynamic Data Masking と、行レベルの Row Access Policy です。どちらもクエリ実行時に評価されるため、保存されている実データは1セットのまま、参照する人のロールや条件に応じて返る結果だけが変わります。なお列レベル/行レベルのセキュリティは Enterprise Edition 以上の機能です。

顧客テーブル(実データ)email:taro@ex.jp給与:620,000region:北海道 ほかクエリ時にポリシー評価列: Masking Policy行: Row AccessROLE: FINANCE_ADMINemail: taro@ex.jp給与: 620,000 / 全リージョンROLE: SALES_ANALYSTemail: ***@***給与: ****** / 自部門の行のみROLE: PARTNERemail: *** / 給与: ***契約範囲の行のみ表示
同じ1つのテーブルを、ロールに応じてマスキングポリシーと行アクセスポリシーで見せ分ける。

02Dynamic Data Masking:列を守る

マスキングポリシーはスキーマレベルのオブジェクトです。CREATE MASKING POLICY で「入力する列の型」と「条件に応じて返す値」を定義し、ALTER TABLE … MODIFY COLUMN … SET MASKING POLICY で対象列に適用します。クエリ実行時、その列が現れるすべての場所でポリシーが評価され、ロールや条件に応じて平文・部分マスク・完全マスクのいずれかが返ります。ポイントは再利用性です。ポリシーを一度書けば数千の列に使い回せ、マスクの中身を変えても列への再適用は不要です。条件分岐には CURRENT_ROLEIS_ROLE_IN_SESSION などのコンテキスト関数を使い、たとえば「特定ロールなら平文、それ以外は伏字」を1行の CASE 式で表現できます。条件付きマスキングでは、別の列(例:同意フラグ)の値を見て開示可否を切り替えることもできます。

現場のコツ:CURRENT_ROLE はセッションで有効なプライマリロール1つだけを見ます。ロール階層で継承した権限まで含めて判定したいなら IS_ROLE_IN_SESSION を使うのが正解です。ここを取り違えると「解除されるべき人が伏字のまま」「意図せず露出」の両方が起き得ます。

03Row Access Policy:行を絞る

行アクセスポリシーは「どの行を返すか」をブール式で定義します。CREATE ROW ACCESS POLICY で列値を引数として受け取り、式が TRUE と評価された行だけが結果に含まれます。テーブルにもビューにもネストして適用でき、地域・部門・テナントIDなどでの絞り込みに使います。実務での定番は「マッピングテーブル方式」です。ユーザーやロールと、見てよいスコープ(部門コードや地域)の対応表をあらかじめ用意し、ポリシー式の中でそれを参照します。重要なのは、ポリシー式がクエリ実行者ではなくポリシーオーナーのロールで評価される点です。おかげで、実行者にマッピングテーブルへの直接の SELECT 権限を与えなくても行フィルタが機能します——マッピング表そのものを隠しながら制御できるわけです。

04タグベースのマスキングでスケールさせる

列ごとに手作業でポリシーを貼る運用は、新しい列が増えるたびに貼り忘れが発生します。タグベースのマスキングは、object tagging と masking policy を組み合わせ、ALTER TAG … SET MASKING POLICY でタグ側にポリシーを一度だけ紐づける方式です。以後、そのタグが付いた列は——ポリシーの入力型と列の型が一致していれば——自動的に保護されます。タグはデータベース・スキーマ・テーブルの各レベルに付与でき、下位オブジェクトへ伝播するため、「新しく作られた列も勝手に守られる」状態を作れます。sensitive data classification(自動分類)と組み合わせれば、PII列の検出 → タグ付与 → 自動マスクという一連の流れを設計できます。

現場のコツ:1つの列にタグ由来のポリシーと直接適用のポリシーが両方効く場合、列に直接適用したポリシーが優先されます。全社の既定はタグで面的に、例外だけ列に直接、という二層構成が管理しやすいです。

05AWS側との連携

SnowflakeはAWS上で動くため、周辺のAWSサービスと組み合わせると守りが厚くなります。外部ステージのS3データは SSE-KMS/カスタマー管理キーで暗号化し、Storage Integration と IAM ロールで最小権限アクセスに寄せます。ロード/アンロードの経路は AWS PrivateLink でインターネットを経由させない構成にできます。さらに強い要件——「Snowflakeにロードする前からトークン化しておき、権限のあるロールだけがクエリ時に復号(detokenize)する」——には External Tokenization を使います。これはマスキングポリシー本体から外部関数を呼ぶ方式で、Snowflakeがリモートサービスへ直接ではなく、Amazon API Gateway(プロキシ)経由で AWS Lambda(リモートサービス)を呼び出し、トークン化プロバイダのポリシーに従って結果を返します。SnowflakeからAPI GatewayへのHTTPリクエストは AWS SigV4 で署名され、鍵は KMS、権限は IAM で分離します。External Tokenization も Enterprise Edition 以上です。

External Tokenization:クエリ時に、権限のあるロールだけ復号するSnowflakeMasking Policy= 外部関数を呼ぶAmazon API Gatewayプロキシ / SigV4署名AWS Lambdaトークン化 / 復号HTTPS中継AWS KMS鍵管理S3 外部ステージSSE-KMS / PrivateLink暗号化データ
マスキングポリシーから外部関数を呼び、API Gateway 経由で Lambda がトークン化/復号する。鍵は KMS、保存データは S3 で暗号化。

06検証で先に踏み抜いた落とし穴

これらのポリシーは強力な一方、条件式の書き方ひとつで「見えてはいけないものが見える」「見えるべきものが伏字」という事故につながります。EMWはこの手の落とし穴を必ずPoC・検証環境で先に踏み抜き、本番では未然に防ぐ運用を徹底しています。実際に検証段階で発見・是正した代表例を挙げます。第一に、マスキング条件を CURRENT_ROLE だけで書いたところ、機能ロールを階層で継承しているユーザーが期待どおりに解除されないケースを検証中に観測しました。本番投入前に IS_ROLE_IN_SESSION ベースへ書き換え、ロール階層を意識した条件に是正しています。第二に、Row Access Policy のマッピングテーブルを巨大テーブルへ毎行結合する式にしたところ、検証で想定外にクエリが重くなると判明。マッピングを絞り込み、クラスタリングやキャッシュ前提の設計に見直しました。第三に、タグの伝播範囲を読み違えると、スキーマにタグを付けた瞬間に想定外の列まで一斉にマスクされ得ることも検証で確認し、適用範囲を段階的に広げる手順へ切り替えました。低コストの小規模導入から最大規模の基盤まで、複数業種で同じ姿勢を通し、本番環境での重大障害0を継続しています。

現場のコツ:本番反映前に「解除されるべきロール」と「絶対に見えてはいけないロール」の両方で同じクエリを流し、期待結果と突き合わせるテストを必ず用意します。ポリシーは1つの見落としが全社の露出になるため、片側だけの確認では不十分です。

07運用とガバナンスのまとめ

ポリシーは分散させず集中管理するのが鉄則です。CREATE/APPLY 権限を専用のポリシー管理ロールに集約し、テーブルオーナーが勝手に外せない構造にします。適用状況は ACCOUNT_USAGEPOLICY_REFERENCESMASKING_POLICIES などのビューで棚卸しし、「どの列・どの行にどのポリシーが効いているか」を定期的に可視化します。そして、誰がいつ機微な列にアクセスしたかは Access History で監査します。列マスキング+行アクセス+タグ+自動分類+監査をセットで回すことで、「誰が・どの条件で・何を見られるのか」を説明可能な状態に保てます。ガバナンスとは、ビジネスルールを強制力のある制御と証跡へ翻訳することであり、Snowflakeのポリシー群はその中核を担います。

参考情報(一次情報)

EMWはAWS×Snowflakeで、マスキング/行アクセス/タグ設計から監査・PrivateLink連携まで検証込みで支援します。データの見せ分け設計はお気軽にご相談ください。

相談する
← ブログ一覧へ戻る