使用混合作业检查来自外部来源的数据

本主题介绍如何使用混合作业和混合作业触发器来检查外部数据是否存在敏感信息。如需详细了解混合作业和混合作业触发器(包括混合环境的示例),请参阅混合作业和混合作业触发器

混合作业和混合作业触发器简介

借助混合作业和混合作业触发器,您可以扩大敏感数据保护提供的保护范围,使其不再局限于简单的内容检查请求Google Cloud Storage 代码库扫描。使用混合作业和混合作业触发器,您可以将几乎任何来源(包括 Google Cloud 外部)的数据直接流式传输到敏感数据保护,并让敏感数据保护检查数据是否包含敏感信息。敏感数据保护会自动保存和汇总扫描结果,以供进一步分析。

混合作业和混合作业触发器的比较

创建混合作业后,这些作业会一直运行,直到您将其停止。只要数据已正确进行路由格式设置,它们就接受所有传入的数据。

混合作业触发器的工作方式与混合作业类似,但您无需在混合作业触发器中明确停止作业。敏感数据保护会在每天结束时自动停止混合作业触发器中的作业。

此外,借助混合作业触发器,您可以在触发器内停止和启动新作业,而无需重新配置 hybridInspect 请求。例如,您可以将数据发送到混合作业触发器,然后停止活跃作业、更改其配置,在该触发器中启动新作业,然后继续将数据发送到同一触发器。

如需详细了解哪个选项适合您的使用场景,请参阅本页面上的典型的混合检查场景

术语定义

本主题使用以下术语:

  • 外部数据:存储在 Google Cloud 外部的数据或敏感数据保护不提供原生支持的数据。

  • 混合作业:配置为扫描来自几乎所有来源的数据的检查作业。

  • 混合作业触发器:配置为扫描来自几乎所有来源的数据的作业触发器。

  • hybridInspect 请求:包含您要检查的外部数据的请求。发送此请求时,您需要指定要向其发送请求的混合作业或混合作业触发器。

如需了解作业和作业触发器的一般信息,请参阅作业和作业触发器

混合检查流程

混合检查流程分为三个步骤。

  1. 选择要发送到敏感数据保护的数据。

    数据可能来自 Google Cloud 内部,也可能来自 Google Cloud 外部。例如,您可以配置自定义脚本或应用,将数据发送到敏感数据保护,以便检查正在传输的数据、来自其他云服务、本地数据存储区或几乎任何其他数据源的数据。

  2. 从头开始或使用检查模板在“敏感数据保护”中设置混合作业或混合作业触发器。

    设置混合作业或混合作业触发器后,敏感数据保护会主动监听发送到该触发器的数据。当您的自定义脚本或应用将数据发送到此混合作业或混合作业触发器时,系统会检查数据并根据配置存储其结果。

    设置混合作业或混合作业触发器时,您可以指定要在其中保存或发布发现结果的位置。选项包括保存到 BigQuery 以及将通知发布到 Pub/Sub、Cloud Monitoring 或电子邮件。

  3. 向混合作业或混合作业触发器发送 hybridInspect 请求。

    hybridInspect 请求包含要扫描的数据。在该请求中,请添加用于描述内容的元数据(也称为标签表标识符),以便敏感数据保护功能识别您要跟踪的信息。例如,如果您要在多个请求(例如同一数据库表中的行)中扫描相关数据,则可以在这些相关请求中使用相同的元数据。然后,您可以收集、记录和分析该数据库表的发现结果。

当混合作业运行和检查请求时,当敏感数据保护生成检查结果时,系统会给出检查结果。相比之下,Pub/Sub 通知等操作只有在应用结束混合作业后才会执行。

混合作业检查流程示意图

注意事项

使用混合作业和作业触发器时,请考虑以下几点:

  • 混合作业和混合作业触发器不支持过滤和采样。
  • 作业和作业触发器不受服务等级目标 (SLO) 的约束,但您可以采取一些措施来缩短延迟时间。如需了解详情,请参阅作业延迟

准备工作

在设置和使用混合作业或混合作业触发器之前,请确保您已完成以下操作:

创建新项目、启用结算功能和敏感数据保护

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  5. 确保您的 Google Cloud 项目已启用结算功能

  6. 启用 Sensitive Data Protection API。

    启用 API

配置数据源

在敏感数据保护检查数据之前,您必须先将数据发送到敏感数据保护。无论您使用什么方法配置混合作业或混合作业触发器,都必须设置外部来源以将数据发送到 DLP API。

如需了解混合检查请求所需的格式,请参阅混合内容项格式。如需了解可随请求中的数据包含的元数据类型,请参阅您可以提供的元数据类型

创建混合作业或混合作业触发器

如需让敏感数据保护检查您向其发送的数据,您必须先设置混合作业或混合作业触发器。如需了解要创建哪种检查,请参阅本页面上的典型的混合检查场景

控制台

在 Google Cloud 控制台中,前往创建作业或作业触发器页面:

转到“创建作业或作业触发器”

以下部分介绍了如何填写创建作业或作业触发器页面中与混合检查操作相关的部分。

选择输入数据

在本部分中,您将指定供敏感数据保护检查的输入数据。

  1. 可选:在名称部分,通过在作业 ID 字段中输入一个值来命名作业。将此字段留空会导致敏感数据保护自动生成标识符。
  2. 可选:从资源位置菜单中,选择要存储混合作业或混合作业触发器的区域。如需了解详情,请参阅指定处理位置
  3. 存储类型部分,选择混合

  4. 可选:在说明部分,描述您创建的混合作业或混合作业触发器。例如,您可以添加要检查的数据源的相关信息。

  5. 可选:对于必需标签,点击添加标签,然后输入您希望从 hybridInspect 请求中获得的标签。未指定此标签的 hybridInspect 请求不会由此混合作业或混合作业触发器处理。您最多可以添加 10 个必需的标签。如需了解详情,请参阅本页面中的需要来自 hybridInspect 请求的标签

  6. 可选:对于可选标签,输入要附加到发送到此作业或作业触发器的所有 hybridInspect 请求的结果中的任何键值对。您最多可以添加 10 个可选标签。如需了解详情,请参阅可选标签

  7. 可选:对于表格数据选项,如果您计划在 hybridInspect 请求中发送表格数据,请输入主键列的字段名称。如需了解详情,请参阅表格数据选项

  8. 点击继续

配置检测

在本部分中,您可以指定敏感数据保护将检查输入数据的敏感数据类型。您可以选择以下选项:

  • 模板:如果您已在当前项目中创建模板以用于定义敏感数据保护检测参数,请点击模板名称字段,然后从显示的列表中选择相应模板。
  • InfoTypes:敏感数据保护会选择要检测的最常用内置 infoType。如需更改 infoType 或选择要使用的自定义 infoType,请点击管理 infoType。您还可以在检查规则集置信度阈值部分中微调检测标准。如需了解详情,请参阅配置检测

配置检测参数后,点击继续

添加操作

您可在此部分指定将每次检查扫描的结果保存在何处,以及每当扫描完成时是否通过电子邮件或 Pub/Sub 通知消息接收通知。如果未将发现结果保存到 BigQuery,扫描结果将仅包含有关发现结果的数量和 infoType 的统计信息。

  • 保存到 BigQuery:每次运行扫描时,敏感数据保护会将扫描发现结果保存到您在此处指定的 BigQuery 表格中。如果您未指定表 ID,BigQuery 将在首次运行扫描时为新表分配一个默认名称。如果您指定现有的表,敏感数据保护会将扫描发现结果附加到该表。
  • 发布到 Pub/Sub:作业完成后,系统将发出 Pub/Sub 消息。

  • 通过电子邮件发送通知:在任务完成后,系统会发送一封电子邮件。

  • 发布到 Cloud Monitoring:作业完成后,其发现结果将发布到 Monitoring。

选择操作后,点击继续

安排

您可在此部分指定是创建立即运行的一个作业,还是创建每当敏感数据保护收到正确路由且设置了格式的数据时都会运行的作业触发器。

执行下列其中一项操作:

  • 如需立即运行混合式作业,请选择无(创建后立即运行一次性作业)

  • 如需配置作业以便从来源接收的数据触发作业,请选择创建一个触发器来定期运行作业

    混合作业会触发汇总 API 调用,因此您可以查看发现结果和一段时间内的趋势。

如需了解详情,请参阅混合作业和混合作业触发器的比较

回顾

您可以在此处查看扫描的 JSON 摘要。请务必记下混合 ob 或 hybrid 作业触发器的名称;在将数据发送到敏感数据保护进行检查时,您需要用到此信息。

查看 JSON 摘要后,点击创建

敏感数据保护会立即启动混合作业或混合作业触发器。 当您向此混合作业或混合作业触发器发送 hybridInspect 请求时,系统会启动检查扫描。

API

在 DLP API 中,作业由 DlpJobs 资源表示。如需创建混合作业,请调用 projects.locations.dlpJobs.create 方法。

在 DLP API 中,作业触发器用 JobTrigger 资源表示。如需创建混合作业触发器,请调用 projects.locations.jobTriggers.create 方法。

您创建的 DlpJobsJobTrigger 对象必须具有以下设置:

  1. inspectJob 字段中,设置 InspectJobConfig 对象。
  2. InspectJobConfig 对象的 storageConfig 字段中,设置 StorageConfig 对象。
  3. StorageConfig 对象的 hybridOptions 字段中,设置 HybridOptions 对象。此对象包含您要检查的数据的相关元数据
  4. InspectJobConfig 对象的 actions 字段中,添加您希望敏感数据保护在每个作业结束时执行的操作 (Action)。

    不支持 publishSummaryToCsccpublishFindingsToCloudDataCatalog 操作。如需详细了解操作,请参阅操作

  5. 通过执行以下任一或两项操作来指定要扫描的内容和扫描方式:

    • inspectTemplateName 字段设置为您要使用的检查模板(如果有)的完整资源名称。

    • 设置 inspectConfig 字段。

    如果您同时设置了 inspectTemplateNameinspectConfig 字段,则它们的设置会合并在一起。

JSON 示例简介

以下标签页包含 JSON 示例,您可以将这些示例发送给敏感数据保护,以创建混合作业混合作业触发器。这些混合作业和混合作业触发器示例配置为执行以下操作:

  • 处理任何带有 appointment-bookings-comments 标签的 hybridInspect 请求。
  • 扫描 hybridInspect 请求中的内容以获取电子邮件地址。
  • "env": "prod" 标签附加到发现结果。
  • 对于表格数据,获取 booking_id 列(主键)中与敏感数据所在的单元格位于同一行的单元格的值。敏感数据保护会将此标识符附加到发现结果,以便您可以将发现结果追溯到其来自的特定行。
  • 在作业停止时发送电子邮件。该电子邮件会发送给 IAM 项目所有者和技术重要联系人
  • 作业停止后,将发现结果发送到 Cloud Monitoring。

如需查看 JSON 示例,请参阅以下标签页。

混合作业

此标签页包含一个 JSON 示例,可用于创建混合作业。

如需创建混合作业,请向以下端点发送 POST 请求。

HTTP 方法和网址

POST https://dlp.googleapis.com/v2/projects/PROJECT_ID/locations/REGION/dlpJobs

替换以下内容:

  • PROJECT_ID:您要存储混合作业的项目的 ID
  • REGION:您要存储混合作业的地理区域

JSON 输入

{
  "jobId": "postgresql-table-comments",
  "inspectJob": {
    "actions": [
      {
        "jobNotificationEmails": {}
      },
      {
        "publishToStackdriver": {}
      }
    ],
    "inspectConfig": {
      "infoTypes": [
        {
          "name": "EMAIL_ADDRESS"
        }
      ],
      "minLikelihood": "POSSIBLE",
      "includeQuote": true
    },
    "storageConfig": {
      "hybridOptions": {
        "description": "Hybrid job for data from the comments field of a table that contains customer appointment bookings",
        "requiredFindingLabelKeys": [
          "appointment-bookings-comments"
        ],
        "labels": {
          "env": "prod"
        },
        "tableOptions": {
          "identifyingFields": [
            {
              "name": "booking_id"
            }
          ]
        }
      }
    }
  }
}

JSON 输出

{
"name": "projects/PROJECT_ID/locations/REGION/dlpJobs/i-postgresql-table-comments",
"type": "INSPECT_JOB",
"state": "ACTIVE",
"inspectDetails": {
  "requestedOptions": {
    "snapshotInspectTemplate": {},
    "jobConfig": {
      "storageConfig": {
        "hybridOptions": {
          "description": "Hybrid job for data from the comments field of a table that contains customer appointment bookings",
          "requiredFindingLabelKeys": [
            "appointment-bookings-comments"
          ],
          "labels": {
            "env": "prod"
          },
          "tableOptions": {
            "identifyingFields": [
              {
                "name": "booking_id"
              }
            ]
          }
        }
      },
      "inspectConfig": {
        "infoTypes": [
          {
            "name": "EMAIL_ADDRESS"
          }
        ],
        "minLikelihood": "POSSIBLE",
        "limits": {},
        "includeQuote": true
      },
      "actions": [
        {
          "jobNotificationEmails": {}
        },
        {
          "publishToStackdriver": {}
        }
      ]
    }
  },
  "result": {
    "hybridStats": {}
  }
},
"createTime": "JOB_CREATION_DATETIME",
"startTime": "JOB_START_DATETIME"
}

敏感数据保护会创建混合作业并生成作业 ID。在此示例中,作业 ID 为 i-postgresql-table-comments。记下作业 ID。 您需要在 hybridInspect 请求中用到它。

如需停止混合作业,您必须明确调用 projects.locations.dlpJobs.finish 方法。DLP API 不会自动停止混合作业。相比之下,DLP API 会在每天结束时自动停止混合作业触发器中的作业。

混合作业触发器

此标签页包含一个 JSON 示例,可用于创建混合作业触发器。

如需创建混合作业触发器,请向以下端点发送 POST 请求。

HTTP 方法和网址

POST https://dlp.googleapis.com/v2/projects/PROJECT_ID/locations/REGION/jobTriggers

替换以下内容:

  • PROJECT_ID:您要存储混合作业触发器的项目的 ID
  • REGION:您要存储混合作业触发器的地理区域

JSON 输入

{
    "triggerId": "postgresql-table-comments",
    "jobTrigger": {
      "triggers": [
        {
          "manual": {}
        }
      ],
      "inspectJob": {
        "actions": [
          {
            "jobNotificationEmails": {}
          },
          {
            "publishToStackdriver": {}
          }
        ],
        "inspectConfig": {
          "infoTypes": [
              {
                "name": "EMAIL_ADDRESS"
              }
          ],
          "minLikelihood": "POSSIBLE",
          "limits": {},
          "includeQuote": true
        },
        "storageConfig": {
          "hybridOptions": {
            "description": "Hybrid job trigger for data from the comments field of a table that contains customer appointment bookings",
            "requiredFindingLabelKeys": [
                "appointment-bookings-comments"
              ],
            "labels": {
              "env": "prod"
            },
            "tableOptions": {
              "identifyingFields": [
                {
                  "name": "booking_id"
                }
              ]
            }
          }
        }
      }
    }
  }

JSON 输出

{
"name": "projects/PROJECT_ID/locations/REGION/jobTriggers/postgresql-table-comments",
"inspectJob": {
  "storageConfig": {
    "hybridOptions": {
      "description": "Hybrid job trigger for data from the comments field of a table that contains customer appointment bookings",
      "requiredFindingLabelKeys": [
        "appointment-bookings-comments"
      ],
      "labels": {
        "env": "prod"
      },
      "tableOptions": {
        "identifyingFields": [
          {
            "name": "booking_id"
          }
        ]
      }
    }
  },
  "inspectConfig": {
    "infoTypes": [
      {
        "name": "EMAIL_ADDRESS"
      }
    ],
    "minLikelihood": "POSSIBLE",
    "limits": {},
    "includeQuote": true
  },
  "actions": [
    {
      "jobNotificationEmails": {}
    },
    {
      "publishToStackdriver": {}
    }
  ]
},
"triggers": [
  {
    "manual": {}
  }
],
"createTime": ""JOB_CREATION_DATETIME",
"updateTime": "TRIGGER_UPDATE_DATETIME",
"status": "HEALTHY"
}

敏感数据保护会创建混合作业触发器。输出包含混合作业触发器的名称。在本示例中为 postgresql-table-comments。记下名称。您的 hybridInspect 请求中需要用到它。

与混合作业不同,DLP API 会在每天结束时自动停止混合作业触发器中的作业。因此,您无需显式调用 projects.locations.dlpJobs.finish 方法。

创建混合作业或混合作业触发器时,您可以分别在以下 API 参考文档页面上使用 API Explorer:

请求参数字段中,输入 projects/PROJECT_ID/locations/REGION。然后,在请求正文字段中,粘贴您尝试创建的对象的示例 JSON。

如果请求成功(即使是在 API Explorer 中创建的请求),则会创建混合作业或混合作业触发器。

如需了解有关如何使用 JSON 将请求发送到 DLP API 的一般信息,请参阅 JSON 快速入门

将数据发送到混合作业或混合作业触发器

如需检查数据,您必须以正确的格式向混合作业或混合作业触发器发送 hybridInspect 请求。

混合内容项格式设置

下面是一个简单的 hybridInspect 请求示例,该请求会发送到敏感数据保护,以便由混合作业或混合作业触发器进行处理。 请注意 JSON 对象的结构,包括 hybridItem 字段,该字段包含以下字段:

  • item:包含要检查的实际内容。
  • findingDetails:包含要与内容关联的元数据。
{
  "hybridItem": {
    "item": {
      "value": "My email is test@example.org"
    },
    "findingDetails": {
      "containerDetails": {
        "fullPath": "10.0.0.2:logs1:app1",
        "relativePath": "app1",
        "rootPath": "10.0.0.2:logs1",
        "type": "logging_sys",
        "version": "1.2"
      },
      "labels": {
        "env": "prod",
        "appointment-bookings-comments": ""
      }
    }
  }
}

如需全面了解混合检查项的内容,请参阅 HybridContentItem 对象的 API 参考文档内容。

混合检查端点

如需使用混合作业或混合作业触发器检查数据,您必须向正确的端点发送 hybridInspect 请求。

混合作业的 HTTP 方法和网址

POST https://dlp.googleapis.com/v2/projects/PROJECT_ID/locations/REGION/dlpJobs/JOB_ID:hybridInspect

如需详细了解此端点,请参阅 projects.locations.dlpJobs.hybridInspect 方法的 API 参考文档页面。

混合作业触发器的 HTTP 方法和网址

https://dlp.googleapis.com/v2/projects/PROJECT_ID/locations/REGION/jobTriggers/TRIGGER_NAME:hybridInspect

如需详细了解此端点,请参阅 projects.locations.jobTriggers.hybridInspect 方法的 API 参考文档页面。

替换以下内容:

  • PROJECT_ID:您的项目标识符
  • REGION:您要存储 hybridInspect 请求的地理区域。此区域必须与混合作业的区域相同。
  • JOB_ID:您为混合作业指定的 ID,带有 i- 前缀。

    如需查找作业 ID,请在敏感数据保护中,依次点击检查 > 检查作业

  • TRIGGER_NAME:您为混合作业触发器指定的名称。

    如需查找作业触发器的名称,请在敏感数据保护中,点击检查 > 作业触发器

需要 hybridInspect 个请求的标签

如果您想控制混合作业或混合作业触发器可以处理哪些 hybridInspect 请求,可以设置必需的标签。针对该混合作业或混合作业触发器的任何 hybridInspect 请求不包含这些必需标签,都将被拒绝。

如需设置必需的标签,请执行以下操作:

  1. 创建混合作业或混合作业触发器时,将 requiredFindingLabelKeys 字段设置为必需标签列表。

    以下示例将 appointment-bookings-comments 设置为混合作业或混合作业触发器中的必需标签。

    "hybridOptions": {
      ...
      "requiredFindingLabelKeys": [
        "appointment-bookings-comments"
      ],
      "labels": {
        "env": "prod"
      },
      ...
    }
    
  2. hybridInspect 请求的 labels 字段中,将每个必需的标签作为键值对中的键添加。对应的值可以为空字符串。

    以下示例在 hybridInspect 请求中设置了必需的标签 appointment-bookings-comments

    {
      "hybridItem": {
        "item": {
          "value": "My email is test@example.org"
        },
        "findingDetails": {
          "containerDetails": {...},
          "labels": {
            "appointment-bookings-comments": ""
          }
        }
      }
    }
    

如果您未在 hybridInspect 请求中添加所需的标签,则会收到如下错误:

{
  "error": {
    "code": 400,
    "message": "Trigger required labels that were not included: [appointment-bookings-comments]",
    "status": "INVALID_ARGUMENT"
  }
}

代码示例:创建混合作业触发器并向其发送数据

C#

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


using System;
using Google.Api.Gax.ResourceNames;
using Google.Api.Gax;
using Google.Cloud.Dlp.V2;
using Grpc.Core;

public class SendDataToTheHybridJobTrigger
{
    public static DlpJob SendToHybridJobTrigger(
       string projectId,
       string jobTriggerId,
       string text = null)
    {
        // Instantiate the dlp client.
        var dlp = DlpServiceClient.Create();

        // Construct the hybrid finding details which will be used as metadata with the content.
        // Refer to this for more information: https://cloud.google.com/dlp/docs/reference/rpc/google.privacy.dlp.v2#google.privacy.dlp.v2.Container
        var findingDetails = new HybridFindingDetails
        {
            ContainerDetails = new Container
            {
                FullPath = "10.0.0.2:logs1:aap1",
                RelativePath = "app1",
                RootPath = "10.0.0.2:logs1",
                Type = "System Logs"
            }
        };

        // Construct the hybrid content item using the finding details and text to be inspected.
        var hybridContentItem = new HybridContentItem
        {
            Item = new ContentItem { Value = text ?? "My email is ariel@example.org and name is Ariel." },
            FindingDetails = findingDetails
        };

        var jobTriggerName = new JobTriggerName(projectId, jobTriggerId);

        // Construct the request to activate the Job Trigger.
        var activate = new ActivateJobTriggerRequest
        {
            JobTriggerName = jobTriggerName
        };

        DlpJob triggerJob = null;

        try
        {
            // Call the API to activate the trigger.
            triggerJob = dlp.ActivateJobTrigger(activate);
        }
        catch (RpcException)
        {
            ListDlpJobsRequest listJobsRequest = new ListDlpJobsRequest
            {
                ParentAsLocationName = new LocationName(projectId, "global"),
                Filter = $"trigger_name={jobTriggerName}"
            };

            PagedEnumerable<ListDlpJobsResponse, DlpJob> res = dlp.ListDlpJobs(listJobsRequest);
            foreach (DlpJob j in res)
            {
                triggerJob = j;
            }
        }

        // Construct the request using hybrid content item.
        var request = new HybridInspectJobTriggerRequest
        {
            HybridItem = hybridContentItem,
            JobTriggerName = jobTriggerName
        };

        // Call the API.
        HybridInspectResponse _ = dlp.HybridInspectJobTrigger(request);

        Console.WriteLine($"Hybrid job created successfully. Job name: {triggerJob.Name}");

        return triggerJob;
    }
}

Go

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import (
	"context"
	"fmt"
	"io"
	"log"
	"time"

	dlp "cloud.google.com/go/dlp/apiv2"
	"cloud.google.com/go/dlp/apiv2/dlppb"
)

// inspectDataToHybridJobTrigger uses the Data Loss Prevention API to inspect sensitive
// information using Hybrid jobs trigger that scans payloads of data sent from
// virtually any source and stores findings in Google Cloud.
func inspectDataToHybridJobTrigger(w io.Writer, projectID, textToDeIdentify, jobTriggerName string) error {
	// projectId := "your-project-id"
	// jobTriggerName := "your-job-trigger-name"
	// textToDeIdentify := "My email is test@example.org"

	ctx := context.Background()

	// Initialize a client once and reuse it to send multiple requests. Clients
	// are safe to use across goroutines. When the client is no longer needed,
	// call the Close method to cleanup its resources.
	client, err := dlp.NewClient(ctx)
	if err != nil {
		return err
	}

	// Closing the client safely cleans up background resources.
	defer client.Close()

	// Specify the content to be inspected.
	contentItem := &dlppb.ContentItem{
		DataItem: &dlppb.ContentItem_Value{
			Value: textToDeIdentify,
		},
	}

	// Contains metadata to associate with the content.
	// Refer to https://cloud.google.com/dlp/docs/reference/rpc/google.privacy.dlp.v2#container for specifying the paths in container object.
	container := &dlppb.Container{
		Type:         "logging_sys",
		FullPath:     "10.0.0.2:logs1:app1",
		RelativePath: "app1",
		RootPath:     "10.0.0.2:logs1",
		Version:      "1.2",
	}

	// Set the required label.
	labels := map[string]string{
		"env":                           "prod",
		"appointment-bookings-comments": "",
	}

	hybridFindingDetails := &dlppb.HybridFindingDetails{
		ContainerDetails: container,
		Labels:           labels,
	}

	hybridContentItem := &dlppb.HybridContentItem{
		Item:           contentItem,
		FindingDetails: hybridFindingDetails,
	}

	// Activate the job trigger.
	activateJobreq := &dlppb.ActivateJobTriggerRequest{
		Name: jobTriggerName,
	}

	dlpJob, err := client.ActivateJobTrigger(ctx, activateJobreq)
	if err != nil {
		log.Printf("Error from return part %v", err)
		return err
	}
	// Build the hybrid inspect request.
	req := &dlppb.HybridInspectJobTriggerRequest{
		Name:       jobTriggerName,
		HybridItem: hybridContentItem,
	}

	// Send the hybrid inspect request.
	_, err = client.HybridInspectJobTrigger(ctx, req)
	if err != nil {
		return err
	}

	getDlpJobReq := &dlppb.GetDlpJobRequest{
		Name: dlpJob.Name,
	}

	var result *dlppb.DlpJob
	for i := 0; i < 5; i++ {
		// Get DLP job
		result, err = client.GetDlpJob(ctx, getDlpJobReq)
		if err != nil {
			fmt.Printf("Error getting DLP job: %v\n", err)
			return err
		}

		// Check if processed bytes is greater than 0
		if result.GetInspectDetails().GetResult().GetProcessedBytes() > 0 {
			break
		}

		// Wait for 5 seconds before checking again
		time.Sleep(5 * time.Second)
		i++
	}

	fmt.Fprintf(w, "Job Name: %v\n", result.Name)
	fmt.Fprintf(w, "Job State: %v\n", result.State)

	inspectionResult := result.GetInspectDetails().GetResult()
	fmt.Fprint(w, "Findings: \n")
	for _, v := range inspectionResult.GetInfoTypeStats() {
		fmt.Fprintf(w, "Infotype: %v\n", v.InfoType.Name)
		fmt.Fprintf(w, "Likelihood: %v\n", v.GetCount())
	}

	fmt.Fprint(w, "successfully inspected data using hybrid job trigger ")
	return nil
}

Java

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


import com.google.api.gax.rpc.InvalidArgumentException;
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ActivateJobTriggerRequest;
import com.google.privacy.dlp.v2.Container;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DlpJob;
import com.google.privacy.dlp.v2.GetDlpJobRequest;
import com.google.privacy.dlp.v2.HybridContentItem;
import com.google.privacy.dlp.v2.HybridFindingDetails;
import com.google.privacy.dlp.v2.HybridInspectJobTriggerRequest;
import com.google.privacy.dlp.v2.InfoTypeStats;
import com.google.privacy.dlp.v2.InspectDataSourceDetails;
import com.google.privacy.dlp.v2.JobTriggerName;
import com.google.privacy.dlp.v2.ListDlpJobsRequest;

public class InspectDataToHybridJobTrigger {

  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    // The Google Cloud project id to use as a parent resource.
    String projectId = "your-project-id";
    // The job trigger id used to for processing a hybrid job trigger.
    String jobTriggerId = "your-job-trigger-id";
    // The string to de-identify.
    String textToDeIdentify = "My email is test@example.org and my name is Gary.";
    inspectDataToHybridJobTrigger(textToDeIdentify, projectId, jobTriggerId);
  }

  // Inspects data using a hybrid job trigger.
  // Hybrid jobs trigger allows to scan payloads of data sent from virtually any source for
  // sensitive information and then store the findings in Google Cloud.
  public static void inspectDataToHybridJobTrigger(
      String textToDeIdentify, String projectId, String jobTriggerId) throws Exception {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (DlpServiceClient dlpClient = DlpServiceClient.create()) {
      // Specify the content to be inspected.
      ContentItem contentItem = ContentItem.newBuilder().setValue(textToDeIdentify).build();

      // Contains metadata to associate with the content.
      // Refer to https://cloud.google.com/dlp/docs/reference/rest/v2/Container for specifying the
      // paths in container object.
      Container container =
          Container.newBuilder()
              .setFullPath("10.0.0.2:logs1:app1")
              .setRelativePath("app1")
              .setRootPath("10.0.0.2:logs1")
              .setType("logging_sys")
              .setVersion("1.2")
              .build();

      HybridFindingDetails hybridFindingDetails =
          HybridFindingDetails.newBuilder().setContainerDetails(container).build();

      HybridContentItem hybridContentItem =
          HybridContentItem.newBuilder()
              .setItem(contentItem)
              .setFindingDetails(hybridFindingDetails)
              .build();

      // Activate the job trigger.
      ActivateJobTriggerRequest activateJobTriggerRequest =
          ActivateJobTriggerRequest.newBuilder()
              .setName(JobTriggerName.of(projectId, jobTriggerId).toString())
              .build();

      DlpJob dlpJob;

      try {
        dlpJob = dlpClient.activateJobTrigger(activateJobTriggerRequest);
      } catch (InvalidArgumentException e) {
        ListDlpJobsRequest request =
            ListDlpJobsRequest.newBuilder()
                .setParent(JobTriggerName.of(projectId, jobTriggerId).toString())
                .setFilter("trigger_name=" + JobTriggerName.of(projectId, jobTriggerId).toString())
                .build();

        // Retrieve the DLP jobs triggered by the job trigger
        DlpServiceClient.ListDlpJobsPagedResponse response = dlpClient.listDlpJobs(request);
        dlpJob = response.getPage().getResponse().getJobs(0);
      }

      // Build the hybrid inspect request.
      HybridInspectJobTriggerRequest request =
          HybridInspectJobTriggerRequest.newBuilder()
              .setName(JobTriggerName.of(projectId, jobTriggerId).toString())
              .setHybridItem(hybridContentItem)
              .build();

      // Send the hybrid inspect request.
      dlpClient.hybridInspectJobTrigger(request);

      // Build a request to get the completed job
      GetDlpJobRequest getDlpJobRequest =
          GetDlpJobRequest.newBuilder().setName(dlpJob.getName()).build();

      DlpJob result = null;

      do {
        result = dlpClient.getDlpJob(getDlpJobRequest);
        Thread.sleep(5000);
      } while (result.getInspectDetails().getResult().getProcessedBytes() <= 0);

      System.out.println("Job status: " + result.getState());
      System.out.println("Job name: " + result.getName());
      // Parse the response and process results.
      InspectDataSourceDetails.Result inspectionResult = result.getInspectDetails().getResult();
      System.out.println("Findings: ");
      for (InfoTypeStats infoTypeStat : inspectionResult.getInfoTypeStatsList()) {
        System.out.println("\tInfoType: " + infoTypeStat.getInfoType().getName());
        System.out.println("\tCount: " + infoTypeStat.getCount() + "\n");
      }
    }
  }
}

Node.js

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');

// Instantiates a client
const dlpClient = new DLP.DlpServiceClient();

// The project ID to run the API call under.
// const projectId = "your-project-id";

// The string to de-identify
// const string = 'My email is test@example.org';

// Job Trigger ID
// const jobTriggerId = 'your-job-trigger-id';

async function inspectDataToHybridJobTrigger() {
  // Contains metadata to associate with the content.
  const container = {
    full_path: '10.0.0.2:logs1:app1',
    relative_path: 'app1',
    root_path: '10.0.0.2:logs1',
    type: 'logging_sys',
    version: '1.2',
  };

  const labels = {env: 'prod', 'appointment-bookings-comments': ''};

  // Build the hybrid content item.
  const hybridContentItem = {
    item: {value: string},
    findingDetails: {
      containerDetails: container,
      labels,
    },
  };
  let jobName;
  const fullTriggerName = `projects/${projectId}/jobTriggers/${jobTriggerId}`;
  // Activate the job trigger.
  try {
    const response = await dlpClient.activateJobTrigger({
      name: fullTriggerName,
    });
    jobName = response[0].name;
  } catch (err) {
    console.log(err);
    if (err.code === 3) {
      const response = await dlpClient.listDlpJobs({
        parent: fullTriggerName,
        filter: `trigger_name=${fullTriggerName}`,
      });
      jobName = response[0][0].name;
    }
    // Ignore error related to job trigger already active
    if (err.code !== 3) {
      console.log(err.message);
      return;
    }
  }
  // Build the hybrid inspect request.
  const request = {
    name: `projects/${projectId}/jobTriggers/${jobTriggerId}`,
    hybridItem: hybridContentItem,
  };
  // Send the hybrid inspect request.
  await dlpClient.hybridInspectJobTrigger(request);
  // Waiting for a maximum of 15 minutes for the job to get complete.
  let job;
  let numOfAttempts = 30;
  while (numOfAttempts > 0) {
    // Fetch DLP Job status
    [job] = await dlpClient.getDlpJob({name: jobName});

    if (job.state === 'FAILED') {
      console.log('Job Failed, Please check the configuration.');
      return;
    }
    // Check if the job has completed.
    if (job.inspectDetails.result.processedBytes > 0) {
      break;
    }
    // Sleep for a short duration before checking the job status again.
    await new Promise(resolve => {
      setTimeout(() => resolve(), 30000);
    });
    numOfAttempts -= 1;
  }
  // Finish the job once the inspection is complete.
  await dlpClient.finishDlpJob({name: jobName});

  // Print out the results.
  const infoTypeStats = job.inspectDetails.result.infoTypeStats;
  if (infoTypeStats.length > 0) {
    infoTypeStats.forEach(infoTypeStat => {
      console.log(
        `  Found ${infoTypeStat.count} instance(s) of infoType ${infoTypeStat.infoType.name}.`
      );
    });
  } else {
    console.log('No findings.');
  }
}
await inspectDataToHybridJobTrigger();

PHP

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


use Google\ApiCore\ApiException;
use Google\Cloud\Dlp\V2\Container;
use Google\Cloud\Dlp\V2\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DlpJob\JobState;
use Google\Cloud\Dlp\V2\HybridContentItem;
use Google\Cloud\Dlp\V2\HybridFindingDetails;

/**
 * Inspect data hybrid job trigger.
 * Send data to the hybrid job or hybrid job trigger.
 *
 * @param string $callingProjectId  The Google Cloud project id to use as a parent resource.
 * @param string $string            The string to inspect (will be treated as text).
 */

function inspect_send_data_to_hybrid_job_trigger(
    // TODO(developer): Replace sample parameters before running the code.
    string $callingProjectId,
    string $jobTriggerId,
    string $string
): void {
    // Instantiate a client.
    $dlp = new DlpServiceClient();

    $content = (new ContentItem())
        ->setValue($string);

    $container = (new Container())
        ->setFullPath('10.0.0.2:logs1:app1')
        ->setRelativePath('app1')
        ->setRootPath('10.0.0.2:logs1')
        ->setType('logging_sys')
        ->setVersion('1.2');

    $findingDetails = (new HybridFindingDetails())
        ->setContainerDetails($container)
        ->setLabels([
            'env' => 'prod',
            'appointment-bookings-comments' => ''
        ]);

    $hybridItem = (new HybridContentItem())
        ->setItem($content)
        ->setFindingDetails($findingDetails);

    $parent = "projects/$callingProjectId/locations/global";
    $name = "projects/$callingProjectId/locations/global/jobTriggers/" . $jobTriggerId;

    $triggerJob = null;
    try {
        $triggerJob = $dlp->activateJobTrigger($name);
    } catch (ApiException $e) {
        $result = $dlp->listDlpJobs($parent, ['filter' => 'trigger_name=' . $name]);
        foreach ($result as $job) {
            $triggerJob = $job;
        }
    }

    $dlp->hybridInspectJobTrigger($name, [
        'hybridItem' => $hybridItem,
    ]);

    $numOfAttempts = 10;
    do {
        printf('Waiting for job to complete' . PHP_EOL);
        sleep(10);
        $job = $dlp->getDlpJob($triggerJob->getName());
        if ($job->getState() != JobState::RUNNING) {
            break;
        }
        $numOfAttempts--;
    } while ($numOfAttempts > 0);

    // Print finding counts.
    printf('Job %s status: %s' . PHP_EOL, $job->getName(), JobState::name($job->getState()));
    switch ($job->getState()) {
        case JobState::DONE:
            $infoTypeStats = $job->getInspectDetails()->getResult()->getInfoTypeStats();
            if (count($infoTypeStats) === 0) {
                printf('No findings.' . PHP_EOL);
            } else {
                foreach ($infoTypeStats as $infoTypeStat) {
                    printf(
                        '  Found %s instance(s) of infoType %s' . PHP_EOL,
                        $infoTypeStat->getCount(),
                        $infoTypeStat->getInfoType()->getName()
                    );
                }
            }
            break;
        case JobState::FAILED:
            printf('Job %s had errors:' . PHP_EOL, $job->getName());
            $errors = $job->getErrors();
            foreach ($errors as $error) {
                var_dump($error->getDetails());
            }
            break;
        case JobState::PENDING:
            printf('Job has not completed. Consider a longer timeout or an asynchronous execution model' . PHP_EOL);
            break;
        default:
            printf('Unexpected job state. Most likely, the job is either running or has not yet started.');
    }
}

Python

如需了解如何安装和使用用于敏感数据保护的客户端库,请参阅敏感数据保护客户端库

如需向敏感数据保护服务进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import time

import google.cloud.dlp

def inspect_data_to_hybrid_job_trigger(
    project: str,
    trigger_id: str,
    content_string: str,
) -> None:
    """
    Uses the Data Loss Prevention API to inspect sensitive information
    using Hybrid jobs trigger that scans payloads of data sent from
    virtually any source and stores findings in Google Cloud.
    Args:
        project: The Google Cloud project id to use as a parent resource.
        trigger_id: The job trigger identifier for hybrid job trigger.
        content_string: The string to inspect.
    """

    # Instantiate a client.
    dlp = google.cloud.dlp_v2.DlpServiceClient()

    # Construct the `item` to inspect.
    item = {"value": content_string}

    # Construct the container details that contains metadata to be
    # associated with the content. For more details, please refer to
    # https://cloud.google.com/dlp/docs/reference/rest/v2/Container
    container_details = {
        "full_path": "10.0.0.2:logs1:app1",
        "relative_path": "app1",
        "root_path": "10.0.0.2:logs1",
        "type_": "logging_sys",
        "version": "1.2",
    }

    # Construct hybrid inspection configuration.
    hybrid_config = {
        "item": item,
        "finding_details": {
            "container_details": container_details,
            "labels": {
                "env": "prod",
                "appointment-bookings-comments": "",
            },
        },
    }

    # Convert the trigger id into a full resource id.
    trigger_id = f"projects/{project}/jobTriggers/{trigger_id}"

    # Activate the job trigger.
    dlp_job = dlp.activate_job_trigger(request={"name": trigger_id})

    # Call the API.
    dlp.hybrid_inspect_job_trigger(
        request={
            "name": trigger_id,
            "hybrid_item": hybrid_config,
        }
    )

    # Get inspection job details.
    job = dlp.get_dlp_job(request={"name": dlp_job.name})

    # Wait for dlp job to get finished.
    while job.inspect_details.result.processed_bytes <= 0:
        time.sleep(5)
        job = dlp.get_dlp_job(request={"name": dlp_job.name})

    # Print the results.
    print(f"Job name: {dlp_job.name}")
    if job.inspect_details.result.info_type_stats:
        for finding in job.inspect_details.result.info_type_stats:
            print(f"Info type: {finding.info_type.name}; Count: {finding.count}")
    else:
        print("No findings.")

典型的混合检查场景

以下部分介绍了混合检查的典型用途及其对应的工作流。

执行一次性扫描

作为季度数据库抽查工作的一部分,对 Google Cloud 之外的数据库执行一次性扫描。

  1. 使用 Google Cloud 控制台DLP API 创建混合作业。

  2. 通过调用 projects.locations.dlpJobs.hybridInspect 将数据发送到作业。如果您想检查更多数据,请根据需要重复执行此步骤。

  3. 发送数据进行检查后,调用 projects.locations.dlpJobs.finish 方法。

    敏感数据保护会执行 projects.locations.dlpJobs.create 请求中指定的操作。

配置持续监控

监控敏感数据保护本身不支持的数据库每天添加的所有新内容。

  1. 使用 Google Cloud 控制台DLP API 创建混合作业触发器。

  2. 通过调用 projects.locations.jobTriggers.activate 方法来激活作业触发器。

  3. 通过调用 projects.locations.jobTriggers.hybridInspect 将数据发送到作业触发器。如果您想检查更多数据,请根据需要重复执行此步骤。

在这种情况下,您无需调用 projects.locations.dlpJobs.finish 方法。敏感数据保护功能会自动对您发送的数据进行分区。只要作业触发器处于活动状态,敏感数据保护就会在每天结束时执行您在创建混合作业触发器时指定的操作。

扫描传入数据库的数据

扫描传入数据库的数据,同时控制数据的分区方式。 作业触发器中的每个作业都是一个分区。

  1. 使用 Google Cloud 控制台DLP API 创建混合作业触发器。

  2. 通过调用 projects.locations.jobTriggers.activate 方法来激活作业触发器。

    系统返回单个作业的作业 ID。下一步中会用到此作业 ID。

  3. 通过调用 projects.locations.dlpJobs.hybridInspect 将数据发送到作业。

    在这种情况下,您需要将数据发送到作业而不是作业触发器。通过此方法,您可以控制发送进行检查的数据的分区方式。如果要在当前分区中添加更多用于检查的数据,请重复此步骤。

  4. 将数据发送到作业后,调用 projects.locations.dlpJobs.finish 方法。

    敏感数据保护会执行 projects.locations.jobTriggers.create 请求中指定的操作。

  5. 如果要为下一个分区创建另一个作业,请再次激活作业触发器,然后将数据发送到生成的作业。

监控来自代理的流量

监控来自两个自定义应用之间安装的代理的流量。

  1. 使用 Google Cloud 控制台DLP API 创建混合作业触发器。

  2. 通过调用 projects.locations.jobTriggers.activate 方法来激活作业触发器。

  3. 通过调用 projects.locations.jobTriggers.hybridInspect 将数据发送到作业触发器。如果您想检查更多数据,请根据需要重复执行此步骤。

    您可以针对所有网络流量无限期地调用此请求。请务必在每个请求中添加元数据

在这种情况下,您无需调用 projects.locations.dlpJobs.finish 方法。敏感数据保护功能会自动对您发送的数据进行分区。只要作业触发器处于活动状态,敏感数据保护就会在每天结束时执行您在创建混合作业触发器时指定的操作。

后续步骤