CREATE MASKING POLICY¶
現在または指定のスキーマに新しいマスキングポリシーを作成するか、既存のマスキングポリシーを置き換えます。
マスキングポリシーを作成した後、 ALTER TABLE ... ALTER COLUMN コマンドを使用してテーブルの列に適用するか、 ALTER VIEW コマンドを使用してビューの列に適用します。
- こちらもご参照ください。
構文¶
CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <name> AS
( <arg_name_to_mask> <arg_type_to_mask> [ , <arg_1> <arg_type_1> ... ] )
RETURNS <arg_type_to_mask> -> <body>
[ COMMENT = '<string_literal>' ]
[ EXEMPT_OTHER_POLICIES = { TRUE | FALSE } ]
必須パラメーター¶
name
マスキングポリシーの識別子。スキーマに対して一意である必要があります。
識別子の値はアルファベットで始まる必要があり、識別子文字列全体が二重引用符で囲まれていない限り、スペースや特殊文字を含めることはできません(例:
"My object"
)。二重引用符で囲まれた識別子も大文字と小文字が区別されます。詳細については、 識別子の要件 をご参照ください。
AS ( arg_name_to_mask arg_type_to_mask [ , arg_1 arg_type_1 ... ] )
マスキングポリシーの署名。クエリの実行時に評価する入力列とデータ型を指定します。
詳細については、 SQL データ型リファレンス をご参照ください。
arg_name_to_mask arg_type_to_mask
最初の列 とそのデータ型は 常に、後続のポリシー条件でマスクまたはトークン化する列のデータ型の値を示します。
仮想列は、条件付きマスキングポリシーの最初の列引数としては指定 できない ことに注意してください。
[ , arg_1 arg_type_1 ... ]
ポリシー条件が、クエリ結果の各行にある最初の列のデータをマスクまたはトークン化する必要があるかどうかを判断するために、評価する条件列とそのデータ型を指定します。
これらの追加の列とデータ型が指定されていない場合、Snowflakeはポリシーを通常のマスキングポリシーとして評価します。
RETURNS arg_type_to_mask
戻りデータ型は、入力列として指定された最初の列の入力データ型と一致する必要があります。
body
arg_name_to_mask
で指定された列のデータを変換する SQL 式。式には、 条件式関数 を含めて条件付きロジック、組み込み関数を表すか、 UDFs を含めてデータを変換することができます。
マスキングポリシー本体内で UDF または外部関数が使用されている場合、ポリシー所有者は UDF または外部関数に USAGE を持っている必要があります。UDF または外部関数に対する USAGE 権限は、マスキングポリシーが適用されている列のクエリに使用されるロールには必要ありません。
条件付きマスキングポリシー本体内で UDF または外部関数が使用されている場合、ポリシー所有者は UDF または外部関数に OWNERSHIP を持っている必要があります。条件付きマスキングポリシーが適用されている列をクエリするユーザーは、 UDF または外部関数に USAGE を持っている必要はありません。
オプションのパラメーター¶
COMMENT = 'string_literal'
マスキングポリシーのコメントを追加するか、既存のコメントを上書きします。
EXEMPT_OTHER_POLICIES = TRUE | FALSE
使用状況に応じて、次のいずれか。
行アクセスポリシーまたは条件付きマスキングポリシーが、このマスキングポリシーによってすでに保護されている列を参照できるかどうかを指定します。
仮想列に割り当てられたマスキングポリシーが、仮想列により継承された VALUE 列のマスキングポリシーを上書きするかどうかを指定します。外部テーブルを操作する場合は、 VALUE 列を保護するマスキングポリシーでこのプロパティを指定します。
TRUE
異なるポリシーによるマスクされた列を参照できるようにするか、仮想列に設定されたマスキングポリシーが外部テーブルの VALUE 列から仮想列が継承するマスキングポリシーを上書きできるようにします。
FALSE
異なるポリシーがマスクされた列を参照できないようにするか、仮想列に設定されたマスキングポリシーが、外部テーブルの VALUE 列から仮想列に継承するマスキングポリシーを上書きできないようにします。
次の点に注意してください。
マスキングポリシーのこのプロパティの値は、テーブルまたはビューにマスキングポリシーを設定した後は変更できません。このプロパティ設定の値を更新するには、マスキングポリシーで CREATE OR REPLACE MASKING POLICY ステートメントを実行します。
プロパティが true に設定されている場合、ポリシーで GET_DDL 関数を呼び出した出力に含まれます。
アクセス制御の要件¶
この SQL コマンドの実行に使用される ロール には、少なくとも次の 権限 が必要です。
権限 |
オブジェクト |
メモ |
---|---|---|
CREATE MASKING POLICY |
スキーマ |
スキーマ内の任意のオブジェクトを操作するには、親データベースとスキーマに対する USAGE 権限も必要であることに注意してください。
指定された権限のセットを使用してカスタムロールを作成する手順については、 カスタムロールの作成 をご参照ください。
セキュリティ保護可能なオブジェクト に対して SQL アクションを実行するためのロールと権限付与に関する一般的な情報については、 アクセス制御の概要 をご参照ください。
マスキングポリシーで EXEMPT_OTHER_POLICIES
プロパティを指定する場合、マスキングポリシーを所有するロール(つまり、ポリシーに対する OWNERSHIP 権限を持つロール)は、行アクセスポリシーまたは条件付きマスキングポリシーを所有するロールのロール階層にある必要があります。
たとえば、ポリシー管理者のカスタムロールは、次のように ロール階層 を形成できます。
masking_admin
»rap_admin
» SYSADMIN
masking_admin
»cond_masking_admin
» SYSADMIN
条件:
masking_admin
行アクセスポリシーまたは条件付きマスキングポリシーの署名で指定される列に設定されるマスキングポリシーを所有するカスタムロールを指定します。
rap_admin
行アクセスポリシーを所有するカスタムロールを指定します。
cond_masking_admin
条件付きマスキングポリシーを所有するカスタムロールを指定します。
マスキングポリシー DDL と権限の詳細については、 列レベルのセキュリティの管理 をご参照ください。
使用上の注意¶
既存のマスキングポリシーを置き換えるために、ポリシーの現在の定義を確認する必要がある場合は、 GET_DDL 関数を呼び出すか、 DESCRIBE MASKING POLICY コマンドを実行します。
マスキングポリシー本文にサブクエリを含むマスキングポリシーの場合は、 CASE 関数の WHEN 分岐で EXISTS を使用します。代表的な例については、 通常のマスキングポリシー セクション(このトピック内)のカスタム資格テーブルの例をご参照ください。
ポリシー
body
にマッピングテーブルルックアップが含まれている場合は、一元化されたマッピングテーブルを作成し、保護されたテーブルと同じデータベースにマッピングテーブルを格納します。これは、body
が IS_DATABASE_ROLE_IN_SESSION 関数を呼び出す場合に特に重要です。詳細については、関数の使用上の注意をご参照ください。特定のテーブルまたはビュー列は、マスキングポリシー署名または行アクセスポリシー署名のいずれかで指定できます。つまり、マスキングポリシー署名と行アクセスポリシー署名の両方で同時に同じ列を指定することはできません。
詳細については、 CREATE ROW ACCESS POLICY をご参照ください。
データ共有プロバイダーは、 リーダーアカウント でマスキングポリシーを作成できません。
マスキングポリシーで UDF を使用する場合は、列、 UDF、およびマスキングポリシーのデータ型が一致していることを確認します。詳細については、 マスキングポリシー内のユーザー定義関数 をご参照ください。
メタデータについて。
注意
Snowflakeサービスを使用する場合、お客様は、個人データ(ユーザーオブジェクト向け以外)、機密データ、輸出管理データ、またはその他の規制されたデータがメタデータとして入力されていないことを確認する必要があります。詳細については、 Snowflakeのメタデータフィールド をご参照ください。
CREATE OR REPLACE <オブジェクト> ステートメントはアトミックです。つまり、オブジェクトが置き換えられると、単一のトランザクションで、古いオブジェクトが削除されて新しいオブジェクトが作成されます。
例: 通常のマスキングポリシー¶
条件式関数、 コンテキスト関数、および UDFs を使用して、 SQL 式を記述できます。
以下は、 SQL のさまざまな式、関数、およびデータ型を使用してマスキングポリシーの条件を作成する方法を示すポリシー本文の代表的な例です。
これらの例では、主に CURRENT_ROLE コンテキスト関数を使用しています。ポリシー条件でロールのアクティブ化とロール階層が必要な場合は、 IS_ROLE_IN_SESSION を使用します。
完全なマスク:
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_identifier>') 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 (VARIANT) での <JavaScript UDF の使用
この例では、JavaScript UDF は JSON 文字列の位置データをマスクします。UDF とマスキングポリシーでデータ型を VARIANT に設定することが重要です。テーブル列、 UDF、 およびマスキングポリシー署名内のデータ型が一致しない場合、Snowflakeは SQL クエリを解決できないため、エラーメッセージを返します。
-- 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;
GEOGRAPHY データ型の使用:
この例では、マスキングポリシーは、 TO_GEOGRAPHY 関数を使用して、列内のすべての GEOGRAPHY データを、 CURRENT_ROLE が
ANALYST
ではないユーザーのために、カリフォルニア州サンマテオのSnowflakeの経度と緯度である固定小数点に変換します。create masking policy mask_geo_point as (val geography) returns geography -> case when current_role() IN ('ANALYST') then val else to_geography('POINT(-122.35 37.55)') end;GEOGRAPHY データ型の列にマスキングポリシーを設定し、セッションの GEOGRAPHY_OUTPUT_FORMAT 値を
GeoJSON
に設定します。alter table mydb.myschema.geography modify column b set masking policy mask_geo_point; alter session set geography_output_format = 'GeoJSON'; use role public; select * from mydb.myschema.geography;Snowflakeは次を返します。
---+--------------------+ A | B | ---+--------------------+ 1 | { | | "coordinates": [ | | -122.35, | | 37.55 | | ], | | "type": "Point" | | } | 2 | { | | "coordinates": [ | | -122.35, | | 37.55 | | ], | | "type": "Point" | | } | ---+--------------------+列Bのクエリ結果の値は、セッションの GEOGRAPHY_OUTPUT_FORMAT パラメーターによって異なります。たとえば、パラメーターが
WKT
に設定されている場合、Snowflakeは次を返します。alter session set geography_output_format = 'WKT'; select * from mydb.myschema.geography; ---+----------------------+ A | B | ---+----------------------+ 1 | POINT(-122.35 37.55) | 2 | POINT(-122.35 37.55) | ---+----------------------+
他のコンテキスト関数とロール階層の使用例については、 高度な列レベルセキュリティのトピック をご参照ください。
例: 条件付きマスキングポリシー¶
次の例では、 CURRENT_ROLE が admin
カスタムロールであるか、可視性列の値が Public
であるユーザーのマスクされていないデータを返します。他のすべての条件では、マスクされた値が固定されます。
-- Conditional Masking create masking policy email_visibility as (email varchar, visibility string) returns varchar -> case when current_role() = 'ADMIN' then email when visibility = 'Public' then email else '***MASKED***' end;
次の例では、 CURRENT_ROLE が admin
カスタムロールであり、別の列の値が Public
であるユーザーの非トークン化されたデータを返します。他のすべての条件は、トークン化された値になります。
-- Conditional Tokenization create masking policy de_email_visibility as (email varchar, visibility string) returns varchar -> case when current_role() = 'ADMIN' and visibility = 'Public' then de_email(email) else email -- sees tokenized data end;
例: 行アクセスポリシーまたは条件付きマスキングポリシーでマスクされた列を許可する¶
メールアドレスの表示、メールアドレスドメインのみの表示、またはマスクされた固定値の表示のいずれかを許可するマスキングポリシーを置き換えます。
create or replace masking policy governance.policies.email_mask as (val string) returns string -> case when current_role() in ('ANALYST') then val when current_role() in ('SUPPORT') then regexp_replace(val,'.+\@','*****@') else '********' end comment = 'specify in row access policy' exempt_other_policies = true ;
このポリシーを列に設定できるようになりました。行アクセスポリシーまたは条件付きマスキングポリシーは、必要に応じて、このマスキングポリシーによって保護された列を参照できます。