BigQuery での匿名化されたデータの検証と PII データの再識別

このチュートリアルでは、自動化された Dataflow パイプラインの実行による PII データセットの匿名化チュートリアルで匿名化したサンプル データセットの検証方法について説明します。検証後、個人を特定できる情報(PII)を匿名化するため、前に使われた Cloud DLP テンプレートを使用してデータを再識別します。

このドキュメントはシリーズの一部です。

このチュートリアルでは、シェル スクリプト、SQL、BigQuery、Dataflow の知識があることを前提としています。

リファレンス アーキテクチャ

このチュートリアルでは、次の図に示されているデータ検証と再識別のパイプラインについて説明します。

再識別のパイプラインのアーキテクチャ。

データ検証と再識別のパイプラインは、匿名化されたデータのコピーを検証し、Dataflow パイプラインを使用して大規模なデータの再識別を行います。

目標

  • 標準 SQL を使用して、BigQuery の匿名化されたデータセットを検証します。
  • Dataflow パイプラインを使用してデータを再識別します。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. シリーズのパート 2 を完了します。
  2. シリーズのパート 3 を完了します。

BigQuery の匿名化されたデータセットを検証する

BigQuery のデータに匿名化されたデータが含まれているかを検証し、PII を公開せずに安全に共有できることを確認します。自動化されたパイプラインでは、前のチュートリアルのサンプル CSV ファイルに基づいて BigQuery テーブルを作成しているため、BigQuery のテーブルとスキーマを比較することでデータを検証できます。

  1. Cloud Shell で、スキーマの作成に使用した CSV ファイルのヘッダー行を表示します。

    head -1 solution-test/CCRecords_1564602825.csv
    

    次のような出力が表示されます。

    ID,Card Type Code,Card Type Full Name,Issuing Bank,Card Number,Card Holder's Name,Issue Date,Expiry Date,Billing Date,Card PIN,Credit Limit,Age,SSN,JobTitle,Additional Details
    
  2. Cloud Console で、BigQuery の [クエリエディタ] ページに移動します。

    [クエリエディタ] に移動

  3. [クエリエディタ] で次のクエリを実行して、スキーマを CSV ファイルのヘッダー行と比較します。

    select table_name, column_name
    from `deid_dataset.INFORMATION_SCHEMA.COLUMNS`
    WHERE table_name="CCRecords_1564602825"
    

    次のような出力が表示されます。

    ラベルの付いた列名を含むテーブルのクエリ出力。

    列名にスペースが含まれないのは、パイプラインが BigQuery の命名規則に従って、列名とテーブル名に有効な文字のみが含まれるようにしているためです。

  4. テーブルの行数が 100,000 であることを検証します。

    select count(*) as number_of_rows
    from `deid_dataset.CCRecords_*` LIMIT 1
    

    出力では、number_of_rows 列は 100,001 ではなく 100,000 です。CSV ファイルにはヘッダー レコードがありますが、テーブルの行数に含まれていません。

    行数を示す出力。

  5. バケット変換が JobTitle 列に正しく適用されていることを確認します。

    select JobTitle, count(*) as number_of_records_found
    from `deid_dataset.CCRecords_1564602825`
    group by JobTitle
    

    出力では、JobTitle 値は、Executive、Engineer、Manager の 3 つの一般化されたバケットにグループ化されます。

    役職のグループ化を示す出力。

  6. Age 列の値が 60~20 の 6 つの異なるバケットにグループ化されていることを検証します。

    select Age, count(*) as number_of_records_found
    from `deid_dataset.CCRecords_1564602825`
    group by Age
    order by Age desc
    

    次のような出力が表示されます。

    年齢層を示す出力。

    PII の匿名化プロセスをさらに支援するために、年齢と役職はこれらのカテゴリにグループ化されています。たとえば、スタートアップ企業に、簡単に識別できる、よく知られた若い CEO がいるとします。元のデータセットの準識別子(役職と年齢)を使用して、データセット内のこの人物を識別する人がいるかもしれません。バケット変換では、データセットの匿名化のコピーにより、この人物を特定することがより困難になります。

  7. SSN のマスキング変換を検証します。

    select SSN
    from `deid_dataset.CCRecords_*`
    where regexp_contains(SSN, "@*")
    

    出力で、すべての SSN エントリの最初の 5 桁がマスクされます。

    マスクされた SSN 出力。

  8. 暗号変換が card_holders_namecard_numbercard_pin のエントリに対し、確定的暗号化を使用していることを検証します。

    select card_holders_name, card_number, card_pin
    from `deid_dataset.CCRecords_*`
    limit 1
    

    出力では、3 つのエントリはすべて base64 でエンコードされた暗号化文字列に置き換えられます。

    カード情報の暗号化を示す出力。

  9. infoType 変換が Additional Details 列に適用されたことを検証します。

    select additional_details
    from `deid_dataset.CCRecords_*`
    where regexp_contains(additional_details, r'(IBAN_CODE+)') or regexp_contains(additional_details, r'(EMAIL_ADDRESS+)')or regexp_contains(additional_details, r'(PHONE_NUMBER+)')or regexp_contains(additional_details, r'(ONLINE_USER_ID+)')
    

    出力では、機密性の高い値は [IBAN_CODE][EMAIL_ADDRESS][PHONE_NUMBER,][ONLINE_USER_ID] などのプレースホルダ値に置き換えられます。

    プレースホルダ値を示す出力。

  10. ID が76901 のデータセットの匿名化されたコピーを照会します。

    select * from `deid_dataset.CCRecords_1564602825` where id='76901'
    

    出力には次の値が表示されます。

    "ID": "76901"
    "Card_Type_Code": "AX"
    "Card_Type_Full_Name": "American Express"
    "Issuing_Bank": "American Express"
    "Card_Number": "encrypted value"
    "Card_Holders_Name": "encrypted value"
    "Issue_Date": "03/2013"
    "Expiry_Date": "03/2015"
    "Billing_Date": "14"
    "Card_PIN": "encrypted value"
    "Credit_Limit": "57000"
    "Age": "40"
    "SSN": "***-**-9395"
    "JobTitle": "Manager"
    "Additional_Details": "[IBAN_CODE][PHONE_NUMBER] [EMAIL_ADDRESS] 102-326-2388 hugedomains.com Maggio[ONLINE_USER_ID]"
    
  11. Cloud Shell で、前のステップの出力を ID が 76901 の CSV ファイル内にある元のデータセットと比較します。

    awk -F "," '$1 == 76901' solution-test/CCRecords_1564602825.csv
    

    次のように出力されます。

    76901,AX,American Express,American Express,376467075604410,Francis U Riggs,03/2013,03/2015,14,7425,57000,43,623-12-9395,Product Manager,ES20 6871 8240 0493 0298 3587 dsumpton1nc4@reddit.com 102-326-2388 hugedomains.com Maggio:5282194096147081
    

BigQuery からのデータセットを再識別する

最後に、匿名化に使用された DLP テンプレートを使用して、データを元の値に再識別できます。データを再識別するために、自動化された再識別 Dataflow パイプラインを使用してデータセットを大規模に再識別します。この再識別プロセスは、トークン暗号鍵(TEK)をローテーションする必要がある場合に役立ちます。キーのローテーション前にデータセットを再識別し、新しい TEK を使用して再トークン化できます。

  1. Cloud Shell で、再識別された値を公開する Pub/Sub トピックを作成します。

    export TOPIC_ID="reid-topic"
    gcloud pubsub topics create ${TOPIC_ID}
    
  2. トピックの Pub/Sub サブスクリプションを作成します。

    export SUBSCRIPTION_ID="reid-subscription"
    gcloud pubsub subscriptions create ${SUBSCRIPTION_ID} --topic=${TOPIC_ID}
    
  3. BigQuery SQL クエリをエクスポートします。

    export QUERY='select id,card_number,card_holders_name
    from `deid_dataset.CCRecords_1564602825`
    where safe_cast(credit_limit as int64)>100000 and safe_cast(age as int64)>50
    group by id,card_number,card_holders_name limit 10'
    

    このチュートリアルでは、利用限度額が 10 万ドルを超える 50 歳以上のカード所有者の名前とカード番号を再識別します。

  4. データ ストレージ バケットにクエリをアップロードします。

      cat << EOF | gsutil cp - gs://${DATA_STORAGE_BUCKET}/reid_query.sql
      ${QUERY}
      EOF
    
  5. パイプラインをトリガーします。

    gcloud beta dataflow flex-template run "dlp-reid-demo" --project=${PROJECT_ID} \
        --region=${REGION} \
        --template-file-gcs-location=gs://dataflow-dlp-solution-sample-data/dynamic_template_dlp_v2.json --  parameters=^~^streaming=true~enableStreamingEngine=true~tempLocation=gs://${DATAFLOW_TEMP_BUCKET}/temp~numWorkers=1~maxNumWorkers=2 ~runner=DataflowRunner~tableRef=${PROJECT_ID}:deid_dataset.CCRecords_1564602825~dataset=deid_dataset~autoscalingAlgorithm=THROUGHPUT_BASED~workerMachineType=n1-highmem-8 ~topic=projects/${PROJECT_ID}/topics/${TOPIC_ID}~deidentifyTemplateName=${REID_TEMPLATE_NAME} ~DLPMethod=REID~keyRange=1024~queryPath=gs://${DATA_STORAGE_BUCKET}/reid_query.sql
    
  6. パイプラインをモニタリングするには、Cloud Console で [Dataflow] ページに移動します。

    Dataflow に移動

    パイプラインは数分で正常に完了し、次の内容が表示されます。

    [完了] のジョブ ステータスが表示された完了済みのパイプライン。

  7. 再識別されたデータを検証するには、Cloud Shell で Pub/Sub サブスクライバーからレコードをランダムに取得します。

    gcloud pubsub subscriptions pull ${SUBSCRIPTION_ID} \
        --auto-ack --limit 1000 --project ${PROJECT_ID} >> re-id-data.txt
    

    出力は、データが元の形式に正常に再識別されたことを示しています。

    cat re-id-data.txt
    

    この出力は次のようになります。

    {"id":"17880","Card Number":"6558977436350773","Card Holder's Name":"Elden E Courtright"}
    {"id":"57055","Card Number":"3529749048585358","Card Holder's Name":"Francisco Duffy"}
    {"id":"31487","Card Number":"6227182611813833","Card Holder's Name":"Leslie C Wade"}
    {"id":"38521","Card Number":"36533383873740","Card Holder's Name":"Laura Z Thomas"}
    {"id":"81585","Card Number":"3569920557158538","Card Holder's Name":"Kelly Reed"}
    {"id":"96408","Card Number":"340687318048371","Card Holder's Name":"Ignacio V Pisano"}
    

クリーンアップ

課金を停止する最も簡単な方法は、チュートリアル用に作成した Cloud プロジェクトを削除することです。また、リソースを個別に削除することもできます。

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ