归因第 1 级

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-attribution-20260708/
最新发布版本:
https://www.w3.org/TR/attribution/
编辑草案:
https://w3c.github.io/attribution/
先前版本:
历史:
https://www.w3.org/standards/history/attribution/
反馈:
public-patwg@w3.org 主题行为 “[attribution] … 消息主题 …”(存档
GitHub
编辑:
(Google)
(Mozilla)
(Meta)
(Meta)
(Google)
(Mozilla)

摘要

本规范定义了一种用于衡量广告效果的浏览器 API。其目标是生成有关广告如何带来转化的聚合统计信息, 同时不对单个 Web 用户的隐私造成风险。此 API 会汇集来自多个 Web 源的有关用户的信息, 这可能对他们的隐私造成重大风险。为管理这种风险,所收集的信息会使用聚合服务进行聚合, 该服务受到用户代理信任,能够在严格限制内执行聚合。此服务生成的聚合结果会加入噪声, 以提供差分隐私。网站可以从用户代理提供的已批准聚合服务列表中选择聚合服务。

本文档状态

本节描述本文档在发布时的状态。当前 W3C 出版物列表以及本 技术报告的最新修订版可在 W3C 技术报告索引中找到。

欢迎对此规范提供反馈和评论。 推荐使用 GitHub Issues 讨论此 规范。或者,也可以将评论发送到 PAT 工作组的邮件列表 public-patwg@w3.org存档)。 本草案突出显示了一些仍有待工作组讨论的待处理议题。 对于这些议题的结果,包括它们是否有效,尚未作出决定。

本文档由 Private Advertising Technology Working Group 作为工作草案发布,并使用 推荐 标准轨道

作为工作草案发布并不意味着得到 W3C 及其成员的认可。

这是一份草案文档,可能随时由其他文档更新、替换或废弃。除作为正在进行的工作外, 不宜引用本文档。

本文档会随时维护和更新。本文档的某些部分仍在进行中。

本文档由一个根据 W3C 专利政策运作的小组制作。W3C 维护着一个与该小组交付成果相关的所有专利披露公开列表; 该页面还包含披露专利的说明。实际知悉某项专利且认为该专利包含必要权利要求的个人,必须按照 W3C 专利政策第 6 节披露该信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档约束。

1. 引言

本文档定义了一个浏览器 API, 该 API 能够收集经过聚合且具有差分隐私保护的指标。

此 API 的目标是为广告启用归因。

1.1. 归因

在广告中,归因 是识别先于某个感兴趣结果发生的操作, 并将价值分配给这些操作的过程。

广告主感兴趣的操作 主要是广告的展示 (也称为 展示)。 其他操作包括广告点击(或其他交互), 以及未被采用的广告展示机会。

广告所期望的结果 更加多样, 因为它们包括广告主希望通过展示广告来改善的任何结果。 期望的结果也可以称为一次转化, 指将潜在客户“转化”为客户。 可算作转化的内容可能包括 销售、订阅、页面访问和咨询。

对于此 API,操作结果都是 事件:即只发生一次的事情。 广告归因的独特之处在于, 这些事件可能不会发生在同一个站点上。 广告最常展示在广告主站点以外的站点上。

归因的主要挑战在于维护隐私。 归因涉及连接不同站点上的活动。 归因的目标是找到一次展示, 该展示在转化发生之前已向同一个人展示。

如果归因信息被直接透露, 它将导致不期望的 跨上下文识别, 从而导致跟踪

本文档通过确保使用聚合服务 来聚合归因信息,从而避免跨上下文识别。 聚合服务被信任用于计算聚合结果, 而不会暴露每个人对该聚合结果所贡献的值。

对每个浏览器实例为给定站点的聚合结果 所贡献的信息量设有严格限制。 差分隐私用于为每次贡献提供额外的隐私保护。

聚合服务操作的详细信息包含在 § 6 聚合中。 所使用的差分隐私设计概述见 § 7 差分隐私

1.2. 背景

从 Web 的早期开始, 广告就被广泛用于为站点创建提供资金支持。

Web 区别于其他广告场所的一个特征, 是能够获得有关广告活动效果的信息。

Web 广告主能够衡量覆盖率(有多少人看到了广告)、 频次(每个人看到广告的频率)、 以及转化(有多少看到广告的人 之后执行了该广告意图促使其执行的操作)等关键指标。 相比之下,这些衡量比任何其他媒介都更及时且更准确。

衡量效果的代价是隐私。 为了生成准确且全面的信息, 广告业务会对所有 Web 用户的活动进行广泛跟踪。 每个浏览器都会被分配一个跟踪标识符, 通常使用由跨站内容记录的 cookie。 每个感兴趣的操作都会针对该标识符进行记录, 从而形成一个人的在线活动的完整记录。

拥有一个人的详细操作记录使广告主能够推断人们的特征。 这些特征使选择合适广告受众变得更加容易, 从而大幅提升广告效果。 这产生了收集更多信息的强烈激励。

在线广告竞争非常激烈。 展示广告的站点寻求从每个广告位获得最多收益。 广告主则寻求在相对于成本而言最能产生效果的位置投放广告。 这些实体——以及代表它们运作的中介方——所获得的任何竞争优势, 都取决于拥有关于潜在受众的更全面信息。

随着时间推移,感兴趣的操作扩展到几乎包括在线活动的每个方面。 人们还设计出方法,将这些信息与 Web 之外的活动相关联。 一个活跃的交易行业已经形成, 其中有多个个人信息供应商将个人信息用于各种目的进行交易。

1.3. 目标

本文档的目标是定义一种执行广告归因的方式, 且不会导致跟踪。

1.4. 最终用户益处

广告效果衡量会产生新的跨站信息流。 该信息流会产生隐私风险或成本——即跨上下文识别——因此需要以最终用户收益为依据进行正当化。

最终用户通过使用归因所实现的任何收益都是间接的。

访问网站的最终用户 主要通过他们对站点向其展示的任何广告所给予的注意力, 来为“免费”内容或服务付费。 这种“价值”归属于广告主, 广告主进而向站点付款。 站点预期会使用这笔资金 来支持其内容或服务的提供。

| Advertiser | | | Attention | | +-------------+ +-----+------+ ^ | | Content and | Money | Services | | v .----+------. +------------+ | Content | | | | Production | Investment | | Profit, | / |<-----------+ Website +-------> | Service | | | Expenses, | Improvement | | | etc... '-----------' +------------+ ]]> 用户 广告主 注意力 内容和 金钱 服务 内容 生产 投资 利润、 / 网站 服务 费用、 改进 等…
广告支持的内容和服务的价值交换

参与归因衡量系统 会构成 Web 用户的次级成本。

支持归因可带来更有效的广告, 主要方式是让广告主了解哪些广告效果最好, 以及在何种情况下效果最好。 这些情况可能包括 广告展示的时间和地点、 广告展示给谁, 以及广告本身的细节。

将这些信息连接到结果, 使广告主能够了解哪些情况最常导致 他们最看重的结果。 这使广告主能够在有效广告上投入更多, 在无效广告上投入更少。 这降低了相对于所获价值而言的总体广告成本。[ONLINE-ADVERTISING]

提供广告库存的站点, 例如内容发布者和服务提供商, 会间接受益于更高效的广告。 能够更好展示广告并产生广告主所寻求结果的广告场所, 可以对广告位收取更高费用。

通过投放广告获得支持的站点, 能够更好地提供优质内容或服务。 重要的是,这种支持来自其受众的方式并不均匀。 与其他形式的资金支持相比,这可能更加公平。 那些对广告商品消费倾向或能力较低的人, 可以获得与有能力付费的人相同的广告支持内容和服务。[EU-AD][COPPACALYPSE]

提供由广告支持的“免费”服务的能力 具有可衡量的经济收益, 这些收益源自这些服务的价值。[FREE-GDP]

1.5. 集体隐私效应

如果正确实现,聚合的使用可确保提供给站点的信息 是关于群体而非个人的信息。

因此,该机制的引入代表了一种集体决策, 符合集体隐私的理念。

当参与群体更大时, 参与归因衡量所带来的隐私成本更低。 这是由于聚合会影响站点 从聚合结果中提取有关个人信息的能力。 对于中心化差分隐私尤其如此, 它是本规范所用隐私设计的数学基础。

更大的参与者群组还会产生更具代表性——因而也更有用——的 关于所衡量广告的统计信息。

如果归因是正当的, 这两个因素都会推动为所有用户启用归因。

用户代理采取行动启用归因衡量, 对某些人来说不会受到积极接受。 不同的人对参与广告所带来的成本和收益 有不同感受。 所提出的设计允许人们选择看起来参与了归因, 而不会向站点暴露这一选择;参见 § 9.2 禁用 Attribution API

1.6. 使用直方图进行归因

归因 试图衡量一个或多个广告投放(展示) 与广告主期望的结果之间的相关性。

在聚合层面考虑时, 关于个人的信息并无用处。 操作和结果需要被分组。

最简单的归因形式根据广告的属性 将展示划分为若干分组, 并统计转化次数。 分组可能由以下属性形成: 广告展示的位置、 展示的内容(“创意”)、 广告展示的时间, 或展示给谁。

这些分组 以及归因到每个分组的转化计数 构成一个直方图。 直方图的每个桶统计 某一组广告的转化次数。

example.com news.example classified.example search.example
转化计数的示例直方图, 按展示所在站点分组

不同的分组可用于不同目的。 例如,按创意(广告内容)分组 可用于了解哪个创意效果最好。

在每次转化时添加一个大于一的值, 可以支持不只是简单计数的功能。 直方图还可以聚合值, 这可用于区分不同结果。 分配给展示的值 称为转化 值。 较高的转化值可用于较大的购买, 或任何价值更高的结果。 转化值也可以在多个展示之间拆分, 以分摊功劳。

2. 操作概述

Attribution API 提供关于两类事件之间关联的聚合信息: 展示转化

展示是广告主在任何网站上执行的任何操作。 此 API 不限制可记录为展示的内容。 广告主可能希望衡量的典型操作包括:

对于此 API,转化是正在衡量的结果。 此 API 不限制什么可以被视为结果。 广告主可能希望衡量的典型结果包括:

本节其余部分描述 Attribution API 如何与聚合服务 结合运作, 以生成聚合归因衡量结果。 该操作如下面的图所示。

| | | Advertiser | | Aggregation | | Server | | Service | | |<-----------+ | +--------------+ Histogram +-------------+ ^ ^ ^ Conversion | | | Reports | | '-----------. | '-----------. | | | | +-------------+-+-+ +---------+----+ | | | | | | | | Other Users | Publisher | | | | Advertiser | | Site(s) | | | | Site | | | | | | | +------+------+-+-+ +-----+--------+ | | ^ saveImpression | measureConversion | | Conversion | | | Report v v | +-------------------------------------+---------+ | | | Private Attribution APIs | | | +-----------------------------------------------+ ^ | v .-----------. | | | Impression | | Store | | | '-----------' ]]> 转化 报告 广告主 聚合 服务器 服务 直方图 转化 报告 其他用户 发布者 广告主 站点 站点 saveImpression measureConversion 转化 报告 Private Attribution APIs 展示 存储
归因操作概述

2.1. 记录展示

当一个展示发生时, 可以使用 saveImpression() 方法 请求浏览器保存信息。 这包括该展示的一个标识符, 以及关于该展示的一些附加信息。 例如,广告主可能会使用附加信息 来记录该展示是广告浏览还是广告点击。

2.2. 转化或查询展示

转化时,会创建一个转化报告转化报告 是一个加密的直方图贡献, 其中包含来自浏览器先前存储的任何展示的信息。

measureConversion() 方法接受一个受限查询, 该查询用于 告诉浏览器如何构造一个转化报告。 其中包括用于从浏览器已存储的展示中进行选择的值, 分配给所选展示的转化值, 以及构造该转化报告所需的其他信息。

转化报告创建的直方图按如下方式构造:

浏览器会更新隐私预算存储,以反映已报告的转化。

生成的直方图会根据所选聚合服务的要求 为聚合做好准备,并返回给站点。 这至少涉及对直方图进行加密。

调用此 API 的站点将始终收到有效的转化报告。 因此,站点不会通过此交互了解到其他站点上发生了什么。

2.3. 聚合

站点可以收集它从对此 API 的调用中收到的加密直方图, 并将它们提交给聚合服务。

在从某个站点接收到一组加密直方图后,聚合服务会:

  1. 确认它先前没有 根据所提供的输入 计算过聚合结果, 并且有足够的转化报告,

  2. 对直方图求和,包括足够的 噪声, 以生成一个差分隐私的聚合直方图,并且

  3. 将该聚合结果返回给站点。

我们将聚合服务的最终输出称为 归因结果

浏览器实现需要拥有一组受信任的聚合服务, 以可靠地执行上述功能。 从所提供的服务集合中, 转化站点 需要 与其所选择的服务达成协议, 由该服务执行聚合。

浏览器可能会建立用于注册聚合服务的项目, 其性质类似于 根存储项目, 用于授权浏览器在验证 Web PKI 证书时 使用的证书颁发机构。 建立这样的项目 不在本文档范围内。

3. API 使用

使用 Attribution API 的站点通常会注册 展示转化,但在某些情况下, 同一站点可能 两者都做。

要注册一次展示,站点调用 saveImpression()。除收集参数值外, 使用此 API 不需要任何准备,不过 在决定是否使用 Attribution API 时,检查受支持的 aggregationServices 可能很有用。

也可以在向用户代理提供资源时, 通过在 HTTP 响应中包含 `Save-Impression` 标头来注册一次展示。

要请求转化报告,站点调用 measureConversion()。 在调用此 API 之前,站点必须 选择一个受支持的聚合服务。 页面可以从 aggregationServices 中找到的受支持服务中选择任意一个。 所选服务的名称必须在调用 measureConversion() 方法时, 作为 aggregationService 成员提供给 AttributionConversionOptions 字典。

3.1. 站点身份

此 API 依赖 HTML 对站点的定义, 并将其作为其操作所围绕的主要作用域。 它识别三类站点:

此 API 使用站点 而不是, 因为它依赖于将所有可能具有隐私后果的活动 与单个实体关联起来。 像 cookie 这样的功能允许 同站 自由交换隐私相关信息, 否则这些信息可能被用来超出隐私预算

此 API 的所有功能都附加到 navigator.attribution 属性。

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute Attribution attribution;
};

这提供了三个关键功能:

3.3. 查找受支持的聚合服务

aggregationServices 属性 包含用户代理支持的一组聚合服务。页面 在调用 measureConversion() 方法时, 必须选择并指定其中一个服务。 在注册展示之前查询受支持的服务 也可能有用, 但这不是必需的, 且展示并不限定于单个聚合服务。

站点可能会有一个 它所使用的聚合服务偏好顺序。 以下代码会遍历偏好列表, 并找到一个用户代理支持的服务。

const preferredServices = [
  "https://aggregator.example/tee",
  "https://aggregator.example/dap",
  "https://example.com/aggregator",
];
const supportedServices = navigator.attribution?.aggregationServices;
const serviceUrl = preferredServices.find(url => supportedServices?.has(url));

如果用户代理支持该 URL, 且其中包含一个偏好服务, 则第一个偏好服务会被保存到 名为 serviceUrl 的变量中。 否则,serviceUrl 将保持为 undefined

enum AttributionAggregationProtocol { "dap-18-histogram" };

dictionary AttributionAggregationService {
  required AttributionAggregationProtocol protocol;
};

[SecureContext, Exposed=Window]
interface AttributionAggregationServices {
  readonly maplike<USVString, AttributionAggregationService>;
};

[SecureContext, Exposed=Window]
interface Attribution {
  readonly attribute AttributionAggregationServices aggregationServices;
};

aggregationServices 属性是 从用于标识聚合服务的 URL 到 该服务元数据的映射:

protocol类型为 AttributionAggregationProtocol
聚合服务所使用的 protocol。 同一协议的不同版本使用不同的值。 即使单个服务提供方支持多个协议, 每个协议也需要使用不同的 URL。 这确保每个协议都可以通过 URL 被唯一标识, 而无需同时指定协议选择。

该 URL 会作为 aggregationService 参数传递给 measureConversion(), 以选择所标识的聚合服务。

AttributionAggregationProtocol 描述了 不同 聚合服务 所使用的提交协议。本文档定义了一种协议:

dap-18-histogram
一种基于 DAP 的协议 [DAP],它使用 MPC;见 § 6.1 多方 计算聚合

3.4. 保存展示

saveImpression() 方法请求 用户代理展示存储中记录一次展示

为广告主展示广告的站点 可以保存一次展示。

在这种情况下,站点会直接保存展示, 标识广告主(advertiser.example), 并包含由广告主协商的信息。 在以下示例中, 这包括广告主稍后可能用于选择此广告的 matchValue 值(2)、 用于包含任何已归因值的直方图索引(histogramIndex = 3), 以及一个至少与广告主要求一样长的保留期(lifetimeDays = 7)。

navigator.attribution.saveImpression({
  histogramIndex: 3,
  matchValue: 2,
  conversionSites: ["advertiser.example"],
  lifetimeDays: 7,
});

或者,中介方, 例如供应方平台(SSP)或需求方平台(DSP), 可以从 iframe 调用同一 API。 从一个框架进行同一 API 调用, 会导致随展示一起保存中介方站点身份。

dictionary AttributionImpressionOptions {
  required unsigned long histogramIndex;
  unsigned long matchValue = 0;
  sequence<USVString> conversionSites = [];
  sequence<USVString> conversionCallers = [];
  unsigned long lifetimeDays = 30;
  long priority = 0;
};

dictionary AttributionImpressionResult {
};

[SecureContext, Exposed=Window]
partial interface Attribution {
  Promise<AttributionImpressionResult> saveImpression(AttributionImpressionOptions options);
};

saveImpression() 的参数如下:

histogramIndex, 类型为 unsigned long
如果 measureConversion() 将此 展示 与后续的 转化 匹配,则 转化值 将被添加到由此索引标识的直方图桶中。
matchValue, 类型为 unsigned long,默认为 0
与该展示关联的一段可选元数据。该值 可用于识别哪些展示可以接收来自 某个 转化 的归因。
conversionSites, 类型为 sequence<USVString>,默认为 []
此展示的 转化 站点 可在其中发生 转化 的顶级站点, 由其域名标识。 measureConversion() 方法 只有在由所指示的站点之一调用时,才会归因到此展示。 如果为空,则任何 转化 站点 都会匹配。
conversionCallers, 类型为 sequence<USVString>, 默认为 []
能够为 转化 选择 此展示的 中介 站点转化站点, 由其域名标识。 measureConversion() 方法 只有在由所指示的站点之一调用时,才会归因到此展示。 此选项包括 转化站点中介站点。 如果为空,则任何调用该 API 的站点都会匹配。
lifetimeDays, 类型为 unsigned long,默认为 30
一个正的“生存时间”(以天为单位),在该时间之后,展示 将不再 能够接收归因。 用户代理 应对该生命周期施加上限, 并且如果此处指定的值超过该上限,则静默降低该值。
priority, 类型为 long,默认为 0
一个整数,用于在归因期间对 展示 进行排序。

3.5. 请求对转化进行归因

measureConversion() 方法请求 用户代理对某次转化执行归因, 并返回一个转化 报告

measureConversion() 方法 始终返回转化报告, 无论是否找到匹配的展示。 如果没有匹配项,或者差分隐私不允许 报告归因,则返回的转化报告不会 对直方图作出贡献,即会全为零。

观察到某次转化的站点 可能会选择请求衡量 不同已存储展示的效果。

为了请求创建加密的衡量结果, 站点会调用 measureConversion() 方法。

此函数接受四种不同类型的输入:

  1. 所选聚合服务, 该服务使用 URL 标识。 选择聚合服务的示例过程 展示了如何选择浏览器支持的服务。

    const serviceDetails = {
      aggregationService: serviceUrl,
    };
    
  2. 聚合衡量的详细信息。 这些值在多个浏览器对 API 的所有调用中 都将保持一致。 这包括直方图的大小 以及可能已消耗的隐私预算量。

    const aggregatedMeasurementDetails = {
      histogramSize: 20,
      epsilon: 1,
    };
    
  3. 一组属性, 全部都是可选的, 用于选择要考虑的展示。 这包括展示可以有多旧 (lookbackDays)、 可能已保存展示的展示 站点impressionSites)、 可能已保存展示的中介方站点impressionCallers), 以及 matchValues 的选择。

    const selectionDetails = {
      lookbackDays: 14,
      impressionSites: ["publisher.example", "other.example"],
      impressionCallers: ["ad-tech.example"],
      matchValues: [2],
    };
    
  4. 归因 逻辑参数。

    const attributionDetails = {
      // top impression's histogram index gets 50% of value, the next two 25% each
      credit: [.5, .25, .25],
      value: 3,
      maxValue: 7,
    };
    

一旦这些值确定, 站点就会调用 API 以获得一个加密的转化报告

const measurement = await navigator.attribution.measureConversion({
  ...serviceDetails,
  ...aggregatedMeasurementDetails,
  ...selectionDetails,
  ...attributionDetails,
});
sendReportToServer(measurement.report);

报告可以被 收集, 并与来自此浏览器和其他浏览器的其他报告一起收集。 随后,收集到的报告可以全部提交给聚合服务, 以获得聚合直方图

dictionary AttributionConversionOptions {
  required USVString aggregationService;
  double epsilon = 1.0;

  required unsigned long histogramSize;

  unsigned long lookbackDays;
  sequence<unsigned long> matchValues = [];
  sequence<USVString> impressionSites = [];
  sequence<USVString> impressionCallers = [];

  sequence<double> credit;
  unsigned long value = 1;
  unsigned long maxValue = 1;
};

dictionary AttributionConversionResult {
  required Uint8Array report;
};

[SecureContext, Exposed=Window]
partial interface Attribution {
  Promise<AttributionConversionResult> measureConversion(AttributionConversionOptions options);
};

measureConversion() 的参数如下:

aggregationService, 类型为 USVString
可在 aggregationServices 中找到的 聚合服务 中的一个选择。
epsilon, 类型为 double,默认为 1.0
要在此 转化报告 上支出的 隐私 预算 量。
histogramSize, 类型为 unsigned long
转化报告 中要使用的直方图桶数量。
lookbackDays, 类型为 unsigned long
一个正整数天数。只有过去 lookbackDays 天内发生的展示可以匹配此 转化。如果 省略,则等同于 最大回溯期
matchValues, 类型为 sequence<unsigned long>,默认为 []
一组可用于选择 展示 的匹配值集合
impressionSites, 类型为 sequence<USVString>,默认为 []
一个展示站点集合。 只有在记录时其 展示站点 属于此集合的 展示 才有资格匹配此 转化。 如果为空,则任何站点都会匹配。
impressionCallers, 类型为 sequence<USVString>,默认为 []
一组集合, 其成员为 可能已调用 saveImpression() API 的站点, 包括 展示站点中介 站点。 如果非空, 则只有由所列站点之一记录的 展示 才有资格匹配此 转化
value, 类型为 unsigned long,默认为 1
转化 值。如果进行了归因且满足隐私 限制,则此值将被编码进 转化报告
maxValue, 类型为 unsigned long,默认为 1
聚合中包含的所有贡献里的最大 转化 值。 与 epsilon 一起,用于校准将被添加到结果中的随机噪声的分布。 它还用于确定要在此 转化报告 上支出的 隐私预算 量。
credit, 类型为 sequence<double>
一个由有限正数组成的列表, 描述如何在多个展示之间分配 转化值。 该值会按列表中值的比例 在选中的展示列表之间拆分, 顺序按指定顺序。 如果选中的展示少于此列表中的值, 则忽略此列表中的任何额外项。 缺省时,转化值会分配给单个展示。

3.6. 中介方的角色

此 API 支持中介方 代表顶级站点进行操作。 广告经常委托给负责投放、竞价和衡量的独立运营方。

由中介方保存的展示 会记录中介方站点的身份。 在为转化衡量选择展示时, 可以使用中介方站点 身份来选择展示。

3.7. 直方图构造

从概念上讲,每个已保存的展示 都有一个单一的直方图定义。 每个展示都有一个单一的直方图索引属性, 用于确定分配给该展示所得直方图中出现的位置。

因此,每次调用 measureConversion() 都需要选择具有相同直方图定义的展示。 尽管这适用于 API 的所有使用, 但当展示 由多个中介方保存衡量时, 一致定义直方图尤其重要。

调用 measureConversion() 时可能被选择的所有展示 都需要使用相同的直方图定义。 此 API 提供了几种工具, 用于确保只选择正确的展示

对于已保存的展示

作为转化通用 匹配逻辑的一部分:

这些选项为站点在归因如何选择直方图方面提供了灵活性。 它不排除转化站点使用不同直方图。 可以保存具有不同直方图定义的多个展示, 前提是 measureConversion() 调用 永远不会选择 具有不同直方图定义的展示。 这确保可以通过多次调用 measureConversion(), 将转化归因到 多个直方图。

3.8. 权限策略集成

委托给中介方的能力 由权限策略控制。

本规范定义了两个策略控制特性

这两个特性的默认允许列表 都是 *

saveImpression()measureConversion() 分别设置权限, 允许同时执行两者的页面将子资源 限制为预期类型的活动。

默认启用权限 简化了集成外部服务的任务。

权限策略只提供全有或全无的控制; 它不支持委托部分隐私预算。

4. API 内部机制

4.1. 展示存储

展示存储measureConversion() 方法用于查找匹配的 展示

尽管此 API 允许站点存储数据, 展示存储 并不使用存储键

4.1.1. 内容

展示存储是一组 集合,其元素为展示

匹配值传递给 saveImpression()matchValue
展示站点调用 saveImpression()展示 站点
中介方站点调用 saveImpression()中介方站点, 或者如果 API 由展示站点调用,则为 undefined
转化站点传递给 saveImpression()集合,其元素为转化站点
转化调用方一组站点集合, 这些站点可以是转化站点中介方站点, 它们可在调用 measureConversion() 时选择此展示
时间戳调用 saveImpression() 的时间。
生命周期展示保持有资格接收归因的持续时间,该持续时间来自 saveImpression() 调用,或来自用户代理定义的限制。
直方图索引传递给 saveImpression() 的直方图索引。
优先级一个整数,用于在归因期间对展示进行排序。

4.1.2. 维护

用户 代理应定期使用 时间戳生命周期值 来识别并删除展示存储中 任何已过期的展示

无需在展示到期后立即移除它们, 只要 measureConversion() 会将已过期的展示排除在 归因之外即可。 但是, 用户 代理不应无限期保留已过期的展示

4.1.3. Clear-Site-Data 集成

`Clear-Site-Data` 字段 [CLEAR-SITE-DATA] 赋予站点移除用户代理维护状态的能力。 `"impressions"` 类型被添加到已识别类型列表中, 该列表定义于 Clear Site Data § 3.1 Clear-Site-Data HTTP 响应标头字段

当调用 clear site data for response 算法时, 如果类型列表包含 `"impressions"`, 则调用 clear impressions for a site, 并传入 origin

为站点清除 展示, 给定一个 origin, 运行以下步骤:
  1. 如果 origin 不是元组源,则返回。

  2. site 为通过调用获得可注册域所返回的值, 并传入 origin主机部分。

  3. 对于展示 存储的每个展示 impression执行以下操作

    1. 如果 impression中介方站点undefined,且 其展示站点等于 site, 则从展示存储移除 impression继续

    2. 如果 impression 有一个等于 site中介方站点, 则从展示存储移除 impression继续

    3. 如果 impression转化站点包含 site

      1. impression转化站点移除 site

      2. 如果 impression转化站点为空, 则从展示存储移除 impression继续

    4. 如果 impression转化调用方包含 site

      1. impression转化调用方移除 site

      2. 如果 impression转化调用方为空, 则从展示存储移除 impression继续

此过程不会移除那些 使用空集合转化站点保存的展示。

4.1.4. 站点名称

展示存储 会保存关于三类站点的信息: 展示站点、 一个可选的中介方站点, 以及一组集合,其元素为转化站点

这些站点必须全部 采用scheme-and-host 形式, 并使用 "https" 方案。 这意味着,对主机 进行简单字符串序列化就足以标识该站点。 因此,此 API 能够使用简单的字符串 来表示站点

实现也可以只使用元组的主机部分 在内部表示站点。

解析站点, 返回站点或失败, 给定一个字符串 input, 运行以下步骤:
  1. host 为调用主机解析器并传入 input 所返回的值。

  2. 如果 host 为失败,则返回失败。

  3. site 为调用获取可注册域并传入 host 所返回的值。

  4. 如果 site 为 null,则返回失败。

  5. 如果 site 为 "localhost",或者如果 site ".localhost" 结尾, 则返回失败。

  6. 返回一个 ("https", site) 的方案和主机元组。

对于所含域标签数量多于可注册域的字符串, 此算法也能成功生成一个站点。 例如,"extra.example.com" 会被解析为 "example.com"。

此算法不接受 localhost 域 [RFC6761], 因此,任何依赖提取站点名称的算法在提到 localhost 域时, 或者当前站点(顶级站点或被框架嵌入的站点)是 localhost 域时, 都会失败。 这会使使用本地服务器进行测试和开发变得困难。 实现可以提供一个禁用 localhost 检查的配置, 以帮助测试和开发。

4.2. 用于隐私预算管理的状态

用户 代理会维护若干状态, 这些状态用于管理隐私预算的消耗:

隐私预算 存储全局隐私预算存储展示站点配额存储扣减隐私和安全预算更新。

展示 存储一样, 隐私预算 存储和相关存储不使用存储键。 这些存储在如何清除信息方面有一些额外约束; 详见 § 9.7 清除 API 状态

归因预算锁定义为布尔标志的选择 是出于规范编写便利。 实现可能更适合使用替代构造。 实现可能能够对此值进行分区, 例如按纪元分区, 以减小任何争用的范围。

4.2.1. 隐私预算存储

隐私预算键 是一个元组, 由以下项目组成:

epoch index

一个纪元索引

site

一个站点

隐私预算 存储是一个映射,其键为 隐私预算键, 其值为32 位无符号整数。 这些整数微 epsilon为单位存储值。 一个微 epsilon是 差分隐私 [DP] 中使用的单位 epsilon 值的 百万分之一。

选择 32 位整数会将 epsilon 的设置限制为 小于或等于 4294 的最大 epsilon。 对实现来说,这应该绰绰有余。

全局 隐私预算存储是一个映射,其键为 纪元索引,其值为 以微 epsilon为单位的 32 位无符号整数

全局隐私预算存储跟踪单一 隐私预算的消耗, 该预算适用于所有站点, 并在每个纪元刷新。 这提供了一个安全限制, 用于抵御能够跨多个站点 关联同一个人活动的对手。

不同于按站点划分的隐私预算存储全局隐私预算存储只以纪元索引为键, 而不是以站点为键。

展示 站点配额存储是一个映射,其键为 隐私预算键, 其值为以微 epsilon为单位的 32 位无符号整数

展示站点配额存储限制任何单个展示 站点在一个纪元中能够贡献的“存量” (与展示相关的隐私预算)。 这可防止单个展示站点 从可能被恶意触发的全局限制中 消耗过多额度。

要在给定 隐私预算 键 key集合,其元素为 展示 impressionsdouble epsilon、 整数 value、 整数 maxValue、 布尔值 isSingleEpoch、 整数 l1Norm集合,其元素为 隐私预算键 deductedImpressionQuotas 以及 集合,其元素为 时期索引 deductedGlobalBudgets 时,扣减 隐私和安全预算
  1. 如果 isSingleEpoch,则令 l1NormSensitivityl1Norm,否则为 2 * value

  2. valueSensitivity 为 2 * value

  3. noiseScale 为 2 * maxValue / epsilon

  4. l1NormDeductionFpl1NormSensitivity / noiseScale

  5. valueDeductionFpvalueSensitivity / noiseScale

    单时期归因 不会跨时期造成任何级联效应。 涉及多个时期的归因会消耗两倍预算, 因为一次变更可能会影响跨时期的归因。 将扣减量加倍是假定已向聚合直方图中添加 与 maxValue / epsilon 成比例的拉普拉斯噪声。

  6. l1NormDeductionl1NormDeductionFp * 1000000,并朝正 Infinity 舍入。

  7. valueDeductionvalueDeductionFp * 1000000,并朝正 Infinity 舍入。

  8. 如果 归因预算锁 为 true, 等待直到该值变为 false, 然后将该值设为 true。

  9. 如果 isSingleEpoch 为 true,则令 deductionl1NormDeduction,否则为 valueDeduction

  10. 如果用 keydeductionvalueDeductionimpressions 调用检查可用隐私预算的结果 为 false,则执行以下步骤:

    1. 归因预算锁 设为 false。

    2. 返回 false。

  11. 所有预算检查均已通过,因此执行扣减:

    1. currentValue 为在 隐私预算存储获取 key 的值所得的结果,默认值为每站点隐私预算

    2. 隐私预算存储中,将 key 的值设置currentValuededuction

    3. epochkey时期索引组件。

    4. 如果 deductedGlobalBudgets包含 epoch, 则将 epoch 追加deductedGlobalBudgets, 并将全局隐私预算 存储[epoch] 减少 valueDeduction

    5. impressions 中的每个 impression

      1. impressionSiteimpression展示站点

      2. impressionQuotaKey 为一个隐私预算 键, 其条目为 epochimpressionSite

        以下步骤确保当同一站点有多个展示时, 不会从同一展示站点配额中 多次扣减预算。

      3. 如果 deductedImpressionQuotas包含 impressionQuotaKey

        1. impressionQuotaKey 追加deductedImpressionQuotas

        2. currentImpressionQuotaValue 为在每时期展示站点配额获取 impressionQuotaKey 的值所得的结果, 默认值为每时期展示站点配额

        3. 每时期展示站点配额[impressionQuotaKey\] 的值设置currentImpressionQuotaValuevalueDeduction

  12. 归因预算锁 设为 false。

  13. 返回 true。

要在给定 隐私预算 键 key、整数 deduction、 整数 valueDeduction 以及 集合,其元素为 展示 impressions 时,检查 可用隐私预算
  1. currentValue 设为从 隐私预算存储 获取 key 的值, 默认值为每站点隐私预算

  2. 如果 deduction 大于 currentValue,则返回 false。

  3. epochkey时期索引组件。

  4. currentGlobalValue 设为从全局隐私预算存储 获取 epoch 的值, 默认值为每时期全局隐私预算

  5. 如果 valueDeduction 大于 currentGlobalValue,则返回 false。

  6. impressions 中的每个 impression

    1. impressionSiteimpression展示站点

    2. impressionQuotaKey 为一个隐私预算键, 其条目为 epochimpressionSite

    3. currentImpressionQuotaValue 设为从展示站点配额存储获取 impressionQuotaKey 的值,默认值为 每时期展示站点配额

    4. 如果 valueDeduction 大于 currentImpressionQuotaValue, 则返回 false。

  7. 返回 true。

4.2.2. Attribution API 激活

Attribution API 大致以消耗瞬态激活的 API 为模型, 在这些 API 中,用户激活 会暂时使 API 可用。 有若干差异将此设计 与消耗瞬态激活的 API 区分开来:

这在效果上大体类似于瞬态激活。 但是,归因激活使用与瞬态激活 分离的状态, 并且该状态以不同方式跟踪。 归因激活状态在顶级可遍历对象上跟踪, 而不是在受影响的 Window 上跟踪。 因此,归因激活会在导航之间持续存在, 从而在激活导致导航的情况下, 能够在加载新页面后的一小段时间内 使用此 API。

拥有独立状态可确保 归因激活不会与消耗瞬态激活的 API 发生交互。 一个消耗激活的 API 不会阻止 Attribution API 可用; 同样,使用 Attribution API 也不会阻止 一个消耗瞬态激活的 API 可用。

独立的状态跟踪可确保 那些消耗用户激活的用户动作 能够由 Attribution API 独立测量。

在导航之间保留激活支持广告中的常见模式。 站点可以使用 Attribution API 检查 交互发生所在站点上的动作, 或后续站点上的动作。

为实现这一点, 每个顶级 可遍历对象都会为 Attribution API 跟踪两项状态:

  1. 归因启用标志是一个布尔值, 用于跟踪此 API 是否已启用。 此值初始化为 false。

  2. 归因激活时间戳是一个时刻, 用于跟踪上一次用户激活。 此值初始化为 Unix 纪元

实现还会将归因激活持续时间 配置为一个实现定义的持续时间。 这不应小于瞬态激活持续时间, 但为了确保导航造成的延迟 不会使 Attribution API 变得不可访问, 更大的值可能是可取的。

实现可以选择延长允许的时间, 以考虑导航期间加载页面内容所涉及的延迟。 固定值可能无法考虑设备或网络中的性能差异。 实现可以基于对性能特征的理解, 延长 归因激活持续时间的值。 或者,实现也可以在页面加载期间暂停任何计时器。

当用户交互导致在 Document document 中触发激活触发输入事件时, 用户代理必须执行以下步骤——除激活通知步骤之外——并且要在分派该事件之前执行。 在这种情况下,将可导航对象 navigable 设置为 null。

或者,当导航开始, 且用户导航参与"browser UI" 时, 执行以下步骤, 将 navigable 设置为受影响的可导航对象, 并将 document 设置为 null。

步骤为:

  1. 如果 navigable 不为 null,则令 nnavigable

  2. 否则,令 n 为获取 document节点可导航对象的结果。

  3. top 为获取 n顶级 可遍历对象的结果。

  4. top归因激活时间戳 设置为当前高分辨率时间

当一个顶级 可遍历对象 top导航时, 作为导航算法的一部分, 在文档状态 documentState 已确定, 并且响应 responseOrigin 已知之后, 执行以下步骤:
  1. 如果 documentState发起者源responseOrigin同站,则返回。

  2. top归因启用标志设置为 false。

检查 Attribution API 激活, 给定一个 Document document, 并在失败时抛出 "NotAllowedError" DOMException
  1. n 为获取 document节点可导航对象的结果。

  2. top 为获取 n顶级 可遍历对象的结果。

  3. 如果 top归因启用标志为 true,则返回。

  4. lastActivationtop归因激活时间戳

  5. 如果 lastActivation 加上归因激活持续时间 小于当前高分辨率时间, 则抛出一个 "NotAllowedError" DOMException

  6. 归因激活时间戳设置为 unix epoch

  7. top归因启用标志设置为 true。

4.2.3. 纪元开始时间

隐私预算周期(或周期) 标识一段时间。 一个周期的长度固定为一周或 7 , 其中定义为 86400 秒。

周期开始时间 是来自挂钟的一个时刻。 对于每个用户代理,一个周期会在一周中随机选择的某个小时开始。 这确保了因隐私 预算达到零而在聚合中产生的任何偏差, 会在所有用户的所有贡献中被平均化。

在同一设备上, 所有隐私预算和配额 都会根据周期开始时间在同一时间刷新。

开始时间 由用户代理在首次需要周期时随机选择——作为调用 获取当前 周期算法的副作用。

周期索引是一个整数, 指代给定的周期周期索引用于访问 impression周期开始时间

正如一个时刻是一个抽象概念, 只能表示为相对于另一个时刻持续时间周期也是 抽象的。

周期索引作为 相对于某个设定参考点的整数 存储。 本规范中的周期索引 使用周期开始 时间 作为参考点。 用户代理可以选择使用不同的时刻 来表示“零”或参考周期

本规范中的算法全都使用具体的周期索引, 而不是更抽象的周期时间 点会使用获取当前 周期算法, 被转换为对应周期周期索引

要在给定一个时刻 t 的情况下获取当前 周期, 返回一个周期索引
  1. period 为一个周期持续时间

  2. 如果周期 开始时间未设置, 则按如下方式将其设置为在上一个周期内随机选择的一个小时:

    1. randt 减去一个持续时间, 该持续时间从 0(包含)到 period(不包含)之间 随机选择。

    2. ms 为从 Unix 纪元rand持续时间中的毫秒数。

    3. hourms 除以 3600000 (一小时的毫秒数) 向零舍入 然后乘以 3600000。

    4. 周期开始时间设置为 Unix 纪元 加上作为持续时间hour

  3. start周期开始时间

  4. elapsed 为 (tstart) / period

  5. elapsed 作为整数返回,并向负无穷舍入。

4.2.4. 上次清除浏览历史记录的时间

上次浏览 历史清除是一个使用挂钟时刻, 用于跟踪浏览历史最后一次被清除的时间。 当任何站点级状态 应用户请求被清除时, 上次浏览历史清除值会被更新 为当前粗化挂钟时间。 该值初始为未设置。

作为可选优化, 如果以下所有条件都为 true,则可以跳过更新上次浏览历史清除

如果这三个条件都为 true, 则不需要更新上次浏览历史清除。 相反,必须更新隐私 预算存储, 方法是为可以从每个受影响的站点周期 形成的所有隐私预算 键组合设置值 0 (使用对应的周期索引)。

此优化依赖于用户代理 已保留关于受影响站点 在受影响周期中交互的信息。 这之所以可行,只是因为任何被保留的交互 都可能已经导致预算耗尽。 重置预算是必要的, 以确保不会暴露关于浏览历史空缺的信息。

要在给定时刻 now 的情况下获取归因的起始周期, 返回一个周期索引
  1. earliestEpochIndex 为用 now最大回溯天数获取当前周期的结果。

    这确保可以查询所有可能的展示

  2. startEpochearliestEpochIndex

  3. 如果上次浏览历史清除已设置, 则执行以下步骤:

    1. clearEpoch 为用上次浏览历史清除的值获取当前 周期的结果。

      这里使用获取当前周期 可能会返回负值。 这是因为周期开始时间 很可能会被设置为浏览历史最后一次清除之后的时间。

    2. clearEpoch 设置为 clearEpoch + 1。

      加上是必要的,这样归因的周期范围 就不会与浏览历史被清除之前的周期 重叠。

    3. 如果 clearEpoch 大于 startEpoch, 则返回 clearEpoch

  4. 返回 startEpoch

清除归因的浏览历史, 给定一个由站点 sites 组成的集合, 一个布尔值 forgetVisits, 以及一个时刻 now
  1. 如果 forgetVisits 为 false:

    1. 断言sites 不是 空的

    2. sites 中的每个 site

      1. startingEpoch 为 在给定 now 的情况下调用获取归因的起始周期 的结果。

      2. currentEpoch 为 在给定 now 的情况下调用获取当前周期 的结果。

      3. 对从 startingEpochcurrentEpoch闭区间范围 中的每个 epoch

        1. key 为由 siteepoch 形成的隐私 预算键

        2. 隐私预算 存储[key] 设置为 0。

    3. 返回。

  2. 如果 sites 为空

    1. 清空展示存储

    2. 清空隐私预算 存储

    3. 清空展示站点配额存储

    4. 清空全局 隐私预算存储

  3. 如果 sites 不是空的

    1. 展示存储中的 每个 impression, 如果 sites 包含 impression展示站点, 则从展示存储移除 impression

    2. 隐私预算存储 中的每个 key, 如果 sites 包含 key站点组成部分, 则移除隐私预算 存储[key]。

    3. 展示站点配额存储 中的每个 key, 如果 sites 包含 key站点组成部分, 则移除展示站点配额 存储[key]。

      此过程不会触碰全局 隐私预算存储。 这主要是为了确保隐私预算 一旦被花费,就不会被遗忘。

  4. 上次浏览历史清除设置为 now

    在仅清除某些站点的状态时 (即,当 sites 不是 空的时) 设置上次浏览历史清除 会使不在该集合中的站点无法访问某些展示。 实现也可以移除任何不可用的展示 以及任何因此无法使用的预算记录 (例如全局隐私预算存储中的记录)。

4.3. 保存展示算法

saveImpression(options) 方法步骤 如下:
  1. implicitInputs 为从 this 获取 隐式 API 输入的结果。

  2. 断言implicitInputs 不为 null。

  3. 返回使用 optionsimplicitInputs 运行保存展示的结果。

要在给定 AttributionImpressionOptions options隐式 API 输入 implicitInputs 的情况下保存一个 展示
  1. documentimplicitInputs关联文档

  2. realmdocument相关领域

  3. 如果 document被允许使用名为 "save-impression" 的策略控制特性, 则返回在 realm 一个 "NotAllowedError" DOMException 拒绝的 promise。

  4. 在给定 document 的情况下检查 Attribution API 激活, 对任何抛出的原因返回以其拒绝的 promise

  5. 验证页面提供的 API 输入:

    1. 如果 options.histogramIndex 大于或等于实现定义最大直方图大小, 则返回在 realm一个 RangeError 拒绝的 promise。

    2. 如果 options.lifetimeDays 为 0, 则返回在 realm一个 RangeError 拒绝的 promise。

    3. options.lifetimeDays 钳制到 最大回溯

    4. 如果 options.conversionSites大小 大于实现定义每个展示的最大 转化站点数, 则返回在 realm一个 RangeError 拒绝的 promise。

    5. conversionSites 为一个集合,它是 对 options.conversionSites 中的每个值 调用解析 站点 的结果。

    6. 如果 conversionSites 中有任何结果为失败,则返回在 realm一个 "SyntaxError" DOMException 拒绝的 promise。

    7. 如果 options.conversionCallers大小 大于实现定义每个展示的最大 转化调用方数, 则返回在 realm一个 RangeError 拒绝的 promise。

    8. conversionCallers 为一个集合,它是 对 options.conversionCallers 中的每个值 调用解析站点 的结果。

    9. 如果 conversionCallers 中有任何结果为失败,则返回在 realm一个 "SyntaxError" DOMException 拒绝的 promise。

  6. 并行运行以下步骤:

    1. impression 构造为一个已保存的展示,由以下内容组成:

      匹配值

      options.matchValue

      展示站点

      implicitInputs顶级站点

      中介站点

      implicitInputs中介站点

      转化站点

      conversionSites

      转化调用方

      conversionCallers

      时间戳

      implicitInputs时间戳

      生命周期

      options.lifetimeDays

      直方图索引

      options.histogramIndex

      优先级

      options.priority

    2. 如果 Attribution API 已启用, 则将 impression 保存到展示存储

  7. result 为一个新的 AttributionImpressionResult

  8. 返回在 realm result 兑现的 promise。

saveImpression() 不返回指示该展示是否被记录的状态。 这会最大限度地降低检测 Attribution API 是否已禁用的能力。

实现必须尝试缓解可能暴露 API 状态的侧信道。 例如,返回的 promise 的兑现 不以将 impression 保存到展示存储为前提,以确保 兑现所需时间不依赖于 现有展示的数量或 API 是否已启用。

隐式 API 输入是一个具有以下字段的结构体

顶级站点一个站点
中介站点一个站点undefined
时间戳一个时刻
关联文档一个 Document
要在给定 领域 realm 以及 可选的(默认为 null)的情况下,从 realm 获取 隐式 API 输入
  1. windowrealm全局对象

  2. 如果 window 不是一个 Window, 则返回 null。

  3. settingsrealm设置对象

  4. timestampsettings当前挂钟时间

  5. topLevelOriginsettings顶级源

  6. 如果 origin 为 null,则将 origin 设置为 settings

  7. topLevelSite 为从 topLevelOrigin 获取 站点的结果。

  8. intermediarySite 为:

    1. 如果 origintopLevelOrigin 同站, 则为 undefined 值,

    2. 否则,为从 origin 获取站点的结果。

  9. 返回一个具有以下字段的隐式 API 输入

    顶级站点

    topLevelSite

    中介站点

    intermediarySite

    时间戳

    timestamp

    关联文档

    window关联文档

4.4. 衡量转化算法

measureConversion() 方法异步完成, 在 Attribution 任务源上排队工作。

measureConversion(options) 方法 步骤为:
  1. implicitInputs 为从 this 获取隐式 API 输入的结果。

  2. 断言implicitInputs 不为 null。

  3. 返回用 optionsimplicitInputs 运行测量一次转化的结果。

要在给定 AttributionConversionOptions options隐式 API 输入 implicitInputs 的情况下测量一次 转化
  1. documentimplicitInputs关联文档

  2. realmdocument相关领域

  3. 如果 document被允许使用名为 "measure-conversion" 的策略控制特性, 则返回在 realm 一个 "NotAllowedError" DOMException 拒绝的 promise。

  4. 检查归因 API 激活 给定 document,返回 一个被拒绝的 promise,其拒绝原因是 任何抛出的原因。

  5. validatedOptions验证 options 的结果, 对任何抛出的原因返回以其拒绝的 promise

  6. promiserealm一个新的 promise

  7. 并行运行以下步骤:

    1. report 为用 validatedOptions直方图大小调用创建一个全零直方图的结果。

    2. 如果 Attribution API 已启用, 则将 report 设置为用 validatedOptionsimplicitInputs顶级站点implicitInputs中介站点以及 implicitInputs时间戳 运行执行归因并填充 直方图的结果。

    3. aggregationServicevalidatedOptions聚合 服务

    4. 切换 aggregationService.protocol 的值:

      dap-18-histogram

      执行以下步骤:

      1. encryptedReport 为调用构造 DAP 报告并给定 validatedOptionsimplicitInputs顶级站点implicitInputs中介 站点implicitInputs时间戳,以及 report 所得的结果。

    5. result 为一个具有以下项的 AttributionConversionResult

      report

      encryptedReport

    6. Attribution 任务源排队一个任务, 以用 result 兑现 promise

  8. 返回 promise

实现必须尝试缓解可能暴露 API 状态的侧信道。 例如,理想情况下,返回的 promise 的兑现所需时间 不应依赖于已存储或匹配的展示数量 或 API 是否已启用。

已验证的 转化选项是一个具有以下字段的结构体

聚合 服务一个 AttributionAggregationService 实例。
Epsilon一个有限正数。
直方图大小一个32 位无符号整数
回溯一个正持续时间
匹配值一个由32 位无符号整数组成的集合
展示站点一个由站点组成的集合
展示 调用方一个由站点组成的集合
权重一个由数字组成的列表
一个32 位无符号整数
最大值一个32 位无符号整数
验证 AttributionConversionOptions options
  1. 如果 aggregationServices包含 一个条目,其options.aggregationService, 则抛出 ReferenceError

  2. aggregationService 为从 AttributionAggregationServices 获取值的结果, 给定 options.aggregationService

  3. 如果 options.epsilon 小于或等于 0,或者大于最大 epsilon, 则抛出 RangeError

  4. 如果 options.histogramSize 为 0,或者大于实现定义最大直方图 大小, 或者大于 options.aggregationService最大聚合服务 直方图大小(如果有), 则抛出 RangeError

  5. 如果 options.value 为 0, 则抛出 RangeError

  6. 如果 options.value 大于 options.maxValue, 则抛出 RangeError

  7. 如果 options.credit 存在,则令 credit 为它,否则为 «1»。

  8. 如果 credit 为空,则抛出 RangeError

  9. 如果 credit 的任何 不是有限的, 或者小于或等于 0, 则抛出一个 RangeError

  10. 如果 credit大小超过实现定义最大权重值数量,则抛出 RangeError

  11. 如果 options.lookbackDays 存在,则令 lookback 为其天数, 否则为最大回溯天数

  12. 如果 lookback 大于最大值,则将 lookback 设置为最大回溯天数

  13. 如果 lookback 为 0 ,则抛出 RangeError

  14. 如果 options.matchValues大小 大于实现定义最大 匹配值数量, 则抛出 RangeError

  15. matchValues 为用 options.matchValues 运行创建集合的结果。

  16. 如果 options.impressionSites大小大于 实现定义转化的最大展示 站点数, 则抛出 RangeError

  17. impressionSites 为一个集合,它是 对 options.impressionSites 中的每个值 调用解析 站点 的结果。

  18. 如果 impressionSites 中有任何结果为失败,则抛出一个 "SyntaxError" DOMException

  19. 如果 options.impressionCallers大小大于 实现定义转化的最大 展示调用方数, 则抛出 RangeError

  20. impressionCallers 为一个集合,它是 对 options.impressionCallers 中的每个值 调用解析 站点 的结果。

  21. 如果 impressionCallers 中有任何结果为失败,则抛出一个 "SyntaxError" DOMException

  22. 返回一个具有以下字段的已验证转化选项

    聚合服务

    aggregationService

    Epsilon

    options.epsilon

    直方图大小

    options.histogramSize

    回溯

    lookback

    匹配值

    matchValues

    展示站点

    impressionSites

    展示调用方

    impressionCallers

    权重

    credit

    options.value

    最大值

    options.maxValue

4.4.1. 归因逻辑

归因逻辑 确定转化值如何分配到直方图桶。

要在给定 已验证转化选项 options站点 topLevelSite站点undefined intermediarySite,以及 时刻 now 的情况下执行 归因并填充直方图
  1. currentEpoch 为使用 now 调用获取当前纪元 的结果。

  2. startEpoch 为使用 now 调用获取归因的起始 纪元 的结果。

  3. earliestEpoch 为调用获取当前纪元的结果, 并传入 (nowoptions回溯)。

  4. 如果 currentEpoch 等于 earliestEpoch,则令 isSingleEpoch 为 true,否则为 false。

  5. l1Norm 为 0。

  6. 如果 isSingleEpoch 为 true:

    1. impressions 为使用 optionstopLevelSiteintermediarySitecurrentEpochnow 调用通用匹配 逻辑的结果。

    2. 如果 impressions 为 空,则返回使用 options直方图大小 调用创建全零直方图的结果。

    3. histogram 为使用 impressionsoptions直方图大小optionsoptions功劳 调用使用最后 N 次触达归因 填充直方图的结果。

    4. l1Norm 设置为 histogram的和。

    5. 断言l1Norm 小于或等于 options

  7. deductedImpressionQuotas 为一个新的集合

  8. deductedGlobalBudgets 为一个新的集合

  9. matchedImpressions 为一个集合

  10. 对于从 startEpochcurrentEpoch(包含两端)的每个 epoch

    1. impressions 为使用 optionstopLevelSiteintermediarySiteepochnow 调用通用匹配 逻辑的结果。

      在单纪元情况下,这会重新计算 matchedImpressions。 实现会希望避免重复执行这项工作。

    2. 如果 impressions 非 空

      1. key 为一个隐私预算键,其项目为 epochtopLevelSite

      2. budgetAndSafetyOk 为使用 keyimpressionsoptionsepsilonoptionsoptions最大值isSingleEpochl1NormdeductedImpressionQuotasdeductedGlobalBudgets 调用扣减隐私和安全 预算的结果。

      3. 如果 budgetAndSafetyOk 为 true, 则用 impressions 扩展 matchedImpressions

  11. 如果 matchedImpressions 为 空,则返回使用 options直方图大小 调用创建全零直方图的结果。

  12. histogram 为使用 matchedImpressionsoptions直方图大小optionsoptions功劳 调用使用最后 N 次触达归因 填充直方图的结果。

  13. 返回 histogram

创建 全零直方图,给定整数 size
  1. 返回一个列表,其大小size,其全为 0。

4.4.2. 通用展示匹配逻辑

要执行通用 匹配逻辑,给定 已验证转化选项 options站点 topLevelSite站点undefined intermediarySite周期索引 epoch,以及 时刻 now
  1. matching 为一个 集合

  2. 对于展示存储中的每个 impression执行以下操作

    1. impressionEpoch 为调用获取当前 纪元的结果, 并传入 impression时间戳

    2. 如果 impressionEpoch 不等于 epoch,则继续

    3. 如果 now 晚于 impression时间戳 加上 impression生命周期, 则继续

    4. 如果 now 晚于 impression时间戳加上 options回溯, 则继续

    5. 如果 impression转化站点非空, 且不包含 topLevelSite, 则继续

    6. 如果 intermediarySite 不是 undefined, 则令 conversionCallerintermediarySite, 否则为 topLevelSite

    7. 如果 impression转化调用方非空, 且不包含 conversionCaller, 则继续

    8. 如果 options匹配值非空, 且不包含 impression匹配值, 则继续

    9. 如果 options展示站点 非空,并且 不包含 impression展示站点, 则继续

    10. 如果 impression中介方站点 不是 undefined,则令 impressionCaller 为它, 否则为 impression展示站点

    11. 如果 options展示调用方 非空, 且不包含 impressionCaller, 则继续

    12. impression 追加matching

  3. 返回 matching

4.4.2.1. 最后 N 次触达归因
公平分配 功劳,给定一个 double 列表 credit 和整数 value
  1. 断言credit 非空

  2. sumCreditcredit之和。

  3. roundedCredit 为一个新的列表

  4. 对于 credit 的每个 item执行以下操作

    1. normalizedCreditvalue * item / sumCredit

    2. normalizedCredit 追加roundedCredit

  5. idx1 为 0。

  6. 对于 roundedCredit索引中移除第一个后的每个 n执行以下操作

    1. idx2n

    2. frac1roundedCredit[idx1] − floor(roundedCredit[idx1])。

    3. frac2roundedCredit[idx2] − floor(roundedCredit[idx2])。

    4. 如果 frac1frac2 都等于零,则继续

    5. 如果 frac1 + frac2 大于 1,则令 incr1 为 1 − frac1,并令 incr2 为 1 − frac2

    6. 否则,令 incr1 为 −frac1,并令 incr2 为 −frac2

      incr1 表示要增加 roundedCredit[idx1] 的量,以使其成为整数; incr2idx2 也类似。 注意,这些值可以为负。

    7. p1incr2 / (incr1 + incr2)。

      p1 的值表示 idx1 中的被舍入为整数的概率。 当 incr1 + incr2 为 0 时会发生除以零, 这只有在 frac1frac2 都为整数(要么都恰好为 0,要么都恰好为 1)时才可能。在这种情况下,idx2 不需要 舍入,因此我们直接跳过它。

    8. r 为 0 到 1(包含两端)之间的随机 double。

    9. 如果 r 小于 p1,则令 incrincr1, 并交换 idx1idx2 的值。

    10. 否则,令 incrincr2

    11. roundedCredit[idx2] 增加 incr

    12. roundedCredit[idx1] 减少 incr

  7. integerCredit 为将 roundedCredit每个通过舍入到最接近的整数 转换为整数的结果, 半值情况向远离零的方向舍入。

  8. 返回 integerCredit

    这个最终舍入步骤仅用于处理微小的浮点 加法和减法误差未能完全移除 roundedCredit[idx1] 的小数部分的情况。半值舍入模式 实际上永远不会发生,选择该模式是为了匹配 C++ std::round 行为,以便实现。

    该算法旨在:1)在各分配之间精确分配总计 value 的值; 2)保持 integerCredit 的期望值恰好等于 归一化功劳 (即 credit * value / sumCredit,其中 * 表示逐元素 相乘); 3)任何分配都不会产生大于 1 的误差。

使用最后 N 次触达 归因填充直方图,给定一个集合,其元素为 展示 matchedImpressions、整数 histogramSize、整数 value,以及 double 列表 credit
  1. 断言matchedImpressions 非 空

  2. sortedImpressionsmatchedImpressions,按 优先级排序,然后按时间戳降序排序

  3. Ncredit大小sortedImpressions大小 中的较小值。

  4. lastNImpressionssortedImpressions 的前 N 个条目。

  5. 移除 credit 中除前 N 个条目之外的所有条目。

  6. normalizedCredit 为使用 creditvalue 公平分配 功劳的结果。

  7. histogram 为使用 histogramSize 调用创建 全零直方图的结果。

  8. 对于 lastNImpressions索引中的每个 i执行以下操作

    1. impressionlastNImpressions[i]。

    2. valuenormalizedCredit[i]。

    3. indeximpression直方图索引

    4. 如果 index 小于 histogram大小, 则将 histogram[index] 增加 value

  9. 返回 histogram

4.5. 设置实现定义值

本规范标识了若干实现定义值。 本节包括一些给实现的建议, 关于如何最好地设置这些值。

实现会为 lifetimeDayslookbackDays 设置一个实现定义最大回溯最大回溯是一个 正整数数。 为这些值设置不同最大值没有意义, 因为两个值中较小的那个 将决定哪些已保存的展示可用于转化。

实现必须最大回溯设置为至少 30 天。 在此期间内,实现应当尝试为每个展示站点保留 至少 1000 个展示。

在可能的情况下,实现应当在超出这些关于时间和数量的推荐限制后 继续保留展示。 可用于存储展示的容量同时取决于 保留展示数据所需的存储空间 以及生成转化报告所需的处理时间。 如果站点请求存储超出可用容量的展示、 如果用户请求这样做(见§ 9.2 禁用 Attribution API), 或出于实现定义原因, 实现可以在达到这些限制之前丢弃展示。

实现可能选择不保留展示的一个可能原因是, 该站点未获得足够的用户参与度。

对于传递给 saveImpression()measureConversion() 的站点列表,会选择一个实现定义值。 每个展示的最大转化站点数 是对 conversionSites 的值数量的限制; 实现必须将此值设置为至少 5。 每个展示的最大转化调用方数转化的最大展示调用方数 分别是对 conversionCallersimpressionCallers 的值数量的限制; 实现必须将这些值分别设置为至少 10。 转化的最大展示站点数 是对 impressionSites 的值数量的限制; 实现必须将此值设置为至少 30。

会为 最大 权重值数量选择一个实现定义值, 该值是对 credit 的值数量的限制; 实现必须将此值设置为至少 10。 会为 最大 匹配值数量选择一个实现定义值, 该值是对 matchValues 的值数量的限制; 实现必须将此值设置为至少 30。

measureConversion() 生成的直方图大小 同时受一个实现定义最大直方图大小最大聚合服务直方图大小约束。 没有为最大直方图大小设置最小值, 因为预期聚合技术的选择 将会设置一个限制。 最大聚合服务直方图大小 将是一个由聚合服务所使用技术的选择 决定的固定值; 它不是实现定义的。

4.5.1. 隐私和安全限制参数配置

用户 代理通过为以下内容定义值, 来配置隐私预算安全限制

安全限制配置为每站点预算的倍数, 会决定多个站点可以如何使用该 API。 在设置此倍数时, 实现需要考虑它们预期中 可能会使用其预算的站点数量, 也许还要向下调整, 以允许存在未完全使用其预算的站点。

安全限制设置为每站点预算的倍数, 可确保耗尽共享限制需要许多站点协作, 使其主要作为一种防止滥用的手段有用, 而不是作为主要的隐私机制。

5. HTTP API

5.1. 保存展示

`Save-Impression` 是一个 字典结构化标头, 设置在响应上,请求用户代理调用 saveImpression() API。

这是JavaScript saveImpression 示例的 HTTP 等价物:
Save-Impression: histogram-index=3, match-value=2, conversion-sites=("advertiser.example"), lifetime-days=7

定义了以下键,对应于传递给 saveImpression()AttributionImpressionOptions 字典的成员。被省略的 可选键的默认值会按与对应 AttributionImpressionOptions 字段相同的方式处理。未知字典键会被忽略, 未知参数也是如此。

conversion-sites
conversionSites 的值, 是一个包含字符串内部列表。 每个字符串值仅使用 A-label 包含一个域名; 因此,国际化 域名需要使用 punycode。 此键是可选的。
conversion-callers
conversionCallers 的值, 是一个包含字符串内部列表。 每个字符串值仅使用 A-label 包含一个域名; 因此,国际化 域名需要使用 punycode。 此键是可选的。
histogram-index
histogramIndex 的值, 是一个位于32 位无符号整数范围内的整数。此键是必需的。
priority
priority 的值, 是一个位于32 位有符号整数范围内的整数。此键是可选的。
match-value
matchValue 的值, 是一个位于32 位无符号整数范围内的整数。此键是可选的。
lifetime-days
lifetimeDays 的值, 是一个正整数。此键是可选的。
解析 Save-Impression 标头,给定一个标头值 input,运行以下步骤:
  1. dict 为使用 input_bytes 设置为 inputfield_type 设置为 "dictionary" 解析 结构化字段的结果。

  2. 如果解析失败,则返回错误。

  3. histogramIndexdict["histogram-index"] 带默认值 undefined

  4. 如果 histogramIndex 不是位于32 位无符号整数范围内的整数,则返回错误。

  5. opts 为一个新的 AttributionImpressionOptions, 其项目如下:

    histogramIndex

    histogramIndex

  6. 如果 dict["conversion-sites"] 存在

    1. conversionSites 为其

    2. 如果 conversionSites 不是内部 列表,或者 conversionSites 的任何 不是字符串, 则返回错误。

    3. opts.conversionSites 设置为 conversionSites

  7. 如果 dict["conversion-callers"] 存在

    1. conversionCallers 为其

    2. 如果 conversionCallers 不是内部 列表,或者 conversionCallers 的任何 不是字符串, 则返回错误。

    3. opts.conversionCallers 设置为 conversionCallers

  8. 如果 dict["match-value"] 存在

    1. matchValue 为其

    2. 如果 matchValue 不是位于 32 位无符号整数范围内的整数, 则返回错误。

    3. opts.matchValue 设置为 matchValue

  9. 如果 dict["lifetime-days"] 存在

    1. lifetimeDays 为其

    2. 如果 lifetimeDays 不是正整数, 则返回错误。

    3. opts.lifetimeDays 设置为 lifetimeDays

  10. 如果 dict["priority"] 存在

    1. priority 为其

    2. 如果 priority 不是位于 32 位有符号整数范围内的整数, 则返回错误。

    3. opts.priority 设置为 priority

  11. 返回 opts

5.2. 衡量转化

`Measure-Conversion` 是一个 字典结构化标头, 设置在响应上,请求用户代理调用 measureConversion() API。

这是JavaScript measureConversion 示例的 HTTP 等价物, 并额外带有一个 report-url,生成的报告将被 POST 到该 URL:
Measure-Conversion: aggregation-service="https://aggregator.example/tee", histogram-size=20, epsilon=1.0, lookback-days=14, impression-sites=("publisher.example" "other.example"), impression-callers=("ad-tech.example"), match-values=(2), credit=(0.25 0.25 0.5), value=3, max-value=7, report-url="https://report-handler.example/foo"

定义了以下键,对应于传递给 measureConversion()AttributionConversionOptions 字典的成员。被省略的 可选键的默认值会按与对应 AttributionConversionOptions 字段相同的方式处理。未知字典键会被忽略, 未知参数也是如此。

aggregation-service
aggregationService 的值, 是一个字符串。此键是必需的。
epsilon
epsilon 的值, 是一个正小数整数。此键是 可选的。
histogram-size
histogramSize 的值, 是一个正整数。此键是必需的。
lookback-days
lookbackDays 的值, 是一个正整数。此键是可选的。
match-values
matchValues 的值, 是一个包含非负整数内部列表。 此键是可选的。
impression-sites
impressionSites 的值, 是一个包含字符串内部列表。 每个字符串值仅使用 A-label 包含一个域名; 因此,国际化 域名需要使用 punycode。 此键是可选的。
impression-callers
impressionCallers 的值, 是一个包含字符串内部列表。 每个字符串值仅使用 A-label 包含一个域名; 因此,国际化 域名需要使用 punycode。 此键是可选的。
credit
credit 的值, 是一个包含正小数 或正整数内部列表。此键是可选的。
value
value 的值, 是一个正整数。此键是可选的。
max-value
maxValue 的值, 是一个正整数。此键是可选的。
report-url
一个字符串, 其中包含生成的报告(如果有)将被 POST 到的潜在可信 URL。 该 URL 可以相对于响应 URL。其方案 必须是 "https"。 此键是必需的。
解析 Measure-Conversion 标头,给定一个标头值 input 和一个URL baseUrl,运行以下步骤:
  1. dict 为使用 input_bytes 设置为 inputfield_type 设置为 "dictionary" 解析 结构化字段的结果。

  2. 如果解析失败,则返回错误。

  3. aggregationServicedict["aggregation-service"] 带默认值 undefined

  4. 如果 aggregationService 不是字符串,则返回 错误。

  5. histogramSizedict["histogram-size"] 带默认值 undefined

  6. 如果 histogramSize 不是位于32 位无符号整数范围内的正整数,则返回错误。

  7. reportUrlStringdict["report-url"] 带默认值 undefined

  8. 如果 reportUrlString 不是字符串,则返回 错误。

  9. reportUrl 为使用 baseUrlURL 解析器应用于 reportUrlString 的结果。

  10. 如果 reportUrl 为失败,则返回错误。

  11. 如果 reportUrl 不是潜在可信 URL,则返回错误。

  12. 如果 reportUrl方案不是 "https",则返回错误。

  13. opts 为一个新的 AttributionConversionOptions, 其项目如下:

    aggregationService

    aggregationService

    histogramSize

    histogramSize

  14. 如果 dict["epsilon"] 存在

    1. epsilon 为其

    2. 如果 epsilon 不是小数整数,则返回错误。

    3. opts.epsilon 设置为 epsilon

  15. 如果 dict["lookback-days"] 存在

    1. lookbackDays 为其

    2. 如果 lookbackDays 不是正整数, 则返回错误。

    3. opts.lookbackDays 设置为 lookbackDays

  16. 如果 dict["match-values"] 存在

    1. matchValues 为其

    2. 如果 matchValues 不是内部 列表,或者 matchValues 的任何 不是位于 32 位无符号整数范围内的整数,则返回 错误。

    3. opts.matchValues 设置为 matchValues

  17. 如果 dict["impression-sites"] 存在

    1. impressionSites 为其

    2. 如果 impressionSites 不是内部 列表,或者 impressionSites 的任何 不是字符串, 则返回错误。

    3. opts.impressionSites 设置为 impressionSites

  18. 如果 dict["impression-callers"] 存在

    1. impressionCallers 为其

    2. 如果 impressionCallers 不是内部 列表,或者 impressionCallers 的任何 不是字符串, 则返回错误。

    3. opts.impressionCallers 设置为 impressionCallers

  19. 如果 dict["credit"] 存在

    1. credit 为其

    2. 如果 credit 不是内部 列表,或者 credit 的任何 不是小数整数,则返回错误。

    3. opts.credit 设置为 credit

  20. 如果 dict["value"] 存在

    1. value 为其

    2. 如果 value 不是位于 32 位无符号整数范围内的正整数, 则返回错误。

    3. opts.value 设置为 value

  21. 如果 dict["max-value"] 存在

    1. maxValue 为其

    2. 如果 maxValue 不是位于 32 位无符号整数范围内的正整数, 则返回错误。

    3. opts.maxValue 设置为 maxValue

  22. 返回 (opts, reportUrl)。

发送报告,给定一个 字节 序列 report、 一个 URL url,以及一个环境设置对象 settings
  1. 断言url 是一个潜在可信 URL

  2. 断言url方案为 "https"。

  3. headers 为一个新的标头列表,其中包含一个名为 "Content-Type"、值为 "application/dap-report" 的标头

    注:如果 AttributionAggregationProtocol 将来获得除 dap-18-histogram 之外的值,则这里需要更新。

  4. request 为一个具有以下属性的新请求

    方法

    "POST"

    URL

    url

    标头列表

    headers

    主体

    report

    客户端

    settings

    模式

    "cors"

    缓存模式

    "no-store"

    keepalive

    true

    凭据模式

    "omit"

    引用来源

    url

  5. 获取 request,并可在发生错误时重试。

5.3. Fetch 猴子补丁

处理 Attribution 标头,给定一个请求 request响应 response,运行以下步骤:
  1. 如果 request目标不是以下之一, 则返回:"""audio""image""script""track""video"

  2. 如果 request客户端不是安全上下文,则返回。

  3. 如果 responseURL 不是潜在可信 URL,则返回。

  4. 如果 responseURL方案不是 "https",则返回。

  5. implicitInputs 为从 request客户端 获取隐式 API 输入的结果, 并使用 responseURL

  6. 如果 implicitInputs 为 null,则返回。

  7. saveImpressionHeader 为从 response标头列表获取 `Save-Impression` 的结果。

  8. 如果 saveImpressionHeader 不是 null:

    1. impressionOptions解析 saveImpressionHeader 的结果。

    2. 如果 impressionOptions 不是错误,则用 implicitInputs 保存 impressionOptions

  9. measureConversionHeader 为从 response标头列表获取 `Measure-Conversion` 的结果。

  10. 如果 measureConversionHeader 不是 null:

    1. parseConversionResult解析 measureConversionHeader 的结果。

    2. 如果 parseConversionResult 不是错误:

      1. 令 (conversionOptions, reportUrl) 为 parseConversionResult

      2. reportPromise 为使用 conversionOptionsimplicitInputs 运行衡量 转化的结果。

      3. 并行

        1. reportPromise 兑现时,令 result 为兑现值。

        2. 使用 result.reportreportUrlrequest客户端 发送报告

按如下方式修改 HTTP-network fetch

在步骤

如果 includeCredentials 为 true,则用户代理应该在给定 requestresponse 的情况下解析并存储响应 Set-Cookie 标头。

之后添加以下步骤

  1. 使用 requestresponse 处理 Attribution 标头

6. 聚合

聚合 服务接收多份归因信息, 并生成一个聚合指标。

用户代理实现对于聚合会有不同的要求。 但是,聚合过程具有一些共同要素。

首先,用户代理将需要被配置, 或以其他方式获得, 关于聚合服务的信息。 这包括所支持的聚合方法 以及任何所需的配置。

每种聚合方法都需要定义 直方图如何:

聚合方法还需要定义 站点如何获得聚合结果。

6.1. 多方计算聚合

多方计算 (MPC) 系统是指 涉及多个独立实体, 它们协同计算一个约定函数的系统。

本规范使用基于 Prio [PRIO]Distributed Aggregation Protocol(DAP) [DAP] 的 MPC 系统。 这是一个两方 MPC 系统,其特征在于 依赖客户端提供的输入正确性证明。 这允许非常高效的 MPC 操作, 代价只是提交到系统的数据大小适度增加。

使用 MPC 的聚合服务 由两个或更多独立服务组成, 它们协作计算预定义函数。

MPC 提供的基本保证是: 只会向任何实体揭示函数的已定义输出, 以及明确定义的泄露。

MPC 保证仅在 参与实体的某个子集是诚实的范围内成立。 对于 Prio 中使用的两方 MPC, 只要任一 MPC 操作者保持诚实, 隐私——即输入的机密性——就会得到维护。 这种 MPC 配置不防止 任一 MPC 操作者 破坏输出。

6.1.1. Prio 和 DAP

dap-18-histogram 聚合方法使用 Prio [PRIO] 和 Distributed Aggregation Protocol(DAP)[DAP]。 具体来说,此聚合方法使用 Prio3L1BoundSum [PRIO-L1] 可验证分布式聚合函数(VDAF)[VDAF]

DAP 和 Prio3L1BoundSum 实例化定义了报告如何准备、 加密并提交以进行聚合。 DAP 还定义了如何获得聚合值, 以及用户代理需要获得 关于聚合服务的哪些配置。

在使用 Prio3L1BoundSum 时, 报告包含一个分布式零知识证明, 该证明允许参与 MPC 的节点 确认所提交直方图的和小于某个设定值。 Prio3L1BoundSum 只能 验证直方图的和 严格小于二的幂。 也就是说,证明确认 该和小于 2n,其中 n 为正整数值。

为了构造报告, 会基于一个值生成证明, 该值是大于 maxValue 的下一个二的幂。 这意味着 聚合服务无法拒绝 介于 maxValue 和下一个二的幂之间的报告。 因此,恶意的用户代理可能会生成一个报告, 其对聚合直方图的贡献 最多可达到 maxValue 值的两倍。 该证明确保当 maxValue 等于 2n − 1 时, 不存在超额贡献的机会; 任何此类攻击的相对影响都可以通过 将 maxValue 设置得尽可能接近 2n − 1 且受其他约束允许来降低。

6.1.2. DAP 扩展

对于此应用,需要 DAP 的扩展 [DAP-ATTRIBUTION]

用户代理使用这些扩展来构造 它们生成的报告。

6.1.3. 用于 DAP 的报告加密

构造 DAP 报告, 生成一个字节序列 report, 给定已验证的转化选项 options站点 topLevelSite站点undefined intermediarySite时刻 now, 以及由整数组成的列表 histogram
  1. lengthhistogram大小

  2. maxValueoptions.最大值

  3. chunkLength 为 (Math.ceil(log2(maxValue + 1)) + 1) * length 的平方根, 四舍五入到最接近的整数。

  4. vdaf 为新的 PrioL1BoundSum VDAF [PRIO-L1] 实例, 传入 lengthmaxValuechunkLength

  5. microEpsilonoptions.epsilon 乘以 1,000,000,然后向正无穷方向舍入。

  6. 如果 intermediarySite 不是 undefined, 则令 callerintermediarySite, 否则为 topLevelSite

  7. taskConfig 为对 TaskConfiguration 实例进行编码 所产生的字节 序列, 如 第 4.2 节[DAP] 中所定义,并具有 以下值:

    1. 空的 task_info

    2. leader_aggregator_endpoint 设置为 DAP Leader 的序列化 URL, 取自 options.Aggregation Service 中所选聚合服务实现定义的定义。 通过使用配置的 URL 和 false(用于排除片段)调用URL 序列化器 来产生编码后的值。

    3. helper_aggregator_endpoint 设置为 DAP Helper 的序列化 URL, 取自 options.Aggregation Service 中所选聚合服务实现定义的定义, 使用与 leader_aggregator_endpoint 值相同的过程产生。

    4. time_precision 值为 5。

    5. min_batch_size 值为 20。

    6. batch_mode 值为 TBD(参见 Distributed Aggregation Protocol (DAP) Extensions for the Attribution API § batch-mode)。

    7. 空的 batch_config

    8. vdaf_type 值为 7(参见 A Prio Instantiation for Vector Sums with an L1 Norm Bound on Contributions § dap)。

    9. vdaf_configuration 按照 PrioL1BoundSum A Prio Instantiation for Vector Sums with an L1 Norm Bound on Contributions § dap 编码, 并使用 lengthmaxValuechunkLength

    10. 一组任务扩展 extensions, 即从16 位无符号整数字节序列映射

  8. taskID字节 序列,该字节序列通过 Task Binding and In-Band Provisioning for DAP § task-id 中描述的过程产生, 并传入 taskConfig

  9. ctx 为通过拼接 字符串 dap-18编码值 和 taskID 而形成的字节 序列, 如 第 4.4.2.1 节[DAP] 中所定义。

  10. reportID 为从密码学安全随机源采样的 16 字节 [RFC4086]

  11. rand 为从密码学安全随机源采样的 128 字节 [RFC4086]

  12. publicShareinputShares 为调用 vdaf.shard() 的结果, 如 第 4.1 节[VDAF] 中所定义, 并使用 ctxhistogramreportID(作为 VDAF 的 "nonce" 参数) 和 rand

  13. time 为如下整数:将从 Unix 纪元now持续时间 除以 5 秒的持续时间所得的结果, 并向负无穷方向舍入。

  14. extensions 为从16 位无符号整数字节序列映射, 由以下内容组成:

    • 隐私 预算的扩展码点, 映射到 microEpsilon 的值, 该值通过使用 UINT32、 值 microEpsilonfalse(用于 isLittleEndian)调用 NumericToRawBytes 来编码。

  15. reportMetadata 为编码后的 DAP ReportMetadata, 它由 reportIDtimeextensions 生成。

  16. encryptedInputShares 为空的 列表

  17. inputShares每个 share, 遵循 第 4.4.2.1 节中描述的用于加密 share 的方法:

    1. pkR 为来自对应角色的公钥,该公钥来自为 options.Aggregation Service 所指示的聚合服务 获取的聚合服务 HPKE 配置

      "dap-18-histogram" 的 URL 预期用于标识 DAP Leader 角色。 实现需要静态地获取两个 Aggregator 的 HPKE 配置; 参见 § 9.4 未配置的浏览器。 HPKE 配置不得按需获取, 因为所花费的时间会向 measureConversion() 的调用者泄漏信息。

    2. serverRole 为一个字节,其值 对第一个条目(Leader)为 2, 对第二个条目(Helper)为 3。

    3. info 为通过拼接以下内容形成的字节 序列: 字符串 dap-18 input share编码值、 值为 0x01 的字节,以及 serverRole

    4. inputShareAADtaskIDreportMetadatapublicSharetaskConfig 按照 InputShareAad 的结构构造。

    5. plaintextShare 由 空集合(用于 private_extensions)和 share(用于 payload) 按照 PlaintextInputShare 的结构构造。

    6. hpke 为一个基于相同HPKE 配置的 HPKE [RFC9180] 实例。

    7. encryptedShare 为调用 hpke.Seal<mode_base>() 的结果, 传入 pkRinfoinputShareAADplaintextShare

    8. encryptedShare 追加encryptedInputShares

  18. report 为编码后的 DAP Report, 它由 reportMetadatapublicShareencryptedInputShares (这两个值分别为 leader 和 helper 加密输入 share), 以及从 DAP aggregators 获取的聚合服务 HPKE 配置 生成。

  19. 返回 report

此算法复现了 DAP 相关规范的一些细节。 如果本文档与那些规范之间存在差异, 则这是本文档中的非故意错误。 与 DAP 交互时始终遵循被引用的规范。

6.2. 抗重放要求

浏览器生成的转化报告 被绑定到请求该报告的站点 所支出的隐私 预算金额。

聚合 服务必须保证 它不会多次接受同一报告。

7. 差分隐私

此设计使用差分隐私的概念 作为其隐私设计的基础。 [PPA-DP]

差分隐私 是隐私的一种数学定义, 可以保证系统所揭示的 私有信息量。 [DP] 差分隐私不是此系统中 保护隐私的唯一手段, 但它是定义和分析最严格的一种。 因此,它提供最强的隐私保证。

差分隐私使用随机噪声 来隐藏对聚合数据集的 私有数据贡献。 噪声的作用是隐藏 对数据集的个体贡献, 同时保留任何聚合分析的有用性。

要应用差分隐私, 必须定义要保护哪些信息。 在此系统中,受保护的信息是 单个用户配置文件的展示, 位于单个用户代理上, 跨单个周期, 针对注册转化的单个网站。 § 7.1 隐私单元更详细地描述了此设计的含义。

此归因设计使用一种 称为个体差分隐私的差分隐私形式。 在此模型中,每个用户代理都分别负责 确保限制其贡献的 信息。

此 API 的个体差分隐私设计 有三个主要组成部分:

  1. 用户代理限制(使用隐私预算) 通过转化报告离开设备的 关于展示的信息量。 § 7.2 隐私预算对此进行了更深入的探讨。

  2. 聚合 服务确保任何给定的转化报告 仅按照用户代理 为其核算的隐私预算使用。 § 6.2 抗重放要求更详细地描述了对聚合 服务的要求。

  3. 噪声由聚合服务添加。 § 7.3 差分隐私机制详述了可能 使用的机制。

这些措施共同限制了 为每个隐私单元释放的信息。

7.1. 隐私单元

差分隐私的实现 需要清晰定义要保护的内容。 这称为隐私 单元, 它表示接收隐私保护的实体。

此系统采用的隐私单元 是三个值的组合:

  1. 一个用户代理配置文件。 也就是说,作为单个人使用的 用户代理实例。

  2. 请求关于展示的信息的站点转化站点)。

    注册展示的站点(展示站点) 不被考虑。 这些站点不会直接从此系统接收信息。

  3. 当前周期

这些值中的任何一个发生变化都会产生新的隐私单元, 从而产生单独的隐私预算。 一个人访问的每个站点 在每个周期中 都会收到有界数量的信息。

理想情况下,隐私单元是 单个人。 虽然这很理想,但由于多种原因, 无法开发一个有用的系统 来保证与某个人完全对应:

7.1.1. 隐私属性及其局限性的形式化分析

Attribution 中的隐私保护是多层的:

  1. 按站点预算限制任何单个转化站点可以了解用户多少信息。

  2. 全局预算提供后备限制,限制所有站点可以了解用户多少信息。

  3. 展示站点配额限制转化站点可以了解用户在任何单个 展示站点上的活动多少信息。

  4. 每次用户操作后维护的计数器限制有多少站点可以向 API 存储数据或从 API 学习信息。

本规范中的形式化隐私分析基于两篇论文。 第一篇 [PPA-DP] 建立了设备上个体 DP 核算的理论。 第二篇 [PPA-DP-2] 将分析扩展到 按站点预算和全局预算所提供的数学隐私保证。

按站点预算应被视为主要隐私保护。按站点预算应配置为 提供有意义的 DP 保证。 但是,[PPA-DP-2] 中的分析 确定了两个会限制这些保证的假设:

  1. 数据生成中没有跨站点自适应性。 站点的可查询数据流(展示 和转化)必须独立于来自其他站点的过去 DP 归因 结果生成。

  2. 没有通过跨站点共享限制发生泄露。 来自一个站点的查询不得影响向其他站点发出哪些报告。

简而言之,这两个假设在实践中都无法成立。

需要“没有跨站点自适应性”这一假设,是因为系统涉及多个站点, 它们可能会随时间与同一用户交互。 站点会基于彼此的 DP 测量来改变向用户展示的广告。例如,如果一个 广告主从归因 结果中了解到如何制作更好的广告,那么一些用户可能会在他们的站点上转化, 而不是在竞争对手的站点上转化。在这种情况下,一个站点学到的内容——只计入 其自身按站点预算——改变了其竞争对手可见的数据(或数据缺失),但 这并未计入这些竞争对手的按站点预算。

任何提供连续测量的系统都具有此属性,因此唯一的结论只能是接受 这一局限。这一局限也是设置全局 DP 预算和共享配额的理由之一, 它们引出了第二个假设。

当存在跨多个站点的共享限制时,需要“没有跨站点泄露”这一假设。 这种共享限制的一个例子是旨在提供全局 DP 保证的全局安全限制。 如果某些站点的 measureConversion() 请求导致 达到共享限制,则发送给其他站点的报告可能会被过滤。例如,知道自己有展示的站点 会了解到共享限制是否已达到的某些信息。尽管这些信息是聚合且有噪声的, 但它仍然是关于耗尽其预算的站点的信息,超出了该站点的按站点预算。

通过共享限制发生的泄露促使这些限制只作为限制滥用的手段来使用。将共享 限制设置为按站点预算的大倍数,会使得试图利用共享限制至少需要同样多的站点 进行协调。倍数越大,共享限制作为隐私保护手段就越不有用, 而更适合作为防止拒绝服务或类似形式滥用的手段。

相比之下,分析表明,全局预算可以在没有这些局限的情况下实现并提供可靠的 全局个体 DP 保证。但是,为了支持许多站点使用 API, 全局预算需要配置为按站点预算的一个显著倍数。这意味着 它提供的 DP 保证虽然不依赖任何假设,但单独而言无法提供有意义的 DP 保护。因此,按站点预算提供主要 DP 保证。全局预算可被视为 在恶意站点协同攻击时的后备。

全局 DP 预算还可以防护能够跨多个站点关联用户身份 以合并按站点预算的站点。按站点模型没有考虑这种可能性,尽管某些 站点通常具有这种能力。值得注意的是,这包括身份提供者、接收用户 标识符(如电子邮件地址或电话号码)的站点、成功使用导航跟踪 [NAV-TRACKING-MITIGATIONS] 的站点,以及因任何原因能够使用 跨站点 cookie 的站点 [WEB-WITHOUT-3P-COOKIES]。跨 多个站点使用 Attribution 可能给这些站点带来协调挑战,但站点可能具有 将活动关联到单个人的能力,这一点在对系统隐私进行整体分析时 不能忽视。

7.1.2. 浏览器实例

每个浏览器实例管理单独的隐私预算

浏览器实例之间的协调可能是可行的, 但并不预期如此。 这种协调可能通过减少释放的信息总量 来改进隐私。 它也可能通过允许一个浏览器实例上的展示 在另一个浏览器实例上转化 来改进归因的效用。

跨不同实现的协调 目前超出此工作的范围。 实现可以在已知属于同一个人的实例之间 执行一些协调, 但这不是强制性的。

7.1.3. 按站点限制

释放给网站的信息是基于站点进行的。 这与其他隐私相关功能中使用的同一边界一致。

更细的隐私单元,例如, 会使获取额外信息变得微不足道。 可以从多个源收集 关于同一个人的信息。 然后可以利用站点内信息的自由流动 将这些信息合并, 例如使用 cookie [COOKIES] 或类似机制。

§ 7.2.2 安全限制讨论了利用此限制的攻击, 以及用户代理可能实现的一些额外安全 限制 来防止这些攻击。

7.1.4. 隐私预算周期

站点接收单独的差分隐私预算, 用于查询在每个隐私 预算周期 (或周期)中 记录的展示

此预算适用于向用户代理 注册并随后被查询的展示, 而不是转化

从分析 [PPA-DP] 的角度来看, 每个周期展示形成单独的 数据库。 有限的隐私预算 会在对每个数据库进行的所有查询中强制执行。

从跨多个周期展示 生成转化 报告具有隐私后果。 对网站的一次访问可以向该站点提供 跨许多周期的活动信息。 这只要求 在整个期间转化站点 被标识为 展示的目标。 可查询的周期数量由用户代理限制。

目标是设置一个尽可能大的周期。 更长的时间段允许更好的隐私/效用平衡, 因为站点可以在任何时间点 被分配更大的总体预算, 同时保持总体隐私损失率较低。 但是,更长的间隔意味着 更容易完全耗尽隐私预算, 从而在下一次刷新前得不到任何信息。

周期时长设置为一周的决定在很大程度上是任意的。 预计一周足以让站点 在决定如何花费隐私预算时 具有一定灵活性, 而不需要仔细规划以考虑 未来几天或几周内可能发生的变化。

§ 7.2 隐私预算更详细地描述了预算过程。

7.2. 隐私预算

浏览器维护隐私 预算, 这是一种限制隐私损失量的手段。

本规范使用一种个体形式的 (ε, δ)-差分隐私作为其基础。 在此模型中,隐私损失使用值 ε 来度量。 δ 值由聚合服务 在向聚合结果添加噪声时处理。

每个用户代理实例负责 管理隐私预算。

每个被请求的转化报告 都指定一个 ε 值, 表示该报告消耗的隐私预算量, 以及转化报告中可返回值的最大值。

7.2.1. 隐私预算扣除

在为转化报告搜索展示时, 用户代理会从保存这些展示所在的隐私预算周期的预算中 扣除指定的 ε 值。 如果该周期隐私预算 不足, 则不会使用该周期中的展示。

每当转化 站点调用 measureConversion() 时, 会对归因 逻辑所选择的展示 所来自的周期 扣除隐私预算

在下图中, 来自多个不同站点的展示被记录下来, 以圆圈表示。
时间 `--. .--' `--. .--' `--. .--' `--. .--' ^ | | | | | 第 1 周 第 2 周 第 3 周 第 4 周 现在 ]]> 站点 A 站点 B 站点 C 站点 D 站点 E 时间 第 1 周 第 2 周 第 3 周 第 4 周 现在
随时间变化的展示存储示例

可能会在标记为“现在”的时间请求一个转化 报告。 该转化报告选择用黑色圆圈标记的展示, 对应于来自站点 B、C 和 E 的展示。

因此,转化站点隐私 预算 会从周期 1、3、4 和 5 中被扣除。 在周期 2 中没有记录展示, 因此不会从该周期扣除任何预算

用户 代理如何管理隐私预算的耗尽, 取决于所选择的归因 逻辑

7.2.2. 安全限制

基本隐私单元 容易受到能够在多个站点之间 关联同一个人活动的攻击者攻击。

站点组有时可以协调其活动, 例如当它们具有共同所有权或强协议时。 能够确定某个特定访问者是同一个人的站点组——使用任何手段,包括 类似 FedCM [FEDCM] 的机制——可以合并从此 API 获得的信息。

这可用于提高站点从归因中 获得信息的速率, 其比例取决于 发生协调的站点数量。 默认隐私单元对此方式释放的信息 不设置任何限制。

为抵消这种影响,用户代理可以实现安全限制, 即不考虑站点的额外隐私预算。 安全限制可能显著高于按站点预算, 因此在大多数正常浏览活动中不会达到。 目标是确保它们只对 高强度活动或遭受攻击时有效。

与按站点隐私预算一样, 至关重要的是,站点无法确定 其对转化报告的请求 是否导致安全限制被超过。

7.3. 差分隐私机制

差分隐私机制——即添加噪声的具体方法——可以由 聚合 服务选择。

预计添加拉普拉斯噪声会产生良好结果, 在噪声的总体幅度 与实现和分析的简单性之间取得平衡。 当前设计使用基于 L1 范数的 DP 敏感度, 它支持在聚合中添加拉普拉斯噪声。 支持其他噪声机制可能需要对 敏感度的计算和信号传递方式进行额外更改。

在中心位置添加噪声, 如这些聚合服务中任一项所定义, 确保噪声总量不会随着 报告总数的增加而增加。 与在报告生成点应用噪声的差分隐私设计 (即本地差分隐私模型) 相比,这提供了效用优势, 后者的噪声会按报告总数成比例增加。

8. 安全性考量

8.1. 展示存储

Attribution API 使用的展示存储 保存与浏览活动相关的信息, 并跨浏览会话持久存在。 尽管通过展示存储的信息流 受到严格控制, 它仍会跨源携带一定量的信息。

以下措施限制了 有害信息通过展示存储流动的可能性:

8.2. 实现中的侧信道风险

Attribution API 必须谨慎实现, 以维护所需的安全和隐私属性。 调用这些 API 的站点不能了解:

请注意,显式返回值或抛出的异常 并不是站点可以从 Attribution API 中了解信息的唯一方式。 可能可以从如下侧信道 推断敏感信息:

API 中函数执行时间的变化 是维护保证时的主要考量。 对执行时间而言,有两个特别令人担忧的因素:

全局隐私预算存储展示站点配额存储周期开始时间中的 共享全局状态 风险较小, 因为这些值从不直接影响算法运行时间。 实现仍需要确保任何全局状态 不会导致指纹识别 或其他信息泄露。

虽然完全消除所有侧信道并不现实, 实现必须作出合理努力以防止 Attribution API 泄露敏感信息。 防止泄露的策略包括:

8.3. 聚合服务

虽然聚合服务不是 Web 平台的一部分, 但其安全性对于 Attribution 机制的总体安全性 非常重要。 由 measureConversion() 生成的转化报告 使用聚合服务的密码密钥进行加密。 因此,披露这些报告中所含信息的 很大一部分潜在可能性 取决于聚合服务的细节。

用户 代理开发者在将聚合服务添加为 Attribution API 支持的服务之前, 应仔细考虑聚合服务的设计 以及聚合服务操作者的可信度。 关于这些问题的其他讨论 可见于 § 6 聚合§ 9 隐私 考量

8.4. 合并来自多个站点的报告

Attribution API 中的隐私机制 主要以站点粒度运行。 恶意操作者 可能尝试为多个站点 注册展示, 从而超过本应通过归因 释放的信息量。 § 7.2.2 安全限制讨论了建立额外跨站点 隐私预算以缓解这种可能性。

8.5. 控制跨站点参与

为了生成聚合直方图, 多个站点需要协作。 每个展示站点 都需要为其保存的展示 生成一致的值。 转化站点需要 信任展示站点会记录正确的值。

API 提供了多个过滤选项, 以帮助站点管理不需要的展示 污染聚合结果的风险。

过滤选项有助于 限制哪些站点能够参与归因, 从而减少能够污染聚合结果的实体集合。 有效使用这些选项对于防止 意外包含某些不需要的展示尤其有用。

这些过滤选项在抵御恶意污染结果的尝试方面 效力有限。 信任很少像这些控制所预期的那样严格二元。 被列入的展示站点可能会将 从转化站点角度看是真实的展示 与伪造或错误的展示混合。 错误展示表示所谓的无效流量(IVT), 其中一些可能被认为是欺诈性的。

8.5.1. 广告欺诈

Web 上的广告 一直是各种欺诈的对象。 站点可能会试图使用此 API 进行展示欺诈, 制造价值被错误归因到 其投放广告上的印象。

欺诈性注册展示 是此 API 的一个特别关注点, 因为展示只存储在设备上。 无法应用服务器端智能 来识别欺诈性展示并将其 排除在归因之外。

针对恶意展示的唯一直接缓解措施 是站点级过滤选项。 这防止完全不受信任站点上的展示 干扰对预期候选展示集合的归因。

相反,尽管转化报告是加密的, 因为这些报告被发送到转化站点, 转化站点可以作出判断, 认为该转化很可能是欺诈性的, 并将其排除在聚合之外。

9. 隐私考量

此 API 的主要隐私目标是 确保为站点提供执行归因的能力 不会增强它们执行跨站点识别的能力。

本节提供更多信息, 说明实现此目标所需的保护措施。 其他讨论涉及次要隐私目标, 例如防止同站点识别

9.1. Attribution API 暴露的信息

展示存储隐私预算 存储 包含关于浏览活动横截面的信息。 随着 API 使用增加, 此信息的范围也随之增加。 但是,写入这些存储的大多数信息 永远不会被披露。 因为归因是在设备上执行的 (设备上归因), Attribution API 只暴露关于已归因转化的信息。 这与其他方案形成对比,在那些方案中, 关于展示和转化的信息都会被发送到 聚合服务进行设备外归因。 在后一类方案中, 聚合服务被攻破 (或与聚合服务的通信被攻破)时 可能揭示的信息量 要大得多。

当 Attribution API 进行归因时, 关于该归因的信息只会在差分隐私限制允许的范围内 从设备释放。

虽然 Attribution API 旨在衡量 相对不频繁的转化事件 与有限一组相关展示候选项之间的关联, 但必须考虑 API 可能如何被误用 于更大规模的数据收集。 展示枚举可能的转化 站点(反之亦然)的要求 在防止 API 被误用进行大规模数据收集 以及使此类误用尝试更可见方面 具有重要作用。

9.2. 禁用 Attribution API

用户代理必须提供控件, 供用户禁用 Attribution API。

Attribution API 被设计为只揭示聚合信息。 使用差分隐私 限制了确定任何特定用户 是否对聚合输出作出贡献的可能性。 但是,一些用户仍可能更愿意 不参与归因测量。

实现可以向用户提供选择退出的选项, 使用 Attribution API 的专用控件, 或通过适用于多个功能的统一隐私控件。

用户代理开发者应考虑 其他隐私模式与 Attribution API 的交互。 例如,归因可能在私密浏览模式中被禁用, 或者如果用户选择退出诊断数据收集, 归因也可能被禁用。

按设计,网站无法检测用户是否已选择退出。

为了最大限度降低指纹识别风险, 并防止对选择禁用 Attribution API 的用户 进行歧视, 站点不得检测 API 是否被禁用。 具体而言,对 Attribution API 的所有调用 只要在其他方面有效, 即使 API 被禁用也会成功完成。 行为上的唯一差异是, API 被禁用时返回的转化 报告 永远不会报告任何转化值。 因为报告是加密的, 接收转化报告的站点无法检测到 这种差异。

9.3. 可见性

实现为用户提供一种方式, 以查看展示存储的状态 并审查过去的报告提交。

这些界面可能仅限于显示 站点对 Attribution API 聚合使用情况的摘要信息。 用于检查展示和已提交报告详情的界面 可以帮助用户和 Web 开发者 诊断 API 的运行。

9.4. 未配置的浏览器

此 API 假定用户代理实例 具有响应 measureConversion() 请求所需的 所有配置。

如果调用 measureConversion() 所需的聚合 服务配置 不存在或已过期, 站点可能会观察到这一点。

如果检索配置 可能延迟对 measureConversion() 调用的解析, 这会产生计时侧信道。 如果改为生成假响应, 来自正确配置的用户代理的响应 与假响应之间的差异 可能可被观察到。 这可能是密钥标识符的使用 或其他未加密元数据。 密文长度的差异也可能揭示被加密内容的变化 或算法选择的变化。

检测陈旧或缺失的配置可能被用于 对用户代理 进行指纹识别

因此,用户 代理 以站点不可观察的方式 优先获取聚合服务配置。 这可以通过在启动时 在开始加载任何内容之前获取配置来实现。

如果无法获得必要配置, 或配置明显陈旧, 实现可以选择在调用 measureConversion() 时 立即拒绝。 这会泄露信息, 但可能比尝试生成假值泄露得更少。

9.5. 在保存的展示中包含识别信息

站点能够在展示中 编码一定量的数据, 使用 matchValue 或其他字段。 API 不会阻止站点 在这些字段中编码用户标识符。 归因过程在构造转化报告时 可以使用这些数据, 这意味着该识别信息 有可能被接收该报告的站点获得。 以下措施缓解了此风险:

9.6. 在第三方上下文中使用

Attribution API 即使在第三方上下文中也可用。 特别是,第三方 iframe 可以调用 saveImpression()。 但请注意,展示会以顶级导航上下文的站点 记录,而不是以 iframe 的 记录。

虽然 API 在第三方上下文中可用 会带来一定的隐私风险增加, 但这种支持被认为是必要的, 因为 iframe 常用于展示广告。

9.7. 清除 API 状态

用户 代理可能会提供清除存储的选项。 这些选项存在有两个原因:

清除跟踪隐私预算支出的状态 会对面向站点的隐私产生不利影响。 站点随后将能够从归因中 获得更多信息。

当 API 被禁用时, 用户 代理可以清除 隐私 预算存储周期开始时间中的数据。 在这种情况下,如果 API 重新启用, 就无法确定 API 被禁用之前 已支出了多少预算。 在这种情况下,用户代理可以更新 上次清除浏览历史的值, 以确保隐私 预算不会被无意中超出。

9.7.1. 清除站点数据

在应用户请求清除站点数据 但保留浏览历史时, 用户 代理会调用为归因清除浏览历史, 给定受影响站点集合、 false(用于forgetVisits), 以及采取该操作的时间。 这会将该站点的隐私预算设置为零, 防止在该站点上使用转化测量。 这不会从展示存储中移除已保存的展示; 从逻辑上说,展示在保存时 就被转移给转化站点

当应站点请求 通过使用 `Clear-Site-Data` 标头清除站点数据时, 用户 代理只会移除展示, 而不会改变隐私预算存储周期开始 时间

9.7.2. 清除浏览历史

在清除浏览历史时, 更新隐私 预算存储是不够的。 保留为防止面向站点的隐私损失 所必需的按站点 信息 会留下关于站点访问的信息, 供计算机的其他用户发现。

清除浏览历史的用户代理 会调用为归因清除浏览历史, 给定受影响站点集合、 true(用于forgetVisits), 以及启动该操作的时间。

在清除浏览历史时, 用户 代理需要 移除所有按站点隐私预算信息 (也就是说,从隐私预算存储中移除条目)。 用户 代理还需要确保 任何后续隐私 预算支出 不会因丢失该信息而导致 超过配置限制的隐私损失。

这可以通过在丢弃浏览历史所在的周期 中禁用归因来实现。 否则,一个在清除历史前 立即花费其预算的站点 可能会通过 API 了解 比不清除状态时更多的信息。

这会在受影响站点周期剩余时间内禁用 API。 因为周期开始 时间没有被清除, 周期 时间线保持连续。

用户 代理会在上次清除浏览历史值中 记住上次清除历史的时间。 这用于防止预算支出, 直到可以保证站点不会超过 用户 代理选择的最大允许隐私预算

获取归因起始周期 算法 确保转化 站点 不能查询在清除状态后一个周期持续时间内 开始的任何周期中的 展示

9.7.3. 清除展示

必须提供一种机制来清除展示存储。 例如,可以在激活 禁用 Attribution API 的控件时 清除展示存储。

建议将用户代理提供的 任何清除已存储数据(历史、cookie 等)的机制 扩展为覆盖展示存储。 § 9.7 清除 API 状态提供了关于 清除已存储数据的更详细信息。

站点清除状态的用户 代理 必须丢弃在受影响期间保存的所有已保存 展示, 这些展示具有匹配的展示站点转化站点。 对于展示站点, 这些展示与被清除的活动有关。 已清除状态的转化站点 将无法使用这些展示

具有匹配的 中介站点展示 可以被保留。

9.8. 时钟的选择

此 API 使用挂钟作为其时间基础。 这主要是因为 API 依赖持久的时间概念。 单调时钟只在用户 代理的单次执行期间定义, 因此如果用户代理重启, 它不能保证一致性。

挂钟可以被调整以考虑 可能因时钟漂移而累积的误差。 因此,挂钟不能保证始终以一致速率 前进, 包括它有时可能后退的可能性。

挂钟的后退不会影响 此 API 提供的隐私保证。 只有时钟的前进 可能具有不利的隐私影响。 超过正常时间进度的前进 可能导致隐私预算 比预期更快地更新。

对于在每个周期内 经历校正的时钟, 时钟调整不会产生隐私影响。 单次足够大的校正 可能导致隐私 预算 提前更新, 从而导致一次性的隐私损失增加。 连续的大幅校正对隐私影响最严重, 因为每次周期之间的过渡 都会释放额外的隐私预算

时间的大幅增加 如果跳过整个周期, 不会导致额外的隐私损失。 除非展示能够被保存, 否则不可能发生隐私损失。

当然,任何需要对其时钟进行大幅 或连续 校正的用户代理 都很可能因其报告的时间而具有高度可识别性。 仅这一点就可能足以实现不希望的跨站点识别

10. 致谢

本规范是许多人大量工作的成果。 此级别 API 的总体形态基于 Luke Winstrom 的一个想法。 隐私架构由 [PPA-DP] 的作者提供。

一致性

文档 约定

一致性要求通过描述性断言 与 RFC 2119 术语的组合来表达。 规范性部分中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、 “MAY” 和 “OPTIONAL” 应按照 RFC 2119 中的说明来解释。 但是,为了可读性, 这些词在本规范中并非全部以大写字母出现。

本规范的全部文本均为规范性文本, 除非章节明确标记为非规范性、示例和注释。 [RFC2119]

本规范中的示例以“for example”一词引入, 或通过 class="example" 与规范性文本分开, 如下所示:

这是一个资料性示例的例子。

资料性注释以“Note”一词开头, 并通过 class="note" 与规范性文本分开, 如下所示:

Note,这是一个资料性注释。

一致性 算法

作为算法一部分以祈使语气表述的要求 (例如 "strip any leading space characters" 或 "return false and abort these steps") 应按照引入该算法时所使用的关键词 ("must"、"should"、"may" 等) 的含义来解释。

以算法或具体步骤表述的一致性要求 可以以任何方式实现, 只要最终结果等效即可。 特别是,本规范中定义的算法 旨在易于理解, 并非旨在高性能。 鼓励实现者进行优化。

索引

本规范定义的术语

由引用定义的术语

参考文献

规范性参考文献

[CLEAR-SITE-DATA]
Mike West. 清除站点数据. 2017 年 11 月 30 日. WD. URL: https://www.w3.org/TR/clear-site-data/
[CSS-2025]
Chris Lilley; et al. CSS 快照 2025. 2025 年 9 月 18 日. NOTE. URL: https://www.w3.org/TR/css-2025/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位 模块第 4 级. 2024 年 3 月 12 日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS2]
Bert Bos; et al. 层叠样式表第 2 级修订版 1(CSS 2.1)规范. 2011 年 6 月 7 日. REC. URL: https://www.w3.org/TR/CSS2/
[DAP]
Tim Geoghegan; et al. 用于隐私保护测量的分布式聚合 协议. 2024-04-29. URL: https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-16
[DAP-ATTRIBUTION]
Martin Thomson. 用于 Attribution API 的分布式 聚合协议(DAP)扩展. 2026-02-18. URL: https://datatracker.ietf.org/doc/html/draft-thomson-ppm-dap-attribution-01
[DAP-TASKPROV]
Shan Wang; Christopher Patton. DAP 的任务绑定与 带内配置. 2025-09-05. URL: https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-taskprov-03
[DOM]
Anne van Kesteren. DOM 标准. 现行标准. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 语言规范. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch 标准. 现行 标准. URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. 高分辨率时间. 2026 年 3 月 24 日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. 现行标准. URL: https://infra.spec.whatwg.org/
[PERMISSIONS-POLICY-1]
Ian Clelland. 权限策略. 2026 年 6 月 18 日. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[PRIO-L1]
Martin Thomson; David Cook. 一种用于带有 L1 范数贡献上界的 向量和的 Prio 实例化. 2024-10-21. URL: https://datatracker.ietf.org/doc/draft-thomson-ppm-l1-bound-sum/
[RFC2119]
S. Bradner. 用于 RFC 中表示 要求级别的关键词. 1997 年 3 月. 最佳当前实践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SECURE-CONTEXTS]
Mike West. 安全上下文. 2023 年 11 月 10 日. CRD. URL: https://www.w3.org/TR/secure-contexts/
[URL]
Anne van Kesteren. URL 标准. 现行标准. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. 现行 标准. URL: https://webidl.spec.whatwg.org/

非规范性参考文献

[COOKIES]
A. Barth. HTTP 状态管理机制. 2011 年 4 月. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[COPPACALYPSE]
Garrett Johnson; et al. COPPAcalypse?YouTube 和解对儿童内容的影响. 2024-03-14. URL: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4430334
[DP]
Cynthia Dwork; Aaron Roth. 差分隐私的算法基础. 2014. URL: https://doi.org/10.1561/0400000042
[EU-AD]
Niklas FOURBERG; et al. 在线 广告:定向广告对广告主、市场准入和消费者 选择的影响. 2021-06. URL: https://www.europarl.europa.eu/thinktank/en/document/IPOL_STU(2021)662913
[FEDCM]
Nicolas Pena Moreno. 联合凭证管理 API. 2024 年 8 月 20 日. FPWD. URL: https://www.w3.org/TR/fedcm-1/
[FREE-GDP]
Leonard Nakamura; Jon D. Samuels; Rachel Soloveichik. 在 GDP 与生产率账户中衡量 “免费”数字经济. 2017-10. URL: https://www.bea.gov/research/papers/2017/measuring-free-digital-economy-within-gdp-and-productivity-accounts
[NAV-TRACKING-MITIGATIONS]
导航跟踪 缓解措施. Editor's Draft. URL: https://privacycg.github.io/nav-tracking-mitigations/
[ONLINE-ADVERTISING]
Avi Goldfarb; Catherine Tucker. 在线 广告. URL: https://doi.org/10.1016/B978-0-12-385514-5.00006-9
[PPA-DP]
Pierre Tholoniat; et al. Cookie Monster:用于差分隐私广告测量系统的高效 端上预算管理. URL: https://arxiv.org/abs/2405.16719
[PPA-DP-2]
Pierre Tholoniat; et al. Big Bird:W3C 隐私保护归因 API 的隐私预算 管理. URL: https://arxiv.org/abs/2506.05290
[PRIO]
Henry Corrigan-Gibbs; Dan Boneh. Prio:私密、 鲁棒且可扩展的聚合统计计算. 2017-03-14. URL: https://crypto.stanford.edu/prio/paper.pdf
[RFC3492]
A. Costello. Punycode:一种用于应用中的国际化域名(IDNA)的 Unicode Bootstring 编码. 2003 年 3 月. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc3492/
[RFC4086]
D. Eastlake 3rd; J. Schiller; S. Crocker. 安全性的随机性要求. 2005 年 6 月. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc4086/
[RFC5890]
J. Klensin. 应用中的国际化域名(IDNA): 定义与文档框架. 2010 年 8 月. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc5890/
[RFC6761]
S. Cheshire; M. Krochmal. 特殊用途域 名. 2013 年 2 月. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc6761/
[RFC9180]
R. Barnes; et al. 混合公钥 加密. 2022 年 2 月. Informational. URL: https://www.rfc-editor.org/info/rfc9180/
[STORAGE]
Anne van Kesteren. Storage 标准. 现行 标准. URL: https://storage.spec.whatwg.org/
[UNSANCTIONED-TRACKING]
Mark Nottingham. 未经批准的 Web 跟踪. 2015 年 7 月 17 日. TAG Finding. URL: https://www.w3.org/2001/tag/doc/unsanctioned-tracking/
[VDAF]
Richard L. Barnes; et al. 可验证分布式 聚合函数. 2026-01-30. URL: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-18
[WEB-WITHOUT-3P-COOKIES]
没有第三方 Cookie 的 Web. URL: https://www.w3.org/2001/tag/doc/web-without-3p-cookies/

IDL 索引

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute Attribution attribution;
};

enum AttributionAggregationProtocol { "dap-18-histogram" };

dictionary AttributionAggregationService {
  required AttributionAggregationProtocol protocol;
};

[SecureContext, Exposed=Window]
interface AttributionAggregationServices {
  readonly maplike<USVString, AttributionAggregationService>;
};

[SecureContext, Exposed=Window]
interface Attribution {
  readonly attribute AttributionAggregationServices aggregationServices;
};

dictionary AttributionImpressionOptions {
  required unsigned long histogramIndex;
  unsigned long matchValue = 0;
  sequence<USVString> conversionSites = [];
  sequence<USVString> conversionCallers = [];
  unsigned long lifetimeDays = 30;
  long priority = 0;
};

dictionary AttributionImpressionResult {
};

[SecureContext, Exposed=Window]
partial interface Attribution {
  Promise<AttributionImpressionResult> saveImpression(AttributionImpressionOptions options);
};

dictionary AttributionConversionOptions {
  required USVString aggregationService;
  double epsilon = 1.0;

  required unsigned long histogramSize;

  unsigned long lookbackDays;
  sequence<unsigned long> matchValues = [];
  sequence<USVString> impressionSites = [];
  sequence<USVString> impressionCallers = [];

  sequence<double> credit;
  unsigned long value = 1;
  unsigned long maxValue = 1;
};

dictionary AttributionConversionResult {
  required Uint8Array report;
};

[SecureContext, Exposed=Window]
partial interface Attribution {
  Promise<AttributionConversionResult> measureConversion(AttributionConversionOptions options);
};