Snowflakeでタグを介してマスキングポリシーを付与できる「Tag-based Masking Policies」を試してみた #SnowflakeDB

2022.12.14

※本エントリは、Snowflakeをもっと使いこなそう! Advent Calendar 2022の14日目の記事となります。

さがらです。

Snowflakeでタグを介してMasking Policyを付与できるTag-based Masking Policiesを試してみたので、その内容をまとめてみます。

Tag-based Masking Policiesとは

前提:Masking Policyとは

まず、前提となるMasking Policyですが、SnowflakeのDynamic Data Maskingを適用させる際に必要なポリシーです。

例えば、Dynamic Data Maskingをあるカラムに対して適用することで、Aというロールには全ての値を見せるが、Bというロールにはすべて「*」などでマスキングした値を見せる、ということが可能です。

以下は、Masking Policyのサンプルです。

  • Masking Policyのサンプルクエリ
-- Masking Policyの作成
use role sagara_admin_role;
create or replace masking policy first_name_mask as (val string) returns string ->
  case
    when current_role() in ('SAGARA_ADMIN_ROLE') then val
    else '*********'
  end;

-- 対象のカラムへ適用
alter table if exists customers modify column first_name set masking policy first_name_mask;
  • カラムの値を見ることが出来るsagara_admin_roleからのクエリ実行

  • カラムの値を見ることが出来ないsagara_dev_roleからのクエリ実行

Tag-based Masking Policiesとは

前述のMasking Policyですが、カラム一つずつに対してalter table文を発行しないと行けないため、少々運用に手間がかかるところが難点でした。

そこで、今回試すTag-based Masking Policiesの出番です!

Tag-based Masking Policiesは、タグを介してMasking Policyを付与できる機能です。

メリットとしては、下記のような点が挙げられます。

  • Masking Policyの付与はタグに一度行うだけで済む
  • テーブルに対してTag-based Masking Policiesを適用すると、そのテーブルで新しいカラムが追加された際にデータ型が一致するならば、自動でタグの付与とMasking Policyの適用までしてくれる

より詳細については、公式Docも併せてご確認ください。

試してみた

ということで、Tag-based Masking Policiesを試してみたいと思います!

試すこと

以下のテーブルのFIRST_NAME列とLAST_NAME列に対して、以下の内容でTag-based Masking Policiesを適用してみます。

  • sagara_admin_roleの場合:カラムの値を見せる
  • それ以外のROLLの場合:カラムの値を見せない(アスタリスクでマスキングする)

必要な権限の付与

Tag-based Masking Policiesを管理するロールは、「タグを作成・付与できる権限」「Masking Policyを作成・付与できる権限」が必要となります。他には、対象のデータベース・スキーマへのUSAGE権限、対象のテーブルへのSELECT権限が必要となるため、ご注意ください。

-- Masking Policyに必要な権限の付与
use role accountadmin;
grant create masking policy on schema sagara_rawdata_db.jaffle_shop to role sagara_admin_role;
grant apply masking policy on account to role sagara_admin_role;

-- タグ管理に必要な権限の付与
use role accountadmin;
grant apply tag on account to role sagara_admin_role;
grant create tag on schema sagara_rawdata_db.jaffle_shop to role sagara_admin_role;

Masking Policyの作成

続いて、Masking Policyを作成します。

-- Masking Policyの作成
use role sagara_admin_role;
create or replace masking policy name_mask as (val string) returns string ->
  case
    when current_role() in ('SAGARA_ADMIN_ROLE') then val
    else '*********'
  end;

タグの作成・タグへのMasking Policyの適用

続いて、タグを作成し、作成したタグに対してMasking Policyを適用します。

-- タグの作成
use role sagara_admin_role;
create or replace tag name_tag;

-- タグへのMasking Policyの適用
alter tag name_tag set masking policy name_mask;

検証その1:カラムレベルにタグ付け

まず、カラムレベルにタグ付けすることを考えてみます。

以下のクエリを実行して、FIRST_NAME列とLAST_NAME列に対してタグ付けを行います。

-- カラムレベルにタグ付け
use role sagara_admin_role;
alter table customers modify column first_name set tag name_tag = 'firstname';
alter table customers modify column last_name set tag name_tag = 'lastname';

この上で、各ロールからクエリを実行してみます。使用するロールによって、正しくマスキングされていることがわかりますね!

  • カラムの値を見ることが出来るsagara_admin_roleからのクエリ実行
-- 値を見ることが出来るロールでの実行
use role sagara_admin_role;
select * from customers;

  • カラムの値を見ることが出来ないsagara_dev_roleからのクエリ実行
-- 値を見ることが出来ないロールでの実行
use role sagara_dev_role;
select * from customers;

検証その2:テーブルレベルにタグ付け

続いて、Tag-based Masking Policiesを活かした、テーブルレベルにタグ付けを行い、テーブル内の該当する型を持つカラムに対して一括でMasking Policyを適用してみます。(検証その1で行ったカラムレベルのタグ付けは、事前にUNSETしております)

-- テーブルレベルにタグ付け
use role sagara_admin_role;
alter table customers set tag name_tag = 'firstname and lastname';

この上で、各ロールからクエリを実行してみます。テーブルレベルにタグを適用しても、該当する型を持つカラムにおいて、正しくマスキングされていることがわかりますね!

注意点としては、テーブルレベルにMasking Policyを付与したタグを適用する場合、タグに紐づいているMasking Policyの型(String、Numberなど)と一致するカラム全てにMasking Policyが適用されてしまいます!この点だけご注意ください。

  • カラムの値を見ることが出来るsagara_admin_roleからのクエリ実行
-- 値を見ることが出来るロールでの実行
use role sagara_admin_role;
select * from customers;

  • カラムの値を見ることが出来ないsagara_dev_roleからのクエリ実行
-- 値を見ることが出来ないロールでの実行
use role sagara_dev_role;
select * from customers;

最後に

Snowflakeでタグを介してMasking Policyを付与できるTag-based Masking Policiesを試してみました。

運用面を考慮すると、ただのMasking Policyを各カラムに適用するのではなく、基本的にはTag-based Masking Policiesを使う方が良いと思います!ぜひご活用ください。