Snowflakeのデータアクセス制御方法まとめ(2024-02版)
とーかみです。
Snowflake にあるデータにアクセスする範囲の制御方法は、データベースでよくある制御方法の他にも Snowflake 独自の機能があります。
この記事では、 Snowflake において、ユーザーからアクセスできるデータを制御する際に使用できる方法についてまとめました。
オブジェクトに対する操作を制御(GRANT)
Snowflake ではオブジェクトに対する参照、使用、変更といった操作の権限を GRANT コマンドで与えます。
権限を与える対象にはいくつかの種類がありますが、考え方は同じなため、この記事ではロールを対象にして説明します。
(「A に対して B を C する(操作)権限を与える」の場合の A に相当します)
操作対象
与える権限の操作対象について説明します。
(「A に対して B を C する(操作)権限を与える」の場合の B に相当します)
操作対象の中でデータアクセス制御に関係するものには以下のようなものがあります。
- データベース
- スキーマ
- テーブル
- ビュー
- ユーザー定義関数(UDF)
- ストアドプロシージャ
参考 : ロール設計
Snowflake のロール設計に関する参考記事を紹介します。
Functional Role + Access Role の考え方について
Functional Role + Access Role は、以下の公式ドキュメントで紹介されている考え方です。
構築する際のイメージは以下の記事にも記載されていますので参考にしてください。
ロールの階層設計
あわせて、ロール設計の参考になる記事も紹介します。
コンテキスト関数を使用した動的な制御
SQL ステートメントが実行される際のコンテキストに関する情報を取得する関数をコンテキスト関数と呼びます。
例えば、現在日付を取得する CURRENT_DATE
はコンテキスト関数に含まれます。
この記事で紹介するアクセス制御方法の条件設定の中でコンテキスト関数を使用することで動的な制御を実現できます。
ロールごとの動的な制御
以降の手法の紹介の中で触れるため、ロールごとに動的に制御するために使用できる組み込み関数を先に紹介します。
CURRENT_ROLE
CURRENT_ROLE は現在のセッションで使用されている プライマリロール の名前を返す組み込み関数です。
セカンダリロールを有効にしている場合、期待した動作にならない場合があるので注意してください。
以下のように使用します。
SELECT CURRENT_ROLE();
IS_ROLE_IN_SESSION
IS_ROLE_IN_SESSION は、プライマリロールまたはセカンダリロールが、指定されたロールを継承しているかを検証します。
Functional Role + Access Role の考え方を採用している場合では、Functional Role ではなく Access Role を基準とした制御が実現できるようになるということです。
以下のように使用します。
IS_INSTANCE_ROLE_IN_SESSION( '<instance_name>' , '<instance_role_name>' )
ビュー
ビューを使用したアクセス制御には 2 パターンあります。
- ビュー自体へのアクセス許可による制御
- 動的ビューによる制御
ビュー自体へのアクセス許可による制御
本体のテーブルや、参照するカラムを制限したビューを作成し、それらへのアクセスを許可するかどうかでアクセス範囲を制限する方式です。
この方法は、マテリアライズドビューも利用することができます。
ビューの定義を隠したい場合はセキュアビューを利用してください。
動的ビューによる制御
CURRENT_ROLE
や IS_ROLE_IN_SESSION
を使用して、セッションのロールによって参照するレコードや値が変わるような動的ビューを定義してアクセス範囲を制御する方法です。
例えば、 SELECT 句の CASE 文や WHERE 句のなかでこれらの関数を使ってアクセス範囲を制御します。
この方法では、マテリアライズドビューは利用できません。
マテリアライズドビューの事前処理の際にロール情報が特定できないためです。
ただし、直接利用できないというだけなので、マテリアライズドビューを参照するような動的ビューであれば作成可能です。
列レベルセキュリティ
列レベルのセキュリティには、ダイナミックデータマスキングと外部トークン化が利用できます。
ダイナミックデータマスキング
ダイナミックデータマスキングは、以下の公式ドキュメントに記載されている SQL のように、ロールを基準にデータをマスクするかどうかの制御を定義します。
CREATE MASKING POLICY employee_ssn_mask AS (val string) RETURNS string ->
CASE
WHEN CURRENT_ROLE() IN ('PAYROLL') THEN val
ELSE '******'
END;
外部トークン化
外部トークン化は、外部関数を経由してトークン化したデータを Snowflake にロード(保存)することで Snowflake 上には生データが保存されないようにする方法です。
定義は、以下の公式ドキュメントに記載されている SQL の形で行います。
外部トークン化を利用する場合、権限のないユーザーにはトークン化されたデータが表示される形になります。(CASE 文の ELSE の記述)
CREATE MASKING POLICY employee_ssn_detokenize AS (val string) RETURNS string ->
CASE
WHEN CURRENT_ROLE() IN ('PAYROLL') THEN ssn_unprotect(VAL)
ELSE val -- sees tokenized data
END;
列レベルセキュリティの適用
ダイナミックデータマスキングや外部トークン化を使用して定義したマスキングポリシーを適用します。
テーブル全体に適用する場合
テーブルまたはビューの全体に適用する場合は、公式ドキュメントに記載されている以下のような SQL になります。
-- table
CREATE OR REPLACE TABLE user_info (ssn string masking policy ssn_mask);
-- view
CREATE OR REPLACE VIEW user_info_v (ssn masking policy ssn_mask_v) AS SELECT * FROM user_info;
特定の列に適用する場合
特定の列には、公式ドキュメントに記載されている以下のような SQL になります。
-- table
CREATE OR REPLACE TABLE user_info (email string masking policy email_visibility) USING (email, visibility);
--view
CREATE OR REPLACE VIEW user_info_v (email masking policy email_visibility) USING (email, visibility) AS SELECT * FROM user_info;
行レベルセキュリティ
Snowflake では、行アクセスポリシーにより行レベルのセキュリティを実現できます。
行レベルのセキュリティは、 SELECT だけでなく、 UPDATE、DELETE、MERGE の中で選択される行にも影響します。
行アクセスポリシーの設定イメージ
上記の公式ドキュメントの SQL を抜粋しながら設定および利用イメージを説明します。
設定時のロール設定についてはここでは省略していますので、公式ドキュメントを確認してください。
行アクセスポリシーは、関数の引数を定義するような形で基準とする列を利用できます。
下記の SQL では sales_region
という名前で指定しています。
BOOLEAN が返るように定義することでその行を返すかどうか(クエリ時に参照できるかどうか)を判定します。
CREATE OR REPLACE ROW ACCESS POLICY security.sales_policy
AS (sales_region varchar) RETURNS BOOLEAN ->
'sales_executive_role' = CURRENT_ROLE()
OR EXISTS (
SELECT 1 FROM salesmanagerregions
WHERE sales_manager = CURRENT_ROLE()
AND region = sales_region
)
;
行アクセスポリシーを設定する場合は、ポリシー名と基準とする列(以下の SQL の場合は region
)を指定します。
ALTER TABLE sales ADD ROW ACCESS POLICY security.sales_policy ON (region);
設定したテーブルに対して SELECT すると、そのロールで参照可能な範囲の行のみ選択される状態になります。
タグでの対象の制御
タグ付け
Snowflake ではオブジェクトにタグをつけることができます。
タグにより分類のような説明情報を付与したり、コストを分類したり、アクセス制御をしやすくできます。
Snowflake のタグは key-value 型で、 key に対して取り得る value を定義します。
以下の例では finance
と engineering
の値が設定できる cost_center
というタグを作成しています。
create tag cost_center
allowed_values 'finance', 'engineering';
タグベースのマスキングポリシー設定
タグを利用してマスキングポリシーを設定できます。
タグを利用することで、同一のマスキングポリシーを複数のテーブルやカラムに適用する際に管理しやすくなります。
GRANT での権限制御とは別で考える必要がある点に注意してください。
具体的な設定、動作イメージは以下の記事を参照してください。
参考 : 自動分類と自動タグ付け
以下の記事で、Classification を用いた自動分類と自動タグ付けについて紹介されていますので参考にしてください。
プライバシー保護
「アクセス自体は禁止しないが個人情報が透けて見えるような状態にはしたくない」というときに考えるのがプライバシー保護です。
Snowflake ではプライバシー保護に関連するポリシーや加工の機能が利用できます。
以下の記事でとてもわかりやすくまとめられていました!
特に「プライバシー機能俯瞰図」として 1 枚の画像にまとまっているものがイメージしやすいのでぜひご覧ください。
ハッシュ化・暗号化
上記の記事でも触れられていますが、ハッシュ化および暗号化に関数が用意されています。
ハッシュ化および暗号化に関数は、ビューの定義やマスキングポリシーの中で使用できます。
データ共有でアカウント単位の制御
Snowflake はアカウントを超えてデータ共有ができます。
大規模な環境の場合、マルチアカウント戦略をとり、データ共有によりデータの参照範囲を制御するやり方もあります。
まとめ
Snowflake でのデータアクセス制御方法をまとめました。
さまざまな方法が利用でき柔軟な制御ができます。
一方で、実現できるからといって追加していくと管理ができなくなるリスクがあります。
どのような制御を何で(どこで)実現するか、それらをどのように管理していくかの方針を決めたうえで運用するようにしましょう。