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> -> <body>
[ COMMENT = '<string_literal>' ]
[ EXEMPT_OTHER_POLICIES = { TRUE | FALSE } ]
Copy

必須パラメーター

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 を含めてデータを変換することができます。

UDFs と外部関数の場合:

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

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

ポリシー body のコンテキスト関数の場合:

ポリシーが CURRENT_DATABASE または CURRENT_SCHEMA 関数を呼び出すとき、関数は、 USE <オブジェクト> コマンドで指定した、または Snowsight のコンテキストセレクターで選択したセッションのデータベースまたはスキーマではなく、保護されたテーブルまたはビューを含むデータベースまたはスキーマに対して評価されます。

オプションのパラメーター

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 を使用します。代表的な例については、 通常のマスキングポリシー セクション(このトピック内)のカスタム資格テーブルの例をご参照ください。

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

    詳細については、 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;
Copy

実稼働 アカウント では、マスクされていない値を表示できるようにし、他のすべてのアカウント(例: 開発、テスト)では、マスクされた値を表示できるようにします。

case
  when current_account() in ('<prod_account_identifier>') then val
  else '*********'
end;
Copy

権限のないユーザーの場合は NULL を返します。

case
  when current_role() IN ('ANALYST') then val
  else NULL
end;
Copy

権限のないユーザーに対して静的なマスク値を返します。

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

権限のないユーザーに対して SHA2 , SHA2_HEX を使用してハッシュ値を返します。マスキングポリシーでハッシュ関数を使用すると、競合が発生する可能性があります。したがって、このアプローチには注意が必要です。詳細については、 高度な列レベルセキュリティのトピック をご参照ください。

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE sha2(val) -- return hash of the column value
END;
Copy

部分的マスクまたは完全なマスクを適用します。

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  WHEN current_role() IN ('SUPPORT') THEN regexp_replace(val,'.+\@','*****@') -- leave email domain unmasked
  ELSE '********'
END;
Copy

タイムスタンプの使用。

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

重要

現在Snowflakeでは、マスキングポリシーを定義してタイムスタンプをターゲットにし、文字列(例: ***MASKED***)を返すなど、入力と出力でデータ型が異なるマスキングポリシーをサポートしていません。入力と出力のデータ型は一致している必要があります。

ワークアラウンドとしては、実際のタイムスタンプ値を作成されたタイムスタンプ値でキャストします。詳細については、 DATE_FROM_PARTS および CAST、 :: をご参照ください。

UDF の使用:

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE mask_udf(val) -- custom masking function
END;
Copy

バリアントデータについて:

CASE
   WHEN current_role() IN ('ANALYST') THEN val
   ELSE OBJECT_INSERT(val, 'USER_IPADDRESS', '****', true)
END;
Copy

カスタム資格テーブルの使用。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;
Copy

ENCRYPT または ENCRYPT_RAW のいずれかで以前に暗号化されたデータに DECRYPT を使用し、暗号化されたデータにパスフレーズを使用します。

case
  when current_role() in ('ANALYST') then DECRYPT(val, $passphrase)
  else val -- shows encrypted value
end;
Copy

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

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

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

Snowflakeは次を返します。

---+--------------------+
 A |         B          |
---+--------------------+
 1 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
 2 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
---+--------------------+
Copy

列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) |
---+----------------------+
Copy

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

例: 条件付きマスキングポリシー

次の例では、 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;
Copy

次の例では、 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;
Copy

例: 行アクセスポリシーまたは条件付きマスキングポリシーでマスクされた列を許可する

メールアドレスの表示、メールアドレスドメインのみの表示、またはマスクされた固定値の表示のいずれかを許可するマスキングポリシーを置き換えます。

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

このポリシーを列に設定できるようになりました。行アクセスポリシーまたは条件付きマスキングポリシーは、必要に応じて、このマスキングポリシーによって保護された列を参照できます。