
Redshiftの動的データマスキング(DDM)の機能を試してみた(Preview) #reinvent
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どーも、データアナリティクス事業本部コンサルティングチームのsutoです。
re:Invent2022で発表された「Amazon Redshift が動的データマスキングのサポートを開始 (プレビュー)」について実際に触ってみました。
※12月20日時点のパブリックプレビューの内容となりますのであらかじめご了承ください。
Amazon Redshift の動的データマスキング機能は 2022 年 11 月 29 日現在において、プレビューのステータスです。この機能は、運用環境ではなく、テスト クラスターでのみ使用することをお勧めします。パブリック プレビューは 2023 年 2 月 28 日に終了します。プレビュー クラスターとプレビュー サーバーレス ワークグループおよび名前空間は、プレビューの終了から 2 週間後に自動的に削除されます。
準備
Mockarooというサイトを利用して、以下のような9列・1000行のデータセットを作成しました。今回はこのデータセットをRedshiftにロードして実施していきます。

Preview用Redshiftクラスターの作成は以下の「Create preview cluster」を選択します。

作成ウィザードで、 Preview trackに「preview2022」を選択してクラスターを作成します。

やってみた
今回は、電話番号(phone列)の表示を制御するというテーマで検証してみます。
リソース構築
Redshiftにスーパーユーザーでログインし、スキーマ(ddmtest)と、テーブル(phone_number)を作成し、データを取り込んだ状態からスタートします
-- スキーマとテーブル作成 CREATE SCHEMA ddmtest; SET search_path to ddmtest; CREATE TABLE phone_number ( id INT, phone TEXT, flag BOOLEAN ); -- テーブルにデータロード COPY phone_number FROM 's3://<detail-bucket-name>/<detail-object-key>' IAM_ROLE '<redshift_role>' CSV IGNOREHEADER 1 ENCODING UTF8 ;
複数のユーザーを用意してphone列のデータマスキングレベルごとにRoleを作成して以下のようにアタッチしている状態を作ります。
※ロールのPriorityは数値の高い方が優先されて適用されます。

- まずユーザーとロールを作成します
--スキーマ、テーブルにSELECT出来る権限を付与(検証なので手っ取り早くTO PUBLICを使います) GRANT USAGE ON SCHEMA ddmtest TO PUBLIC; GRANT SELECT ON phone_number TO PUBLIC; --ユーザー作成 CREATE USER test1 WITH PASSWORD 'Password123!'; CREATE USER test2 WITH PASSWORD 'Password123!'; CREATE USER test3 WITH PASSWORD 'Password123!'; CREATE USER test4 WITH PASSWORD 'Password123!'; -- ロールを作成 CREATE ROLE cust_srvc_role; CREATE ROLE frdprvnt_role; CREATE ROLE auditor_role; -- note that public role exist by default. -- ユーザーにロールをアタッチ GRANT ROLE cust_srvc_role to test2; GRANT ROLE frdprvnt_role to test3; GRANT ROLE auditor_role to test4;
- 次にマスキングポリシーを作成します
-- 1 電話番号を全てマスキングするポリシー
CREATE MASKING POLICY Mask_CC_Full
WITH (phone VARCHAR(256))
USING ('XXX-XXX-XXXX');
-- 2 テキストより左から3桁のみを表示させる処理を行う定義関数を作成
CREATE FUNCTION REDACT_PHONE (text)
returns text
immutable
as $$
select left($1,4)||'XXX-XXXX'
$$ language sql;
-- 3 2の定義関数を実行し、市外局番のみ表示させる部分マスキングを実現するポリシー
CREATE MASKING POLICY Mask_CC_Partial
WITH (phone VARCHAR(256))
USING (REDACT_PHONE(phone));
-- 4 flag列のtrue/falseで判断し、表示/NULL加工をするマスキングポリシー
CREATE MASKING POLICY Mask_CC_Conditional
WITH (flag BOOLEAN, phone VARCHAR(256))
USING (CASE WHEN flag
THEN phone
ELSE Null
END);
-- 5 マスキングを行わないポリシー
CREATE MASKING POLICY Mask_CC_Raw
WITH (phone varchar(256))
USING (phone);
- テーブルまたは列のマスキング ポリシーをユーザーまたはロールにアタッチします
-- デフォルトのポリシーはフルマスキングポリシーに設定 -- より高い優先順位のマスキング・ポリシーがユーザーまたはそのロールに付加されていない限り、すべてのユーザーにこのマスキング・ポリシーが表示されます ATTACH MASKING POLICY Mask_CC_Full ON phone_number(phone) TO PUBLIC; -- cust_srvc_roleロールを持つユーザーは、一部の番号(市外局番のみ)を見ることができる ATTACH MASKING POLICY Mask_CC_Partial ON phone_number(phone) TO ROLE cust_srvc_role PRIORITY 10; -- frdprvnt_roleロールを持つユーザーは、flag列がtrueの行のみ番号を見ることができる ATTACH MASKING POLICY Mask_CC_Conditional ON phone_number(phone) USING (flag, phone) TO ROLE frdprvnt_role PRIORITY 20; -- auditor_roleロールを持つユーザーは、すべての番号を見ることができる -- users with auditor_role role can see raw credit card numbers ATTACH MASKING POLICY Mask_CC_Raw ON phone_number(phone) TO ROLE auditor_role PRIORITY 30;
実際にテストしてみる
クエリエディタv2から実際に検証してみます。
- マスキング ポリシーが作成されていることを確認
SELECT * FROM svv_masking_policy;

- マスキング ポリシーがアタッチされていることを確認します
SELECT * FROM svv_attached_masking_policy;

- cust_srvc_roleがアタッチされているユーザーtest2でクエリを実行すると、全レコードで部分マスキングになっています
SET SESSION AUTHORIZATION test2; SELECT * FROM phone_number;

- frdprvnt_roleがアタッチされているユーザーtest3でクエリを実行すると、flag列がtrueのレコードのみ部分マスキングになっています
SET SESSION AUTHORIZATION test3; SELECT * FROM phone_number;

- auditor_roleがアタッチされているユーザーtest4でクエリを実行すると、マスキングされず全レコードの番号が表示されています
SET SESSION AUTHORIZATION test4; SELECT * FROM phone_number;

- ロールがアタッチされていないユーザーtest1は、デフォルトポリシーが適用となり、全レコードがフルマスキングされて表示されています
SET SESSION AUTHORIZATION test1; SELECT * FROM phone_number;

マスキング ポリシーを変更したいときの注意点
作成したマスキングポリシーの内容を変更したい時は、一度既存設定を削除して再作成する必要があります(ALTERのような更新のかたちで変更はできません)
--ポリシーをロールからデタッチするクエリの例 DETACH MASKING POLICY Mask_CC_Partial ON credit_cards(credit_card) FROM ROLE cust_srvc_role; -- ポリシーを削除するクエリの例 DROP MASKING POLICY Mask_CC_Partial; -- あとは改めてポリシー作成のクエリを実行する
最後に
re:Invent2022で発表されたRedshiftのDynamic Data Masking機能(Preview)を実際に試してみました。
データマスキングといえばGlueジョブやGlue DataBrewにデータソースからPII列を判別してデータを加工することができる機能がありましたが、今回のアップデートによりRedshiftでクエリを実行して指定したカラムのデータを直接的にマスキングする方法もとれるようになりました。
ユースケースとして、すでに大規模なデータを蓄積している既存テーブルに対してデータマスキングを行う必要が出てきた際、ETLジョブを駆使して加工後データを洗い替えするよりも今回のDDM機能を利用する方が運用負担が少なくて済むかもしれませんね。
しかも、わざわざETLジョブを開発しなくてもRedshiftユーザーにとって使い慣れたSQLやLambda UDFなどでマスキング処理を作成できることもメリットの1つになります。







