カテゴリ:

テーブル、ビュー、シーケンス DDL

CREATE MASKING POLICY

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

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

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

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

構文

CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <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 または外部関数に USAGE を持っている必要があります。マスキングポリシーが適用されている列をクエリするユーザーは、 UDF または外部関数に USAGE を持っている必要はありません。

COMMENT = '文字列リテラル'

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

使用上の注意

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

  • マスキングポリシー本文にサブクエリを含むマスキングポリシーの場合は、 WHEN 句で EXISTS を使用します。代表的な例については、 セクションのカスタム資格テーブルの例をご参照ください。

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

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

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

条件式関数コンテキスト関数、および 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_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 に設定することが重要です。

-- 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;

他のコンテキスト関数とロール階層の使用例については、 高度な列レベルのセキュリティトピック を参照してください。