Private Aggregation API 基础知识

Private Aggregation API 的核心概念

本文档的适用对象

Private Aggregation API 可从有权访问跨网站数据的工作程序中收集汇总数据。对于在 Shared Storage 和 Protected Audience API 中构建报告功能的开发者来说,本文中介绍的概念非常重要。

  • 如果您是开发者,正在构建用于跨网站衡量的报告系统。
  • 如果您是营销者数据科学家或其他摘要报告使用者,了解这些机制将有助于您做出设计决策,以检索优化的摘要报告。

关键词

在阅读本文档之前,请先熟悉一些关键术语和概念。下文将详细介绍这些术语。

  • 汇总键(也称为“桶”)是一组预先确定的数据点。例如,您可能希望收集浏览器报告国家/地区名称的一组位置数据。一个汇总键可以包含多个维度(例如,国家/地区和内容 widget 的 ID)。
  • 可汇总的值是收集到汇总键中的单个数据点。如果您想衡量有多少来自法国的用户看过您的内容,那么 France 就是汇总键中的一个维度,而 1viewCount 就是可汇总的值。
  • 可汇总的报告在浏览器中生成并加密。对于 Private Aggregation API,此参数包含有关单个事件的数据。
  • 汇总服务会处理可汇总报告中的数据,以创建摘要报告。
  • 汇总报告是 Aggregation Service 的最终输出,其中包含添加了噪声的汇总用户数据和详细的转化数据。
  • 工作程序是一种基础架构,可让您运行特定的 JavaScript 函数并将信息返回给请求者。在工作程序中,您可以执行 JavaScript,但无法与外部网页互动或通信。

不公开汇总工作流程

当您使用汇总键和可汇总的值调用 Private Aggregation API 时,浏览器会生成可汇总的报告。报告会发送到您的服务器,由该服务器对报告进行批处理。批处理报告稍后会由汇总服务处理,并生成摘要报告。

数据从客户端流向收集器,然后流向汇总服务以生成摘要报告。
从客户端到收集器的数据流。
  1. 当您调用 Private Aggregation API 时,客户端(浏览器)会生成可汇总报告并将其发送到您的服务器以供收集。
  2. 您的服务器会从客户端收集报告,并将它们分批发送到汇总服务。
  3. 收集到足够的报告后,您将对这些报告进行批处理,然后将其发送到在可信执行环境中运行的汇总服务,以生成摘要报告。

本部分中介绍的工作流程与 Attribution Reporting API 类似。不过,归因报告会将从展示事件和转化事件(发生在不同时间)收集的数据相关联。不公开汇总用于衡量单个跨网站事件。

汇总键

汇总键(简称“键”)表示将累积可汇总值的分桶。一个或多个维度可以编码到键中。维度表示您想要深入了解的某个方面,例如用户的年龄段或广告系列的展示次数。

例如,您可能在多个网站上嵌入了一个 widget,并希望分析看到该 widget 的用户的国家/地区。您希望回答诸如“看过我的 widget 的用户中有多少来自 X 国家/地区?”之类的问题。如需针对此问题生成报告,您可以设置一个用于对两个维度(微件 ID 和国家/地区 ID)进行编码的聚合键。

提供给 Private Aggregation API 的密钥是一个 BigInt,由多个维度组成。在此示例中,维度是 widget ID 和国家/地区 ID。假设 widget ID 最多可包含 4 位数字(例如 1234),并且每个国家/地区都按字母顺序映射到一个数字,例如阿富汗为 1、法国为 61、津巴布韦为 195。因此,可汇总的键将为 7 位数,其中前 4 个字符预留给 WidgetID,后 3 个字符预留给 CountryID

假设该键表示来自法国(国家/地区 ID 为 061)且已看到 widget ID 为 3276 的用户的数量,则汇总键为 3276061

汇总键
widget ID 国家/地区 ID
3276 061

还可以使用哈希机制(例如 SHA-256)生成汇总密钥。例如,字符串 {"WidgetId":3276,"CountryID":67} 可以进行哈希处理,然后转换为 42943797454801331377966796057547478208888578253058197330928948081739249096287nBigInt 值。如果哈希值超过 128 位,您可以截断该值,以确保它不会超过允许的最大存储分区值 2^128−1

在 Shared Storage worklet 中,您可以访问 cryptoTextEncoder 模块,这些模块可帮助您生成哈希。如需详细了解如何生成哈希,请参阅 MDN 上的 SubtleCrypto.digest()

以下示例说明了如何根据哈希值生成分桶键:

async function convertToBucket(data) {
  // Encode as UTF-8 Uint8Array
  const encodedData = new TextEncoder().encode(data);

  // Generate SHA-256 hash
  const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);

  // Truncate the hash
  const truncatedHash = Array.from(new Uint8Array(hashBuffer, 0, 16));

  // Convert the byte sequence to a decimal
  return truncatedHash.reduce((acc, curr) => acc * 256n + BigInt(curr), 0n);
}

const data = {
  WidgetId: 3276,
  CountryID: 67
};

const dataString = JSON.stringify(data);
const bucket = await convertToBucket(dataString);

console.log(bucket); // 126200478277438733997751102134640640264n

可汇总的值

可汇总的值会针对许多用户的每个键进行求和,以在摘要报告中生成汇总洞见(以摘要值的形式呈现)。

现在,我们回到之前提出的示例问题:“看过我的 widget 的用户中有多少来自法国?”此问题的答案将类似于“大约有 4,881 位看到过我的 widget ID 3276 的用户来自法国。”每个用户的可汇总值为 1,“4881 位用户”是汇总值,即相应汇总键的所有可汇总值的总和。

汇总键 可汇总的值
widget ID 国家/地区 ID 观看次数
3276 061 1

在此示例中,每当有用户看到该 widget 时,我们就将该值递增 1。 在实践中,可以对可汇总的值进行缩放,以提高信噪比

贡献预算

对 Private Aggregation API 的每次调用都称为一次“贡献”。为保护用户隐私,系统会限制可从个人收集的贡献数量。

当您对所有汇总键的所有可汇总值求和时,总和必须小于贡献预算。预算的范围限定为每个工作程序来源、每天,并且 Protected Audience API 工作程序和 Shared Storage 工作程序的预算是分开的。一天的时间范围为大约过去 24 小时。如果新的可汇总报告会导致超出预算,则不会创建该报告。

贡献预算由形参 L1 表示,设置为每天每十分钟 216 (65,536),上限为 220 (1,048,576)。如需详细了解这些参数,请参阅说明

贡献预算的值是任意的,但噪声会按比例调整为该值。 您可以使用此预算最大限度地提高汇总值的信噪比(详见噪声和缩放部分)。

如需详细了解贡献预算,请参阅说明。 另请参阅贡献预算,了解更多指导。

每个报告的贡献者人数上限

根据调用者的不同,贡献限额可能会有所不同;对于共享存储空间,这些限额是可替换的默认限额。目前,为 Shared Storage API 调用方生成的报告的贡献数上限为每个报告 20 个。另一方面,Protected Audience API 调用方的每次报告最多可包含 100 个贡献。之所以选择这些限制,是为了平衡可嵌入的贡献数量与载荷大小。

对于共享存储空间,在单个 run()selectURL() 操作中做出的贡献会批处理到一份报告中。对于 Protected Audience,单个来源在竞价中做出的贡献会批量处理。

带内边距的贡献

使用填充功能进一步修改贡献。填充载荷的行为可保护嵌入在可汇总报告中的有关真实贡献数量的信息。填充会向载荷添加 null 个贡献(即值为 0),以达到固定长度。

可汇总的报告

用户调用 Private Aggregation API 后,浏览器会生成可汇总报告,以供汇总服务在稍后处理,从而生成摘要报告。可汇总报告采用 JSON 格式,包含加密的贡献列表,每个贡献都是一个 {aggregation key, aggregatable value} 对。 可汇总报告会以最长一小时的随机延迟时间发送。

贡献内容已加密,无法在汇总服务之外读取。 汇总服务会对报告进行解密,并生成摘要报告。浏览器加密密钥和汇总服务的解密密钥由协调器(充当密钥管理服务)颁发。协调器会保留服务映像的二进制哈希列表,以验证调用方是否获准接收解密密钥。

启用了调试模式的可汇总报告示例:

  "aggregation_service_payloads": [
    {
      "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAE0mlvcGVyYXRpb25paGlzdG9ncmFt",
      "key_id": "2cc72b6a-b92f-4b78-b929-e3048294f4d6",
      "payload": "a9Mk3XxvnfX70FsKrzcLNZPy+00kWYnoXF23ZpNXPz/Htv1KCzl/exzplqVlM/wvXdKUXCCtiGrDEL7BQ6MCbQp1NxbWzdXfdsZHGkZaLS2eF+vXw2UmLFH+BUg/zYMu13CxHtlNSFcZQQTwnCHb"
    }
  ],
  "debug_key": "777",
  "shared_info": "{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"5bc74ea5-7656-43da-9d76-5ea3ebb5fca5\",\"reporting_origin\":\"https://localhost:4437\",\"scheduled_report_time\":\"1664907229\",\"version\":\"0.1\"}"

您可以在 chrome://private-aggregation-internals 页面中检查可汇总报告:

Private Aggregation API 内部页面
Private Aggregation API 内部页面

出于测试目的,您可以使用“发送所选报告”按钮立即将报告发送到服务器。

收集可汇总报告并将其分批发送

浏览器会使用以下列出的知名路径,将可汇总报告发送到包含对 Private Aggregation API 的调用的工作程序的来源:

  • 对于 Shared Storage:/.well-known/private-aggregation/report-shared-storage
  • 对于 Protected Audience: /.well-known/private-aggregation/report-protected-audience

在这些端点,您需要运行一个服务器(充当收集器),以接收从客户端发送的可汇总报告。

然后,服务器应将报告分批发送到汇总服务。根据可汇总报告的未加密载荷中的可用信息(例如 shared_info 字段)创建批次。理想情况下,每个批次应包含 100 份或更多报告。

您可以选择每天或每周批量处理。此策略非常灵活,您可以针对预计会产生更多流量的特定活动更改批处理策略,例如预计会产生更多展示次数的日期。 批次应包含来自同一 API 版本、报告来源和预定报告时间的报告。

过滤 ID

借助 Private Aggregation API 和 Aggregation Service,您可以使用过滤 ID 以更精细的级别(例如,按广告系列)处理衡量数据,而不是在较大的查询中处理结果。

不公开汇总和汇总服务过滤 ID。
Private Aggregation 和 Aggregation Service 过滤 ID。

如需立即开始使用,请参考以下大致步骤,将其应用于您当前的实现。

共享存储空间步骤

如果您在流程中使用 Shared Storage API

  1. 定义您将声明和运行新的共享存储模块的位置。 在以下示例中,我们将模块文件命名为 filtering-worklet.js,并将其注册在 filtering-example 下。

    (async function runFilteringIdsExample () {
    await window.sharedStorage.worklet.addModule('filtering-worklet.js');
    await window.sharedStorage.run('filtering-example', {
      keepAlive: true,
      privateAggregationConfig: {
        contextId: 'example-id',
        filteringIdMaxBytes: 8 // optional
      }
    }});
    })();
    

    请注意,filteringIdMaxBytes 可针对每个报告进行配置,如果未设置,则默认为 1。此默认值旨在防止不必要地增加载荷大小,从而避免增加存储和处理费用。如需了解详情,请参阅灵活贡献说明

  2. filtering-worklet.js 中,当您将贡献传递给 Shared Storage worklet 中的 privateAggregation.contributeToHistogram(...) 时,可以指定过滤 ID。

    // Within  filtering-worklet.js
    class FilterOperation {
      async run() {
        let contributions = [{
          bucket: 1234n,
          value: 56,
          filteringId: 3n // defaults to 0n if not assigned, type bigint
        }];
    
        for (const c of contributions) {
          privateAggregation.contributeToHistogram(c);
        }
        
    }
    });
    
    register('filtering-example', FilterOperation);
    
  3. 可汇总报告将发送到您定义端点 /.well-known/private-aggregation/report-shared-storage 的位置。请继续参阅过滤 ID 指南,了解在汇总服务作业参数中需要做出的更改。

在完成批处理并将其发送到已部署的汇总服务后,过滤后的结果应会反映在最终的摘要报告中。

Protected Audience 步骤

如果您在流程中使用 Protected Audience API,请执行以下操作:

  1. 在当前实现的 Protected Audience 中,您可以设置以下内容来接入 Private Aggregation。与共享存储空间不同,目前还无法配置过滤 ID 的最大大小。默认情况下,过滤 ID 的最大大小为 1 字节,并将设置为 0n。请注意,这些参数将在 Protected Audience 报告函数(例如 reportResult()generateBid())中设置。

    const contribution = {
      ...
      filteringId: 0n
    };
    
    privateAggregation.contributeToHistogram(contribution);
    
  2. 可汇总报告将发送到您定义端点 /.well-known/private-aggregation/report-protected-audience 的位置。在批处理完成并发送到已部署的汇总服务后,过滤后的结果应会反映在最终的摘要报告中。以下是 Attribution Reporting API 和 Private Aggregation API 的解说文档(以及初始提案)。

您可以继续阅读汇总服务中的过滤 ID 指南,也可以前往 Attribution Reporting API 部分,详细了解相关信息。

汇总服务

该服务在 TEE 中运行,对可汇总的报告进行解密并添加噪声,以创建最终的摘要报告。
该服务在 TEE 中运行,对可汇总报告进行解密并添加噪声,以创建最终的摘要报告。

汇总服务从收集器接收加密的可汇总报告,并生成摘要报告。如需了解有关如何在收集器中批量处理可汇总报告的更多策略,请参阅我们的批处理指南

该服务在可信执行环境 (TEE) 中运行,可为数据完整性、数据机密性和代码完整性提供一定程度的保证。如果您想详细了解如何将协调器与 TEE 搭配使用,请详细了解它们的角色和用途

摘要报告

汇总报告可让您查看添加了噪声的收集数据。您可以针对给定的密钥集请求摘要报告。

摘要报告包含一组 JSON 字典样式的键值对。每个配对包含:

  • bucket:以二进制数字字符串形式表示的汇总键。如果使用的汇总键为“123”,则分桶为“1111011”。
  • value:给定衡量目标的汇总值,通过对所有可汇总的报告求和(添加噪声)得出。

例如:

[
  {"bucket":` `"111001001",` `"value":` `"2558500"},
  {"bucket":` `"111101001",` `"value":` `"3256211"},
  {"bucket":` `"111101001",` `"value":` `"6536542"},
]

噪声和缩放

为保护用户隐私,每次请求摘要报告时,Aggregation Service 都会向每个摘要值添加一次噪声。噪声值是从 Laplace 概率分布中随机抽取的。虽然您无法直接控制添加噪声的方式,但可以影响噪声对其衡量数据的影响。

无论所有可汇总值的总和是多少,噪声分布都是相同的。因此,可汇总的值越高,噪声可能产生的影响就越小。

例如,假设噪声分布的标准差为 100,且以零为中心。如果收集的可汇总报告值(或“可汇总值”)仅为 200,则噪声的标准差将为汇总值的 50%。但是,如果可汇总的值为 20,000,则噪声的标准差仅为汇总值的 0.5%。因此,20,000 的可汇总值将具有更高的信噪比。

因此,将可汇总的值乘以缩放比例有助于减少噪声。缩放比例表示您要将给定的可汇总值缩放多少。

无论汇总值是多少,噪声都是恒定的。
与汇总值无关的噪声常数。

选择较大的缩放比例来放大值可减少相对噪声。不过,这也导致所有分桶中所有贡献的总和更快达到贡献预算上限。选择较小的缩放比例常数来缩小值会增加相对噪声,但会降低达到预算上限的风险。

将可汇总的值缩放到贡献预算。
将可汇总的值缩放到贡献预算。

如需计算合适的缩放比例,请将贡献预算除以所有键的可汇总值的最大总和。

如需了解详情,请参阅贡献预算文档

互动和分享反馈

Private Aggregation API 正在积极讨论中,未来可能会发生变化。如果您试用了此 API 并有反馈意见,欢迎随时告诉我们。