クエリ時に BigQuery データを匿名化

このチュートリアルでは、リモート関数と機密データの保護を使用して、BigQuery からテーブルにクエリを実行しながらデータを匿名化する方法について説明します。このアプローチは、リアルタイム クエリの結果をサニタイズして、分析に不要なデータへのアクセスを最小限に抑える場合に便利です。

このチュートリアルでは、転送中のデータの暗号化と復号について説明します。機密データの保護を使用して保存データを暗号化する方法については、ストレージ内の機密データの匿名化をご覧ください。

このチュートリアルは、データ セキュリティ、データ処理、データ分析を担当するユーザーを対象としています。このガイドは、データ処理とデータ プライバシーに精通していることを前提としていますが、専門家である必要はありません。また、このガイドでは、基本的な Cloud Shell と SQL スクリプトを実行できることを前提としています。

このチュートリアルでは、SQL ベースの関数、BigQueryリモート関数Cloud Run、機密データの保護を使用します。

暗号化などの匿名化手法により、データ内の未加工の機密性の高い識別子が難読化されます。これらの手法により、データの取り扱いリスクを軽減しながら、データの有用性は失わずに結合や分析を行えます。

企業によっては、クラウド データ ウェアハウスに匿名化されたデータのみを保存するポリシーや規制要件がある場合があります。さらに、レポート生成のために匿名化されたデータを効率的に再識別する必要がある場合もあります。

大量のセンシティブ データを処理するリスクを最小限に抑えるには、自動データ変換パイプラインを使用し、匿名化されたデータセットを作成します。このチュートリアルを使用すると、そのパイプラインを、再識別のみ、または匿名化と再識別の両方を目的とした SQL クエリに置き換えることができます。このチュートリアルは、Cloud Run でホストされている中央サービスを使用した匿名化と再識別の両方を行うための助けとなります。Dataflow クラスタを設定または維持しなくても、この中央サービスを組織全体で使用できます。

機密データの保護は、機密データに関してデータを検査することでデータセットを分類できます。Sensitive Data Protection には、infoTypes という組み込み分類器が 200 以上あります。Cloud Data Loss Prevention API を使用してデータを匿名化するには、データ パイプラインとアプリケーションが必要です。このチュートリアルは、データ アナリスト、エンジニア、サイエンティストが SQL 関数を使用して同じ結果を得ることを目的としています。

このチュートリアルを修了すると、クエリ結果で機密データを匿名化され、再識別されるクエリを作成できるようになります。

SELECT
    pii_column,
    fns.dlp_freetext_encrypt(pii_column) AS dlp_encrypted,
    fns.dlp_freetext_decrypt(fns.dlp_freetext_encrypt(pii_column)) AS dlp_decrypted
FROM
    UNNEST(
    [
        'My name is John Doe. My email is john.doe@example.com']) AS pii_column

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

pii_column dlp_encrypted dlp_decrypted
1 My name is John Doe. My email is john.doe@example.com My name is John Doe. My email is BQ_TRF_EMAIL(40):AQy6lGvwKR+AiiRqJpEr+nBzZUzOcjXkXamUugU= My name is John Doe. My email is john.doe@example.com

アーキテクチャ

次の図は、このチュートリアルでデータ ウェアハウスとして BigQuery を使用し、機密データの保護を使用してデータの匿名化と再識別を行い、リモート関数をホストするために Cloud Run を使用する方法を示しています。

このチュートリアルのアーキテクチャの概要図

環境を準備する

  1. Cloud Shell で、ソース リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/bigquery-dlp-remote-function.git
    
  2. このチュートリアルのディレクトリに移動します。

    cd bigquery-dlp-remote-function/
    

スクリプトを使用してリソースをデプロイする

カスタマイズを行わずにデプロイ スクリプトを使用する場合は、次の手順を行います。デプロイをカスタマイズする場合は、このセクションをスキップして、代わりにカスタマイズされたソリューションを手動でデプロイするをご覧ください。

  1. PROJECT_ID フィールドと REGION フィールドの値を設定します。

    # Project ID of the Google Cloud project
    PROJECT_ID="PROJECT_ID"
    
    # Google Cloud region to use for deployment of resources
    # Refer to https://cloud.google.com/about/locations
    REGION="REGION"
    

    以下を置き換えます。

    • PROJECT_ID: このチュートリアルのプロジェクトの ID。
    • REGION: データを保存して処理するリージョン(例: us-west1)。ゾーンではなくリージョンを指定します。
  2. 省略可: 使用する検査テンプレートがある場合は、DLP_INSPECT_TEMPLATE フィールドをその検査テンプレートの完全なリソース名に設定します。検査テンプレートは、REGION フィールドで設定したのと同じリージョンに存在する必要があります。

    検査テンプレートに、匿名化テンプレートで使用されているすべての infoType が含まれていることを確認します。

    この手順をスキップすると、機密データの保護は、システムデフォルトである infoType 検出器のセットを使用してデータを検査します。

    DLP_INSPECT_TEMPLATE="DLP_INSPECT_TEMPLATE"
    

    DLP_INSPECT_TEMPLATE は、検査テンプレートの完全なリソース名(projects/PROJECT_ID/locations/REGION/inspectTemplates/TEMPLATE_ID など)に置き換えます。

  3. アプリケーションのデフォルト認証情報を使用して認証します。

    gcloud auth application-default login && \
    gcloud auth application-default set-quota-project "${PROJECT_ID}"
    
  4. Terraform スクリプトを初期化して実行し、すべてのリソースを作成します。

    terraform init && \
    terraform apply \
    -var "project_id=${PROJECT_ID}" \
    -var "region=${REGION}" \
    -var "dlp_inspect_template_full_path=${DLP_INSPECT_TEMPLATE}"
    

    Terraform が実行するすべてのアクションが表示されます。アクションを確認します。続行するには、yes と入力します。

  5. データを暗号化および復号できることを確認します。

カスタマイズしたソリューションを手動でデプロイする

デプロイをカスタマイズする場合は、次の手順を行います。カスタマイズや手動の手順を行わずに、提供されたデプロイ スクリプトを使用する場合は、代わりにスクリプトを使用してリソースをデプロイするをご覧ください。

環境変数を設定する

Cloud Shell で、次の環境変数を設定します。

PROJECT_ID="PROJECT_ID"
REGION="REGION"
CLOUD_RUN_SERVICE_NAME="CLOUD-RUN-SERVICE-NAME"
ARTIFACT_REGISTRY_NAME="ARTIFACT-DOCKER-REGISTRY-NAME"

以下を置き換えます。

  • PROJECT_ID: このチュートリアルのプロジェクトの ID。
  • REGION: データを保存して処理するリージョン(例: us-west1)。ゾーンではなくリージョンを指定します。
  • CLOUD_RUN_SERVICE_NAME: 新しい Cloud Run サービスの名前。15 文字まで入力できます
  • ARTIFACT_REGISTRY_NAME: コンテナ イメージを保存する新しい Artifact Registry の名前。

Cloud Run サービスのサービス アカウントを作成する

  1. サービス アカウントの作成:

    RUNNER_SA_NAME="${CLOUD_RUN_SERVICE_NAME}-runner"
    RUNNER_SA_EMAIL="${RUNNER_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
    gcloud iam service-accounts create "${RUNNER_SA_NAME}" \
        --project="${PROJECT_ID}" \
        --description "Runner for BigQuery remote function execution" \
        --display-name "${RUNNER_SA_NAME}"
    
  2. Sensitive Data Protection に必要なロールを付与します。

    DLP 読者のロールを付与します。

    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${RUNNER_SA_EMAIL}" \
        --role='roles/dlp.reader'
    

    DLP ユーザーのロールを付与します。

    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${RUNNER_SA_EMAIL}" \
        --role='roles/dlp.user'
    

Cloud Run サービスをデプロイする

アプリケーションをデプロイするには、次の手順を行います。

  1. 省略可: デフォルト値を変更するには、環境変数を変更するか、src/main/resources/aes.properties ファイルを更新します。

  2. 関数のコンテナ イメージを保存する Artifact Registry リポジトリを作成します。

    gcloud artifacts repositories create "${ARTIFACT_REGISTRY_NAME}" \
    --repository-format=docker \
    --location="${REGION}" \
    --description="Container images repository for BigQuery Functions" \
    --project="${PROJECT_ID}"
    
  3. Cloud Build を使用してアプリケーションをコンパイルし、Cloud Run にデプロイします。

    gcloud builds submit \
    --project ${PROJECT_ID} \
    --substitutions=_CONTAINER_IMAGE_NAME="${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_NAME}/${CLOUD_RUN_SERVICE_NAME}:latest" \
    --machine-type=e2-highcpu-8 && \
    gcloud beta run deploy ${CLOUD_RUN_SERVICE_NAME} \
    --image="${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY_NAME}/${CLOUD_RUN_SERVICE_NAME}:latest" \
    --execution-environment=gen2 \
    --platform=managed \
    --region="${REGION}" \
    --service-account="${RUNNER_SA_EMAIL}" \
    --cpu=4 \
    --memory=8Gi \
    --no-allow-unauthenticated \
    --project ${PROJECT_ID} \
    --update-env-vars=PROJECT_ID=${PROJECT_ID}
    

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

    ID: 403a276e-b0c6-41f3-aaed-f0ec9f9cedba
    CREATE_TIME: 2023-02-04T01:52:15+00:00
    DURATION: 1M59S
    SOURCE: gs://PROJECT_ID_cloudbuild/source/1675475534.124241-9c43787f64e04cfd9e4a1979d3324fe0.tgz
    IMAGES: gcr.io/PROJECT_ID/CLOUD_RUN_SERVICE_NAME (+1 more)
    STATUS: SUCCESS
    Deploying container to Cloud Run service [CLOUD_RUN_SERVICE_NAME] in project [PROJECT_ID] region [REGION]
    OK Deploying new service... Done.
     OK Creating Revision... Revision deployment finished. Checking container heal
     th.
     OK Routing traffic...
    Done.
    Service [CLOUD_RUN_SERVICE_NAME] revision [CLOUD_RUN_SERVICE_NAME-00001-tat] has been deployed and is serving 100 percent of traffic.
    Service URL: https://CLOUD_RUN_SERVICE_NAME-j2bpjx2xoq-uw.a.run.app
    
  4. Cloud Run URL を取得して、環境変数に保存します。

    RUN_URL="$(gcloud run services describe ${CLOUD_RUN_SERVICE_NAME} --region \
        ${REGION} --project ${PROJECT_ID} --format="get(status.address.url)")"
    

機密データの保護の匿名化テンプレートを作成する

機密データの保護の匿名化テンプレートは、匿名化設定を保存して、複数のオペレーションやデータソースで再利用できるようにします。

この手順では、匿名化テンプレートの例を含む sample_dlp_deid_config.json ファイルを使用します。

Cloud Shell でテンプレートを作成します。

DEID_TEMPLATE=$(curl -X POST \
-H "Authorization: Bearer `gcloud auth print-access-token`" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Goog-User-Project: ${PROJECT_ID}" \
--data-binary "@sample_dlp_deid_config.json" \
"https://dlp.googleapis.com/v2/projects/${PROJECT_ID}/locations/${REGION}/deidentifyTemplates")

DEID_TEMPLATE_NAME="$(echo ${DEID_TEMPLATE} | jq -r '.name')"

実際の機密性の高いワークロードに対して機密データの保護の暗号化を実行する場合は、ラップされた鍵を使用することをおすすめします。デモ用に、このチュートリアルではラップ解除された鍵を使用します。ラップされた鍵を作成し、それを匿名化リクエストと再識別リクエストで使用する方法の詳細については、機密データの匿名化と再識別をご覧ください。

Cloud Run への BigQuery 接続を作成する

  1. Cloud Shell で、Cloud Run にアクセスするための BigQuery 接続を作成します。

    bq mk --connection \
    --display_name='External transform function connection' \
    --connection_type=CLOUD_RESOURCE \
    --project_id="${PROJECT_ID}" \
    --location="${REGION}" \
    ext-${CLOUD_RUN_SERVICE_NAME}
    
  2. 接続に使用される BigQuery サービス アカウントを見つけて設定します。

    CONNECTION_SA="$(bq --project_id ${PROJECT_ID} --format json show \
        --connection ${PROJECT_ID}.${REGION}.ext-${CLOUD_RUN_SERVICE_NAME} \
        | jq -r '.cloudResource.serviceAccountId')"
    
  3. サービス アカウントに Cloud Run 起動元ロールを付与します。

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${CONNECTION_SA}" \
        --role='roles/run.invoker'
    

リモート関数用の BigQuery データセットを作成する

  1. リモート関数用の BigQuery データセットを定義します。

    BQ_FUNCTION_DATASET="fns"
    
  2. データセットがまだ存在しない場合は作成します。

       bq mk --dataset \
           --project_id ${PROJECT_ID} \
           --location ${REGION} \
           ${BQ_FUNCTION_DATASET}
    

Sensitive Data Protection リモート関数を作成する

  1. 省略可: 使用する検査テンプレートがある場合は、DLP_INSPECT_TEMPLATE 変数をその検査テンプレートの完全なリソース名に設定します。検査テンプレートは、REGION 環境変数で設定したのと同じリージョンに存在する必要があります。

    検査テンプレートに、匿名化テンプレートで使用されているすべての infoType が含まれていることを確認します。

    この手順をスキップすると、機密データの保護は、システムデフォルトである infoType 検出器のセットを使用してデータを検査します。

    DLP_INSPECT_TEMPLATE="DLP_INSPECT_TEMPLATE"
    

    DLP_INSPECT_TEMPLATE は、検査テンプレートの完全なリソース名(projects/PROJECT_ID/locations/REGION/inspectTemplates/TEMPLATE_ID など)に置き換えます。

  2. 機密データの保護の匿名化関数を作成します。

    bq query --project_id ${PROJECT_ID} \
    --use_legacy_sql=false \
    "CREATE OR REPLACE FUNCTION ${BQ_FUNCTION_DATASET}.dlp_freetext_encrypt(v STRING)
    RETURNS STRING
    REMOTE WITH CONNECTION \`${PROJECT_ID}.${REGION}.ext-${CLOUD_RUN_SERVICE_NAME}\`
    OPTIONS (endpoint = '${RUN_URL}', user_defined_context = [('mode', 'deidentify'),('algo','dlp'),('dlp-deid-template','${DEID_TEMPLATE_NAME}'),('dlp-inspect-template', '${DLP_INSPECT_TEMPLATE}')]);"
    
  3. 機密データの保護の再識別関数を作成します。

    bq query --project_id ${PROJECT_ID} \
    --use_legacy_sql=false \
    "CREATE OR REPLACE FUNCTION ${BQ_FUNCTION_DATASET}.dlp_freetext_decrypt(v STRING)
    RETURNS STRING
    REMOTE WITH CONNECTION \`${PROJECT_ID}.${REGION}.ext-${CLOUD_RUN_SERVICE_NAME}\`
    OPTIONS (endpoint = '${RUN_URL}', user_defined_context = [('mode', 'reidentify'),('algo','dlp'),('dlp-deid-template','${DEID_TEMPLATE_NAME}'),('dlp-inspect-template', '${DLP_INSPECT_TEMPLATE}')]);"
    

匿名化と再識別を確認する

ソリューションがデータを匿名化して再識別化するかどうかを確認するには、次の操作を行います。

コンソール

  1. Google Cloud コンソールで、BigQuery に移動します。

    BigQuery に移動

    最後にアクセスしたプロジェクトで、BigQuery が開きます。

  2. クエリエディタを開くには、 [クエリを新規作成] をクリックします。

  3. 次のクエリを入力します。

    SELECT
        pii_column,
        fns.dlp_freetext_encrypt(pii_column) AS dlp_encrypted,
        fns.dlp_freetext_decrypt(fns.dlp_freetext_encrypt(pii_column)) AS dlp_decrypted
    FROM
        UNNEST(
        [
            'My name is John Doe. My email is john.doe@example.com',
            'Some non PII data',
            '650-253-0000',
            'some script with simple number 1234']) AS pii_column
    
  4. [実行] をクリックします。

bq

  1. データセットの環境変数を設定します。

    BQ_FUNCTION_DATASET="fns"
    
  2. クエリを実行します。

    bq query --project_id ${PROJECT_ID} \
    --use_legacy_sql=false \
    "
    SELECT
      pii_column,
      ${BQ_FUNCTION_DATASET}.dlp_freetext_encrypt(pii_column) AS dlp_encrypted,
    ${BQ_FUNCTION_DATASET}.dlp_freetext_decrypt(${BQ_FUNCTION_DATASET}.dlp_freetext_encrypt(pii_column)) AS dlp_decrypted
    FROM
      UNNEST(
        [
          'My name is John Doe. My email is john.doe@example.com',
          'Some non PII data',
          '650-253-0000',
          'some script with simple number 1234']) AS pii_column"
    

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

pii_column dlp_encrypted dlp_decrypted
1 My name is John Doe. My email is john.doe@example.com My name is John Doe. My email is BQ_TRF_EMAIL(40):AQy6lGvwKR+AiiRqJpEr+nBzZUzOcjXkXamUugU= My name is John Doe. My email is john.doe@example.com
2 Some non PII data Some non PII data Some non PII data
3 650-253-0000 BQ_TRF_PH(40):AeKpGU5KBXaTyecCun7dv1hHht5w5Q2PTpvkRC4= 650-253-0000
4 some script with simple number 1234 some script with simple number 1234 some script with simple number 1234

考慮事項

このチュートリアルをニーズに合わせて調整する場合は、次の点を考慮してください。

  • 匿名化と再識別は、Cloud Run サービスを介して処理されます。コンピューティング要件に応じて、Cloud Run の CPU とメモリをプロビジョニングします。詳細については、Cloud Run の CPU 上限メモリ上限をご覧ください。
  • 機密データの保護を使用する場合は、使用量上限費用管理の推奨事項を検討します。
  • 費用と機密データの保護の割り当て使用量を制御するためには、機密データの保護のリモート関数に渡すアイテムを 10,000 以下に制限します。ソリューションでは、リクエストを自動的にバッチ処理して、次の機密データの保護リクエストの制限を適切に処理できます。

    • テーブル値の最大数: 50,000
    • デフォルトのリクエスト サイズの上限: 0.5 MB

    クエリの最終結果とフィルタされた結果は、ソースではなく機密データの保護関数に渡す必要があります。

    このソリューションでは、pii_column 列の各値がアイテムになります(たとえば、My name is John Doe. My email is john.doe@example.com は 1 つのアイテムです)。

  • BigQuery データセット、Cloud Run サービス、機密データの保護テンプレートが同じクラウド リージョンにあることを確認します。