Redshift の動的データマスキング（DDM）を試してみる

# やりたいこと
プレビュー中の Amazon Redshift 動的データマスキング（DDM）を試してみる。

[Amazon Redshift が動的データマスキングのサポートを開始 (プレビュー)](https://aws.amazon.com/jp/about-aws/whats-new/2022/11/amazon-redshift-support-dynamic-data-masking-preview/)
[Dynamic data masking (preview)](https://docs.aws.amazon.com/redshift/latest/dg/t_ddm.html)

# 何者か

PII 等の機密情報を、クエリー実行時に動的にマスキングするポリシーを定義する機能。

なお PII 検知とマスキングの機能は [AWS Glue にもある](https://docs.aws.amazon.com/ja_jp/glue/latest/ug/detect-PII.html)が、実装は異なる。

|機能|Redshift DDM|Glue PII Detection|
|:---|:---|:---|
|PIIの検知方法|手動。DDMポリシーに基づき列を明示指定|自動。機械学習とパターンマッチングで自動検知|
|PIIのマスキング方法|指定したルールに基づく|指定したルールに基づく|
|マスキングのタイミング|クエリー時|ETL時|
|結果の永続性|表示のみ|変換して永続化|
|ユーザーごとの可視性制御|DDMポリシーで制御可|この機能では不可（Lake FormationのCLSで制御）|

このように、DDM は永続的な**変換**ではなく、あくまでクエリー時の**オンザフライでのマスキング**を意図している。
PII 対応というと、分析環境に持ち込まないよう発生元でコントロールするとか、ETL で変換を行ってから格納するなどとかく手がかかりがちだが、データ発生元の処理や ETL、業務クエリーに手を加えることなく（あるいは専用のツールやサービスを購入することなく）、ポリシーをかぶせるだけで PII を含む機密データ対応ができる点が DDM の魅力と言えそうだ。

# ステップバイステップ

## 1. preivew クラスターの作成

今回は Redshift Serverless を使う。

- サーバーレスのコンソールに移動し、**サーバーレスダッシュボード**の画面を表示する。

- バナーから preview ワークグループを作成する。
![スクリーンショット 2022-12-20 8.48.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/1c45d292-6942-afad-9a12-ed6c4337d8ce.png)

- `workgroup-preview`という名称でワークグループを作成（VPCその他はデフォルト）。

- `namespace-preview`という名称で名前空間を作成（同上）。

- クエリエディタv2と IAM 認証（Federated User）を用いてクラスターに接続する。

## 2. データの準備

公式の例を参考に、クレジットカード番号を sha2 でハッシュする DDM を作成する。
まずはデータとユーザーの準備。

- クレジットカード番号テーブルを作る。

```sql
/* テーブル作成 */
CREATE TABLE credit_cards (
  customer_id INT,
  credit_card TEXT
);

/* データ挿入 */
INSERT INTO credit_cards
VALUES
  (100, '4532993817514842'),
  (100, '4716002041425888'),
  (102, '5243112427642649'),
  (102, '6011720771834675'),
  (102, '6011378662059710'),
  (103, '373611968625635')
;

/* SELECT 権限付与 */
GRANT SELECT ON credit_cards TO PUBLIC;
```

- 検証用ユーザーとロールを作る。

このユーザーには DDM ポリシーを適用し、マスクされた状態のデータのみを読める状態にする想定。
また、DDM をユーザーに紐付けるためのロールを作成する。

```sql
/* ユーザー作成 */
CREATE USER ddm_test_user WITH PASSWORD 'Password12358!';

/* ロール作成 */
CREATE ROLE ddm_test_role;

/* ロール付与 */
GRANT ROLE ddm_test_role TO ddm_test_user;
```

## 3. DDM の設定

DDM ポリシーを書き、ユーザーに紐付ける。

- DDM ポリシーを作成する。

```sql
CREATE MASKING POLICY ddm_credit_card_sha2
WITH (credit_card varchar(256)) 
USING (sha2(credit_card + 'testSalt', 256));
```

- DDM をロール経由で検証用ユーザーに紐付ける。

```sql
ATTACH MASKING POLICY ddm_credit_card_sha2
ON credit_cards(credit_card)
TO ROLE ddm_test_role
PRIORITY 10;
```

## 4. テスト

- まず、管理者ユーザーで検索。

```sql
SELECT * FROM credit_cards;
```

![スクリーンショット 2022-12-20 16.13.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/ec23b262-08b4-b6ca-a75f-6c86b6d7e6b5.png)

- 接続をいったん解除し、検証用ユーザー（`ddm_test_user`）に切り替えてから再度検索。

![スクリーンショット 2022-12-20 16.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/b11aa117-862a-7441-d568-649e66db3348.png)

```sql
SELECT * FROM credit_cards;
```

![スクリーンショット 2022-12-20 16.12.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/fb5c29dd-539d-e036-75ae-91b3a6da5dc6.png)

無事マスキングされていることがわかる。

# 制約

2023年1月現在、プレビューであり、以下の制約がある。
- リージョンに制限がある（バージニア北部、オハイオ、オレゴン、アイルランド、ストックホルム、**東京**）
- preview モードで Redshift クラスターを作成する必要がある
    - DDM を使うには、`preview_2022`を選択する
    - 本番利用は不可

また、以下のシステムテーブルが用意されているが、Redshift Serverless ではサポートされていない。

```sql
/* DDM の一覧 */
SELECT * FROM svv_masking_policy;

/* DDM のアタッチ状況一覧 */
SELECT * FROM svv_attached_masking_policy; 
```

念のため Serverless でサポートされている[システムテーブル/ビューの一覧](https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-monitoring.html#serverless_views-monitoring)をチェックしてみたが、確かに載ってなかった。

他にも、[公式ドキュメント](https://docs.aws.amazon.com/redshift/latest/dg/t_ddm.html)にいくつか留意点がまとめられている。

# まとめ
ETL なしで動的にマスキングができる点、ユーザーごとに可視性をコントロールできる点は便利だと思う。
あとは日本語データの処理の可否が気になるところだが、以下のようなサンプルデータで同じ手順を試してみたところ、一応問題なく通った。

```sql
CREATE TABLE name_jp (
  customer_id INT,
  customer_name TEXT
);
INSERT INTO name_jp
VALUES
  (001, '山田太郎'),
  (002, '下村花'),
  (003, '植村幸三')
;
```

![スクリーンショット 2022-12-20 16.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/acf1af18-220d-9fec-c248-e3918363102f.png)

![スクリーンショット 2022-12-20 16.34.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/c0f8867b-4401-d035-d08c-e63c6462214e.png)