- カテゴリ:
CREATE MASKING POLICY¶
新しい列レベルのセキュリティマスキングポリシーを作成します。マスキングポリシーは、複数のルールとデフォルトの関数を持つことができるスキーマレベルのオブジェクトであり、実行中のコンテキスト(例: ロール)に基づいて、1つのルールを適用できます。
Snowflakeは、マスキングポリシーを SQL 式として評価します。したがって、マスキングポリシー本体の CASE 式で WHEN-THEN 句として指定されている場合、ルールは記述された順序で評価されます。
マスキングポリシー本体は、ルールを指定する SQL 式です。実行時に、Snowflakeはクエリを書き換えて、マスキングポリシー式を列に適用します。
マスキングポリシーを作成した後、 ALTER TABLE ... ALTER COLUMN または ALTER VIEW を使用して、マスキングポリシーをテーブルまたはビューの列に適用します。
- こちらもご参照ください。
構文¶
CREATE [ OR REPLACE ] MASKING POLICY <name> AS
(VAL <data_type>) RETURNS <data_type> -> <expression_ON_VAL>
[ COMMENT = '<string_literal>' ];
パラメーター¶
名前
マスキングポリシーの識別子。スキーマに対して一意である必要があります。
識別子の値はアルファベットで始まる必要があり、識別子文字列全体が二重引用符で囲まれていない限り、スペースや特殊文字を含めることはできません(例:
"My object"
)。二重引用符で囲まれた識別子も大文字と小文字が区別されます。詳細については、 識別子の要件 をご参照ください。
AS ( VAL データ型 )
マスクするデータ型を定義します。詳細については、 データ型 をご参照ください。
RETURNS データ型
返すデータ型を定義します。詳細については、 データ型 をご参照ください。
式 ON_VAL
データを変換するSQL式。
式には、条件付きロジックを表す 条件式関数、組み込み関数、またはデータを変換する UDFs を含めることができます。
マスキングポリシー本体内で UDF または外部関数が使用されている場合、ポリシー所有者は UDF または外部関数に OWNERSHIP を持っている必要があります。マスキングポリシーが適用されている列をクエリするユーザーは、UDFまたは外部関数にUSAGEを持っている必要はありません。
COMMENT = '文字列リテラル'
マスキングポリシーのコメントを追加するか、既存のコメントを上書きします。
使用上の注意¶
既存のマスキングポリシーを置き換えるために、ポリシーの現在の定義を確認する必要がある場合は、 GET_DDL 関数を呼び出すか、 DESCRIBE MASKING POLICY コマンドを実行します。
マスキングポリシー本文にサブクエリを含むマスキングポリシーの場合は、 WHEN 句で EXISTS を使用します。代表的な例については、 例 セクションのカスタム資格テーブルの例をご参照ください。
例¶
条件式関数、 コンテキスト関数、および UDFs を使用して、 SQL 式を記述できます。
以下は、完全なマスク、ハッシュ、正規表現、および UDF を使用してマスキングポリシーを作成する方法を示す代表的な例です。
完全なマスク:
ANALYST ロールはプレーンテキスト値を見ることができます。ANALYST のロールがないユーザーには完全なマスクが表示されます。
CREATE OR REPLACE MASKING POLICY email_mask AS (val string) returns string -> CASE WHEN current_role() IN ('ANALYST') THEN VAL ELSE '*********' END;
実稼働アカウントでは、マスクされていない値を表示できるようにし、他のすべてのアカウント(例: 開発、テスト)では、マスクされた値を表示できるようにします。
case when current_account() in ('<prod_account_name>') then val else '*********' end;
権限のないユーザーの場合は NULL を返します。
case when current_role() IN ('ANALYST') then val else NULL end;
権限のないユーザーに対して静的なマスク値を返します。
CASE WHEN current_role() IN ('ANALYST') THEN val ELSE '********' END;
権限のないユーザーに対して SHA2 , SHA2_HEX を使用してハッシュ値を返します。マスキングポリシーでハッシュ関数を使用すると、競合が発生する可能性があります。したがって、このアプローチには注意が必要です。詳細については、 高度な列レベルのセキュリティトピック をご参照ください。
CASE WHEN current_role() IN ('ANALYST') THEN val ELSE sha2(val) -- return hash of the column value END;
部分的マスクまたは完全なマスクを適用します。
CASE WHEN current_role() IN ('ANALYST') THEN val WHEN current_role() IN ('SUPPORT') THEN regexp_replace(val,'.+\@','*****@') -- leave email domain unmasked ELSE '********' END;
タイムスタンプの使用。
case WHEN current_role() in ('SUPPORT') THEN val else date_from_parts(0001, 01, 01)::timestamp_ntz -- returns 0001-01-01 00:00:00.000 end;重要
現在Snowflakeでは、マスキングポリシーを定義してタイムスタンプをターゲットにし、文字列(例:
***MASKED***
)を返すなど、入力と出力でデータ型が異なるマスキングポリシーをサポートしていません。入力と出力のデータ型は一致している必要があります。ワークアラウンドとしては、実際のタイムスタンプ値を作成されたタイムスタンプ値でキャストします。詳細については、 DATE_FROM_PARTS および CAST、 :: をご参照ください。
UDF の使用:
CASE WHEN current_role() IN ('ANALYST') THEN val ELSE mask_udf(val) -- custom masking function END;
バリアントデータについて:
CASE WHEN current_role() IN ('ANALYST') THEN val ELSE OBJECT_INSERT(val, 'USER_IPADDRESS', '****', true) END;
カスタム資格テーブルの使用。WHEN 句での EXISTS の使用に注意してください。マスキングポリシー本文にサブクエリを含める場合は、常に EXISTS を使用してください。Snowflakeがサポートするサブクエリの詳細については、 サブクエリの操作 をご参照ください。
CASE WHEN EXISTS (SELECT role FROM <db>.<schema>.entitlement WHERE mask_method='unmask' AND role = current_role()) THEN val ELSE '********' END;
ENCRYPT または ENCRYPT_RAW のいずれかで以前に暗号化されたデータに DECRYPT を使用し、暗号化されたデータにパスフレーズを使用します。
case when current_role() in ('ANALYST') then DECRYPT(val, $passphrase) else val -- shows encrypted value end;
JSON における JavaScript UDFs の使用(バリアント):
この例では、JavaScript UDF は JSON 文字列の位置データをマスクします。UDF とマスキングポリシーでデータ型を VARIANT に設定することが重要です。
-- Flatten the JSON data create or replace table <table_name> (v variant) as select value::variant from @<table_name>, table(flatten(input => parse_json($1):stationLocation)); -- JavaScript UDF to mask latitude, longitude, and location data CREATE OR REPLACE FUNCTION full_location_masking(v variant) RETURNS variant LANGUAGE JAVASCRIPT AS $$ if ("latitude" in V) { V["latitude"] = "**latitudeMask**"; } if ("longitude" in V) { V["longitude"] = "**longitudeMask**"; } if ("location" in V) { V["location"] = "**locationMask**"; } return V; $$; -- Grant UDF usage to ACCOUNTADMIN grant ownership on function FULL_LOCATION_MASKING(variant) to role accountadmin; -- Create a masking policy using JavaScript UDF create or replace masking policy json_location_mask as (val variant) returns variant -> CASE WHEN current_role() IN ('ANALYST') THEN val else full_location_masking(val) -- else object_insert(val, 'latitude', '**locationMask**', true) -- limited to one value at a time END;
他のコンテキスト関数とロール階層の使用例については、 高度な列レベルのセキュリティトピック を参照してください。