はじめに
こちらの記事でBase DatabaseのデータをAutonomous AI DatabaseのData Transformsを使って変換し、Google Gloud Storageへ出力してみました。次は作成済みのフローにさらにマスキング処理を追加し、出力をGCSではなく、OCI Object StorageにParquet形式にしてみようと思います。
マスキングは簡易なものならData Transformsで文字列関数(replaceやsubstrなど)を用いて実装することもできますが、ここではData Safeを使います。
前提
- こちらの記事のワークフローにマスキング処理を追加し、出力先をObject Storage、フォーマットをParquetに変更します
- 環境の都合でリージョンがKIXからSydneyになっていますが手順は同じです。
- Object Storageのバケットは作成済みです。test_bucketとします。
- Object Storageアクセスのためのクレデンシャルは作成済みです。今回はリソースプリンシパルを利用しました。リソース・プリンシパルについてはAutonomous Databaseでリソースプリンシパルを有効化するが参考になります。
- マスクするデータは こちらの記事のデータ・フローでADBに出力した表customer_transaction_tableのcustomer_nameです。データはこちら。
select * from TESTUSER.CUSTOMER_TRANSACTIONS_TABLE ;
CUSTOMER_ID TRANSACTION_ID CUSTOMER_NAME ADDRESS AMOUNT TRANSACTION_DATE NET_INCOME
----------- -------------- ------------- --------- ------ ----------------- ----------
1 1001 田中 太郎 TOKYO品川区 8000 2024/6/1 0:00:00 7760
3 1003 佐藤 次郎 TOKYO杉並区 12000 2024/6/5 0:00:00 11640
4 1004 高橋 美咲 TOKYO新宿区 6000 2024/6/6 0:00:00 5820
6 1006 中村 亮 TOKYO世田谷区 5200 2024/6/8 0:00:00 5044
7 1007 小林 渚 千葉県千葉市 9500 2024/6/8 0:00:00 9215
8 1008 加藤 翔 TOKYO渋谷区 11000 2024/6/9 0:00:00 10670
9 1009 吉田 麻衣 TOKYO中野区 7000 2024/6/10 0:00:00 6790
1.Data Safeでプライベート・エンドポイントを作成する
ADBがプライベート・エンドポイントにあるため、接続のためにData Safeでプライベート・エンドポイントを作成します。以下のドキュメントを参考にしました。
OCIコンソールでData Safeのターゲット・データベースを選択し、接続オプションで、プライベート・エンドポイントを選択します。

2.Data SafeにADBを登録する
Data Safeのチュートリアルを参考にData SafeにADBを登録します
登録できました。
3.Data Safeでマスキングポリシーまで作成する
Data Safeでマスキングを行う手順はCloudiさんのblogが参考になります。
PL/SQL SDKで同じこともできると思いますが、マスキングの実行以外はGUIで作成するほうがもちろん楽でしょう、ということでマスキング前チェックまでData SafeのUIで実行します。
3-1.必要なロールを付与
ADBではData Safe用のスキーマが提供されているのですが、ドキュメントのGrant Roles to the Oracle Data Safe Service on an Autonomous AI Databaseに記載されているように、マスキングのためのロールDS$DATA_MASKING_ROLEはデフォルトでは付与されていません。
そのため、ADMINでADBにログインし以下を実行します。
EXECUTE DS_TARGET_UTIL.GRANT_ROLE('DS$DATA_MASKING_ROLE');
ちなみに実行していないと後のマスキング前のチェックで権限のエラーが出力されました。

3-2.機密データモデルとマスキング・ポリシーの作成
ウィザードにそって入力します。ターゲット・データベースを選択します。

機密タイプを選択します。機密タイプには定義済みのFULLNAME(氏名)を指定しました。

検出オプションの選択は「サンプル・データを収集、表示および格納」にチェックを入れて、作成しました。

機密データ・モデルが作成できました。機密列としてTESTUSERの表からCUSTOMER_NAMEが検出されています。
続けて「マスキング・ポリシーを作成してください」を選択して、マスキング・ポリシーを作成します。
そのまま作成します。
作成できました。
3-3.マスキング前チェックの実行
マスキング前チェックを実行します。データ・マスキングを選ぶと、「マスキング前チェック」のボタンがあります。クリックし、ターゲット・データベース、マスキング・ポリシーを選択し実行します。
成功しました。
4.Data Safeでマスキングを実行
まずはそのままData SafeのUIで実行してみます。データ・マスキングで「機密データのマスク」ボタンをクリックし、ターゲット・データベース、マスキング・ポリシーを選択し、データのマスクを実行します。
実際にSQLでデータを確認してみると確かにかわっています。
select * from TESTUSER.CUSTOMER_TRANSACTIONS_TABLE
CUSTOMER_ID TRANSACTION_ID CUSTOMER_NAME ADDRESS AMOUNT TRANSACTION_DATE NET_INCOME
----------- -------------- -------------------- --------- ------ ----------------- ----------
6 1006 Mdhxhxeofhwmp TOKYO世田谷区 5200 2024/6/8 0:00:00 5044
3 1003 Uzndpjqh TOKYO杉並区 12000 2024/6/5 0:00:00 11640
8 1008 Aoxad TOKYO渋谷区 11000 2024/6/9 0:00:00 10670
9 1009 Nkvsiaotlqddgxoh TOKYO中野区 7000 2024/6/10 0:00:00 6790
7 1007 Akrosxbofbuhfyhvs 千葉県千葉市 9500 2024/6/8 0:00:00 9215
1 1001 Zhtgswbvp TOKYO品川区 8000 2024/6/1 0:00:00 7760
4 1004 Gfjssguewxlkwssctxby TOKYO新宿区 6000 2024/6/6 0:00:00 5820
これがPL/SQLでできればよしとなります。いったん作成済みのデータフローを実行して、マスキングした表をマスキング前の状態に戻します。
5.PL/SQL SDKでData Safeのマスキングを実行
PL/SQL SDKの使い方はこちらの記事OCI PL/SQL SDKを使用する準備と実行サンプルや500InternalServerErrorさんのPL/SQL SDKの記事を参考にしました。
利用するファンクションはマスキングを実行するファンクションとマスキング・ジョブの実行状況を確認するファンクションです。ファンクションの詳細はドキュメントをご確認ください。
- DBMS_CLOUD_OCI_DS_DATA_SAFE.MASK_DATA
- DBMS_CLOUD_OCI_DS_DATA_SAFE.GET_WORK_REQUEST
■ 作成したPL/SQLコード
DECLARE
M_RESPONSE DBMS_CLOUD_OCI_DS_DATA_SAFE_MASK_DATA_RESPONSE_T;
M_DETAILS DBMS_CLOUD_OCI_DATASAFE_MASK_DATA_DETAILS_T;
W_RESPONSE DBMS_CLOUD_OCI_DS_DATA_SAFE_GET_WORK_REQUEST_RESPONSE_T;
RESPONSE_BODY DBMS_CLOUD_OCI_DATASAFE_WORK_REQUEST_T;
JSON_OBJ JSON_OBJECT_T;
WID VARCHAR2(100);
BEGIN
-- マスキングの実行
M_RESPONSE := DBMS_CLOUD_OCI_DS_DATA_SAFE.MASK_DATA(
MASKING_POLICY_ID => 'ocid1.datasafemaskingpolicy.oc1.ap-sydney-1.amaaaaaassl65iqatqrpq7xnnslr4maklrvcqnaihoxduycj2hkgywhi5uea'
,
MASK_DATA_DETAILS => M_DETAILS,
REGION => 'ap-sydney-1',
CREDENTIAL_NAME => 'CRED_APPKEY'
);
JSON_OBJ := M_RESPONSE.HEADERS;
WID := JSON_OBJ.GET_STRING('opc-work-request-id');
DBMS_OUTPUT.PUT_LINE('wid:' || WID);
-- マスキング・ジョブのステータス確認
LOOP
W_RESPONSE := DBMS_CLOUD_OCI_DS_DATA_SAFE.GET_WORK_REQUEST(
WORK_REQUEST_ID => WID,
REGION => 'ap-sydney-1',
CREDENTIAL_NAME => 'CRED_APPKEY'
);
RESPONSE_BODY := W_RESPONSE.RESPONSE_BODY;
IF RESPONSE_BODY.STATUS = 'SUCCEEDED' THEN
EXIT;
END IF;
DBMS_SESSION.SLEEP(1);
END LOOP;
DBMS_OUTPUT.PUT_LINE('STATUS:' || RESPONSE_BODY.STATUS);
END;
実行してみた結果はこちらです。表の内容を検索するとGUIで行ったようにマスクがされていました。
wid:ocid1.coreservicesworkrequest.oc1..aaaaaaaajytnl26vpyibmkrdyutbkb3itt3dhgogujfkb6qgvblbwhx5umua
STATUS:SUCCEEDED
PL/SQLプロシージャが正常に完了しました。
SELECT * FROM TESTUSER.CUSTOMER_TRANSACTIONS_TABLE;
CUSTOMER_ID TRANSACTION_ID CUSTOMER_NAME ADDRESS AMOUNT TRANSACTION_DATE NET_INCOME
----------- -------------- ----------------- --------- ------ ----------------- ----------
1 1001 Kmcgptlmyf TOKYO品川区 8000 2024/6/1 0:00:00 7760
3 1003 Rftpewrzppjdraelv TOKYO杉並区 12000 2024/6/5 0:00:00 11640
4 1004 Aisxutdoovngxx TOKYO新宿区 6000 2024/6/6 0:00:00 5820
6 1006 Pfiwelkx TOKYO世田谷区 5200 2024/6/8 0:00:00 5044
7 1007 Rlrqkwgawu 千葉県千葉市 9500 2024/6/8 0:00:00 9215
8 1008 Ejvvbsphmmfxrky TOKYO渋谷区 11000 2024/6/9 0:00:00 10670
9 1009 Ufprwovyojxga TOKYO中野区 7000 2024/6/10 0:00:00 6790
ちなみに実行中にData SafeのUIをみると、ステータスが進行中になっており、正常に完了した後はSUCCEEDEDになっていました。
6.Data Transformsのワークフローに組み込む
作成済みのワークフローをコピーして、新たなワークフローを作成します。
元のワークフローはこのような内容でした。SQLはGCSに書き込むDBMS_CLOUD.EXPORT_DATAの実行コードです。

間にもう1つSQLを追加し、それぞれの名前をわかりやすいように変更しました。
それぞれのSQLには以下のコードを入力します。
■ Masking_PL/SQL
5で作成し、実行を確認済みのマスキングのコードをそのまま利用します。
■ OutputObj_PLSQL
GCSのときのコードから、クレデンシャルをOCI$RESOURCE_PRINCIPAL、file_uri_listをObject Storageのバケット、formatのtypeをparquetに変更しました。
BEGIN
DBMS_CLOUD.EXPORT_DATA(
credential_name => 'OCI$RESOURCE_PRINCIPAL',
file_uri_list => 'https://objectstorage.ap-sydney-1.oraclecloud.com/n/<namespace>/b/test_bucket/o/customer_transactions',
query => 'select * from testuser.customer_transactions_table',
format => JSON_OBJECT('type' value 'parquet'));
END;
成功しました!
ジョブの詳細を見ると、データ・フロー、SQLが順に実行されていることが確認できます。

Object Storageにファイルが出力されていることも確認できました。

ダウンロードして、アプリで参照してみました。正しく出力されています。

おわりに
Data Transformsでデータの変換、マスキング、ファイルへの出力までを行ってみました。今回は作成しませんでしたが、Data Safeはユーザー独自のマスキング定義も作成し利用できます。
























