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


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

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

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

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

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

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

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

敏感数据保护可以通过检查数据是否包含敏感信息来对数据集进行分类。敏感数据保护具有 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

输出类似于以下内容:

Row 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 和 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 和 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)")"
    

创建敏感数据保护去标识化模板

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

此步骤使用 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 建议您在对实际的敏感工作负载执行敏感数据保护加密时,使用封装的密钥。出于演示目的,本教程使用未封装的密钥。如需详细了解如何创建封装密钥并在去标识化和重标识请求中使用该密钥,请参阅对敏感数据进行去标识化和重标识处理

创建与 Cloud Run 的 BigQuery 连接

  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. 创建敏感数据保护去标识化函数:

    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"
    

输出类似于以下内容:

Row 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 表示一项。

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

清理

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

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

后续步骤