どーも、データアナリティクス事業本部コンサルティングチームの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つになります。