Redshiftの動的データマスキング(DDM)の機能を試してみた(Preview) #reinvent

2022.12.21

この記事は公開されてから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つになります。

参考