在查询时对 BigQuery 数据进行去标识化处理


本教程介绍了如何在使用远程函数和敏感数据保护功能从 BigQuery 查询表时对数据进行去标识化处理。此方法非常适合对实时查询结果进行脱敏处理,以最大限度地减少对分析不需要的数据的访问。

本教程演示了传输中的数据加密和解密。如需了解如何使用 Sensitive Data Protection 对静态数据进行加密,请参阅对存储空间中的敏感数据进行去标识化

本教程适用于负责数据安全、数据处理或数据分析的受众。本指南假定您熟悉数据处理和数据隐私,而无需成为专家。本指南还假定您可以运行基本的 Cloud Shell 和 SQL 脚本。

本教程使用基于 SQL 的函数、BigQuery远程函数Cloud Run 和敏感数据保护功能。

去标识化技术(例如加密)会对数据中的原始敏感标识符进行模糊处理。这些技术可让您保留数据的实用性以进行联接或分析,同时降低数据处理的风险。

企业可能有政策或法规要求,要求其仅在云数据仓库中存储去标识化数据。此外,他们可能还需要高效地重标识去标识化数据,以生成报告。

如需最大限度地降低处理大量敏感数据的风险,您可以使用自动数据转换流水线来创建已经去标识化处理的数据集。您可以通过本教程将该流水线替换为 SQL 查询,以便仅进行重新识别,或同时进行去标识和重新识别。本教程将帮助您使用托管在 Cloud Run 上的中央服务执行去标识化和重标识处理。您可以在整个组织中使用这项集中式服务,而无需设置或维护 Dataflow 集群。

Sensitive Data Protection 可以通过检查数据是否包含敏感信息来对数据集进行分类。敏感数据保护有超过 150 个内置分类器,称为 infoTypes。若要使用 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 托管远程函数。

本教程的高级架构图

目标

  • 部署一个 Cloud Run 服务,用于提供敏感数据保护功能中的去标识化功能。
  • 创建使用敏感数据保护去标识化模板的 BigQuery 远程函数。
  • 使用 SQL 查询验证 BigQuery 中的数据加密。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, BigQuery, BigQuery Connection API, Cloud Build, Cloud Data Loss Prevention API, Cloud Key Management Service, Cloud Run, Container Registry, Identity and Access Management, Resource Manager, Secret Manager, and Service Usage APIs:

    gcloud services enable artifactregistry.googleapis.com bigquery.googleapis.com bigqueryconnection.googleapis.com cloudbuild.googleapis.com cloudkms.googleapis.com cloudresourcemanager.googleapis.com containerregistry.googleapis.com dlp.googleapis.com iam.googleapis.com run.googleapis.com secretmanager.googleapis.com serviceusage.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the Artifact Registry, BigQuery, BigQuery Connection API, Cloud Build, Cloud Data Loss Prevention API, Cloud Key Management Service, Cloud Run, Container Registry, Identity and Access Management, Resource Manager, Secret Manager, and Service Usage APIs:

    gcloud services enable artifactregistry.googleapis.com bigquery.googleapis.com bigqueryconnection.googleapis.com cloudbuild.googleapis.com cloudkms.googleapis.com cloudresourcemanager.googleapis.com containerregistry.googleapis.com dlp.googleapis.com iam.googleapis.com run.googleapis.com secretmanager.googleapis.com serviceusage.googleapis.com

准备环境

  1. 在 Cloud Shell 中,克隆源代码库:

    git clone https://github.com/GoogleCloudPlatform/bigquery-dlp-remote-function.git
    
  2. 前往本教程的目录:

    cd bigquery-dlp-remote-function/
    

使用脚本部署资源

如果您想使用部署脚本,而不进行任何自定义,请按以下步骤操作。如果您想自定义部署,请跳过本部分,改为参阅手动部署自定义解决方案

  1. 设置 PROJECT_IDREGION 字段的值:

    # 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. 为敏感数据保护授予所需角色。

    授予 DLP Reader 角色:

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

    授予 DLP User 角色:

    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 网址并将其保存到环境变量中:

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

创建 Sensitive Data Protection 去标识化模板

Sensitive Data Protection 去标识化模板可帮助您保存去标识化设置,以便在多个操作和数据源中重复使用这些设置。

此步骤使用 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')"

Google 建议您在对实际敏感工作负载执行 Sensitive Data Protection 加密时使用封装的密钥。出于演示目的,本教程使用未封装的密钥。如需详细了解如何创建封装密钥并在去标识化和重标识请求中使用它,请参阅对敏感数据进行去标识化和重标识

创建 BigQuery 与 Cloud Run 之间的连接

  1. 在 Cloud Shell 中,创建 BigQuery 连接以访问 Cloud Run:

    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 Invoker 角色:

    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}
    

创建敏感数据保护远程函数

  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. 创建 Sensitive Data Protection 去标识化函数:

    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 项。该解决方案可以自动批量处理请求,以妥善处理以下 Sensitive Data Protection 请求限制:

    • 表格值上限:5 万
    • 默认请求大小限制:0.5 MB

    查询的最终过滤结果应传递给敏感数据保护函数,而不是传递给来源。

    对于此解决方案,pii_column 列中的每个值都是一个项,例如 My name is John Doe. My email is john.doe@example.com 就是一个项。

  • 确保您的 BigQuery 数据集、Cloud Run 服务和敏感数据保护模板位于同一云区域

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

后续步骤