CREATE MASKING POLICY

現在または指定のスキーマに新しいマスキングポリシーを作成するか、既存のマスキングポリシーを置き換えます。

マスキングポリシーを作成した後、 ALTER TABLE ... ALTER COLUMN コマンドを使用してテーブルの列に適用するか、 ALTER VIEW コマンドを使用してビューの列に適用します。

こちらもご参照ください。

集中、ハイブリッド、または分散のアプローチの選択高度な列レベルのセキュリティトピック

マスキングポリシー DDL

構文

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> -> <expression_on_arg_name>
[ COMMENT = '<string_literal>' ];

パラメーター

name

マスキングポリシーの識別子。スキーマに対して一意である必要があります。

識別子の値はアルファベットで始まる必要があり、識別子文字列全体が二重引用符で囲まれていない限り、スペースや特殊文字を含めることはできません(例: "My object")。二重引用符で囲まれた識別子も大文字と小文字が区別されます。

詳細については、 識別子の要件 をご参照ください。

AS ( arg_name_to_mask arg_type_to_mask [ , arg_1 arg_type_1 ... ] )

マスキングポリシーの署名。クエリの実行時に評価する入力列とデータ型を指定します。

詳細については、 データ型 をご参照ください。

arg_name_to_mask arg_type_to_mask

最初の列 とそのデータ型は 常に、後続のポリシー条件でマスクまたはトークン化する列のデータ型の値を示します。

仮想列は、条件付きマスキングポリシーの最初の列引数としては指定 できない ことに注意してください。

[ , arg_1 arg_type_1 ... ]

ポリシー条件が、クエリ結果の各行にある最初の列のデータをマスクまたはトークン化する必要があるかどうかを判断するために、評価する条件列とそのデータ型を指定します。

これらの追加の列とデータ型が指定されていない場合、Snowflakeはポリシーを通常のマスキングポリシーとして評価します。

RETURNS arg_type_to_mask

戻りデータ型は、入力列として指定された最初の列の入力データ型と一致する必要があります。

expression_on_arg_name

データを変換する SQL 式。

式には、 条件式関数 を含めて条件付きロジック、組み込み関数を表すか、 UDFs を含めてデータを変換することができます。

マスキングポリシー本体内で UDF または外部関数が使用されている場合、ポリシー所有者は UDF または外部関数に USAGE を持っている必要があります。UDF または外部関数に対する USAGE 権限は、マスキングポリシーが適用されている列のクエリに使用されるロールには必要ありません。

条件付きマスキングポリシー本体内で UDF または外部関数が使用されている場合、ポリシー所有者は UDF または外部関数に OWNERSHIP を持っている必要があります。条件付きマスキングポリシーが適用されている列をクエリするユーザーは、 UDF または外部関数に USAGE を持っている必要はありません。

COMMENT = 'string_literal'

マスキングポリシーのコメントを追加するか、既存のコメントを上書きします。

アクセス制御の要件

この SQL コマンドの実行に使用される ロール には、少なくとも次の 権限 が必要です。

権限

オブジェクト

メモ

CREATE MASKING POLICY

スキーマ

スキーマ内の任意のオブジェクトを操作するには、親データベースとスキーマに対する USAGE 権限も必要であることに注意してください。

指定された権限のセットを使用してカスタムロールを作成する手順については、 カスタムロールの作成 をご参照ください。

セキュリティ保護可能なオブジェクト に対して SQL アクションを実行するためのロールと権限付与に関する一般的な情報については、 Snowflakeのアクセス制御 をご参照ください。

マスキングポリシー DDL と権限の詳細については、 列レベルのセキュリティの管理 をご参照ください。

使用上の注意

  • 既存のマスキングポリシーを置き換えるために、ポリシーの現在の定義を確認する必要がある場合は、 GET_DDL 関数を呼び出すか、 DESCRIBE MASKING POLICY コマンドを実行します。

  • マスキングポリシー本文にサブクエリを含むマスキングポリシーの場合は、 CASE 関数の WHEN 分岐で EXISTS を使用します。代表的な例については、 通常のマスキングポリシー セクション(このトピック内)のカスタム資格テーブルの例をご参照ください。

  • 特定のテーブルまたはビュー列は、マスキングポリシー署名または行アクセスポリシー署名のいずれかで指定できます。つまり、マスキングポリシー署名と行アクセスポリシー署名の両方で同時に同じ列を指定することはできません。

    詳細については、 CREATE ROW ACCESS POLICY をご参照ください。

  • データ共有プロバイダーは、 リーダーアカウント でマスキングポリシーを作成できません。

  • マスキングポリシーで UDF を使用する場合は、列、 UDF、およびマスキングポリシーのデータ型が一致していることを確認します。詳細については、 マスキングポリシー内のユーザー定義関数 をご参照ください。

  • メタデータについて。

    注意

    Snowflakeサービスを使用する場合、お客様は、個人データ(ユーザーオブジェクト向け以外)、機密データ、輸出管理データ、またはその他の規制されたデータがメタデータとして入力されていないことを確認する必要があります。詳細については、 Snowflakeのメタデータフィールド をご参照ください。

  • CREATE OR REPLACE <オブジェクト> ステートメントはアトミックです。つまり、オブジェクトが置き換えられると、古いオブジェクトの削除と新しいオブジェクトの作成が1つのトランザクションで処理されます。

通常のマスキングポリシー

条件式関数コンテキスト関数、および 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 における JavaScript UDFs の記述 の使用(バリアント):

この例では、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_ROLEadmin カスタムロールであるか、可視性列の値が 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_ROLEadmin カスタムロールであり、別の列の値が 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;