归因第 1 级

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-attribution-20260820/
最新发布版本:
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。 该 API 会生成汇总统计数据,以帮助网站 更好地了解其广告在现实环境中的表现。 此 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. 目标

本文档旨在为使用广告的网站实现归因, 同时避免使用会促成或鼓励跟踪的机制, 例如跨站点 Cookie

Attribution API 旨在通过向网站提供衡量工具, 为用户带来间接的集体的益处。 这些工具在有效应用时, 可以提供有关广告表现的深入信息。

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
转化计数的示例直方图, 按展示所在站点分组

不同的分组可用于不同的目的。 这既可以支持 严谨的旨在确定因果关系的实验, 也可以支持对不同处理方式进行更简单的比较。 例如,按创意素材(广告的内容)进行分组 可用于比较不同的创意素材。

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

1.7. 局限性与成功使用

Attribution API 提供的结果 可以为广告策略相关决策提供信息。 但是,如果未采取应有的谨慎措施,使用该 API 可能会产生误导性结果,从而支持错误的决策。

为了利用 API 提供的信息做出更好的决策, 需要理解其局限性——尤其是潜在的偏差和误差来源。 这种理解需要应用于 使用该 API 的系统设计 以及对任何结果的解释之中。

范围局限性

一个关键局限是,Attribution API 只能捕获同一浏览器中的活动。 广告活动的范围和影响 很少局限于单一媒介。 这意味着不能假定获得的任何衡量结果 都捕获了所有相关活动。

非因果效应

接触广告的人中,有一部分 本来就打算采取 广告试图鼓励的行动。 将结果归因于这些广告 会对其有效性造成错误印象。

为了更好地衡量广告的因果效应, 有必要使用(随机化)对照试验——或者用行业术语来说,增量性——[INFERNO]。 基本的广告对照试验 包括确定目标受众, 向该受众中的处理组投放广告, 不向对照组投放广告或向其展示默认广告, 并衡量各组之间期望结果的差异。

此 API 可用于支持此类试验。 这可以通过将对照组和处理组人群 分配到不同的直方图桶中来实现。 但请注意,目前 Web 平台还没有一种机制 可以在不同网站之间 将用户一致地分配到 对照组和处理组。

简单归因逻辑

该 API 提供了一种简单的多触点归因算法。 简单的归因算法可能会在结果中引入偏差, 从而影响决策。 未来版本的 API 可能会支持更复杂的算法。

误差来源

在分布式衡量系统中 存在多种误差来源。 差分隐私会向聚合结果中引入一定量的噪声, 但其大小是已知的。

由于其他各种原因, 结果可能无法准确反映所衡量的内容, 其中一些原因可能无法避免, 包括:

  • 向参与网站传播配置时发生失败和延迟。

  • 脚本错误导致展示或转化事件丢失。

  • 因存储压力导致已存储的展示记录丢失。

  • 意外或恶意记录展示。

  • 网络错误导致报告丢失。

  • IVT 分类 导致真实事件被忽略。

  • IVT 分类 错误地包含欺诈行为或意外错误。

此类错误可能会给衡量结果 增加未知程度的不确定性。 使用该 API 的网站有责任 管理自身遭受这些及其他类别误差影响的程度。 未来版本的 API 可能会设法为网站提供更好的帮助, 以处理这些误差。

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中列出的任何受支持服务。 所选服务的名称会作为 aggregationService 成员提供给 AttributionConversionOptions 字典,以便在调用 measureConversion() 方法时使用。

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. 站点名称

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

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

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

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

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

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

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

  5. 如果 site 为 "localhost", ".localhost" 结尾, U+005B ([) 开头(它是 IPv6 地址), 或以数字结尾(它是 IPv4 地址), 则返回失败。

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

此算法能够成功地从以下字符串中生成站点: 其中包含的域标签多于可注册域中的域标签。 例如,"extra.example.com" 会被解析为 "example.com"。

此算法不接受以下主机: localhost 域[RFC6761]或 IP 地址。 因此,任何依赖提取站点名称的算法 在提及 localhost 域或 IP 地址时都会失败, 当前站点(顶级站点或框架中的站点)为 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集合,其中包含展示 impressions经验证的转化选项 options, 以及一个可选整数 singleEpochL1Norm,要扣减 隐私和安全预算
  1. epsilonoptionsepsilon

  2. valueoptions

  3. maxValueoptions最大值

  4. valueSensitivity 为 2 * value

  5. noiseScale 为 2 * maxValue / epsilon

  6. valueDeductionFpvalueSensitivity / noiseScale

  7. valueDeductionvalueDeductionFp * 1000000,并向正 无穷大方向舍入。

  8. deductionvalueDeduction

  9. 若给出了 singleEpochL1Norm

    1. l1NormDeductionFpsingleEpochL1Norm / noiseScale

    2. l1NormDeductionl1NormDeductionFp * 1000000,并向 正无穷大方向舍入。

    3. deduction 设置为 l1NormDeduction

    单周期归因 不会在各周期之间引发任何级联效应。 涉及多个周期的归因会消耗双倍预算, 因为一次更改可能会影响跨周期归因。 将扣减量加倍基于以下假设:向聚合直方图添加了 与 maxValue / epsilon 成比例的 拉普拉斯噪声。

  10. 归因预算锁为 true, 则等待其值变为 false, 然后将其值设置为 true。

  11. 若以 keydeductionvalueDeductionimpressions 调用检查可用隐私预算 所得到的结果为 false,则执行以下步骤:

    1. 归因预算锁设置为 false。

    2. 返回 false。

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

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

    2. 隐私预算存储key 的值 设置为 currentValuededuction

    3. epochkey周期索引分量。

    4. currentGlobalValue 为在全局隐私预算存储获取 epoch 的值所得的结果, 并以每周期全局隐私预算作为默认值。

    5. 全局隐私预算存储epoch 的值 设置为 currentGlobalValuevalueDeduction

      此扣减保证每个周期最多发生一次, 因为扣减隐私和安全 预算在每个周期最多调用 一次。

    6. deductedImpressionQuotas 为一个新的集合

    7. 对于 impressions 中的每个 impression

      1. impressionSiteimpression展示站点

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

      2. deductedImpressionQuotas包含 impressionSite

        1. impressionSite 追加deductedImpressionQuotas

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

        3. currentImpressionQuotaValue 为在每周期展示站点配额获取 impressionQuotaKey 的值所得的结果, 并以每周期展示站点配额 作为默认值。

        4. 每周期展示站点配额[impressionQuotaKey] 的值设置为 currentImpressionQuotaValuevalueDeduction

  13. 归因预算锁设置为 false。

  14. 返回 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 秒。

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

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

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

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

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

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

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

给定一个时刻 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,则可以跳过更新上次浏览历史清除

如果这三个条件全部为真, 则无需更新上次清除浏览历史记录的时间。 相反,隐私 预算存储必须通过 设置值为 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. startingEpoch 为以 now 为参数 调用获取归因的起始纪元 所得到的结果。

    3. currentEpoch 为以 now 为参数 调用获取当前纪元 所得到的结果。

    4. 对于 sites 中的每个 site

      1. 对于startingEpochcurrentEpoch闭区间 中的每个 epoch

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

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

    5. 返回。

  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 输入的结果, 如有任何抛出的原因,则返回以该原因拒绝的 promise

  2. 断言implicitInputs 不为 null。

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

给定 AttributionImpressionOptions options隐式 API 输入 implicitInputs,要保存 展示
  1. documentimplicitInputs关联文档

  2. realmdocument相关 Realm

  3. 如果 document 不被允许使用名为 "save-impression" 的策略控制的功能, 则返回以以下原因拒绝的 promise: 一个 "NotAllowedError" DOMException, 其位于 realm 中。

  4. 给定 document检查 Attribution API 激活状态,返回以任何抛出原因拒绝的 promise

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

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

    2. 如果 options.lifetimeDays 为 0, 则返回 RangeError 拒绝的 promise,其位于 realm 中。

    3. options.lifetimeDays 限制为 最大回溯期

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

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

    6. 如果 conversionSites 中的任何结果为失败,则返回 "NotAllowedError" DOMException 拒绝的 promise,其位于 realm 中。

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

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

    9. 如果 conversionCallers 中的任何结果为失败,则返回 "NotAllowedError" DOMException 拒绝的 promise,其位于 realm 中。

  6. 并行运行以下步骤:

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

      匹配值

      options.matchValue

      展示站点

      implicitInputs顶级站点

      中介站点

      implicitInputs中介站点

      转化站点

      conversionSites

      转化调用方

      conversionCallers

      时间戳

      implicitInputs时间戳

      生命周期

      options.lifetimeDays

      直方图索引

      options.histogramIndex

      优先级

      options.priority

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

  7. result 为一个新的 AttributionImpressionResult

  8. 返回在 realmresult 兑现的 promise

saveImpression() 不会返回指示展示是否已被记录的状态。 这可以最大限度降低检测归因 API 何时被禁用的能力。

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

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

顶层站点一个站点
中间站点一个站点undefined
时间戳一个时刻
关联文档一个 Document
要从领域 realm 获取 隐式 API 输入,并具有可选的(默认为 null):
  1. windowrealm全局对象

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

  3. settingsrealm设置对象

  4. timestampsettings当前墙上时间

  5. topLevelOriginsettings顶层源

  6. topLevelSite 为从 topLevelOrigin 获取 兼容站点的结果。

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

  8. intermediarySite 为:

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

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

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

    顶层站点

    topLevelSite

    中间站点

    intermediarySite

    时间戳

    timestamp

    关联文档

    window关联文档

给定 origin,要获取 兼容站点, 并返回一个站点
  1. 如果 origin 不是元组源, 则抛出一个 "NotAllowedError" DOMException

  2. hostorigin主机组件。

  3. 如果 host 为 "localhost", 如果 host 以 " ".localhost" 结尾, 如果 host U+005B ([) 开头, 或如果 host 以数字结尾, 则抛出一个 "NotAllowedError" DOMException

  4. 返回从 origin 获取站点的结果。

有关 localhost 域和 IP 地址主机的 处理说明,请参阅 § 4.1.4 站点名称

4.4. 衡量转化算法

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

measureConversion(options) 方法的 步骤如下:
  1. implicitInputs 为从 this 获取隐式 API 输入的结果, 如有任何抛出的原因,则返回以该原因拒绝的 promise

  2. 断言implicitInputs 不为 null。

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

给定 AttributionConversionOptions options隐式 API 输入 implicitInputs,要测量 转化
  1. documentimplicitInputs关联文档

  2. realmdocument相关领域

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

  4. 给定 document检查归因 API 激活状态, 如有任何抛出的原因,则返回以该原因拒绝的 promise

  5. validatedOptions验证 options 的结果, 如有任何抛出的原因,则返回以该原因拒绝的 promise

  6. promiserealm 中的一个新的 promise

  7. 并行运行以下步骤:

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

    2. 如果归因 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. 归因 任务源排入一个任务,以使用 result 兑现 promise

  8. 返回 promise

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

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

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

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

  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大小超过由实现定义的 最大 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 中的任何结果为失败,则抛出一个 "NotAllowedError" DOMException

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

  20. impressionCallers 为对 options.impressionCallers 中的每个值调用解析 站点所得结果组成的集合

  21. 如果 impressionCallers 中的任何结果为失败,则抛出一个 "NotAllowedError" 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. isSingleEpoch 为 true:

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

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

    3. histogram 为以 impressionsoptions直方图大小optionsoptions权重 执行使用最后 n 次触点归因填充 直方图所得的结果。

    4. l1Normhistogram 中各之和。

    5. 断言l1Norm 小于或等于 options

    6. key 为一个隐私预算键,其项为 currentEpochtopLevelSite

    7. budgetAndSafetyOk 为以 keyimpressionsoptionsl1Norm 调用扣减隐私和安全 预算 所得的结果。

    8. budgetAndSafetyOk 为 true,则返回 histogram

    9. 返回以 options直方图大小 调用创建全零直方图所得的结果。

  6. matchedImpressions 为一个集合

  7. 对于从 startEpochcurrentEpoch 的每个 epoch(含两端):

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

    2. impressions 不 为空

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

      2. budgetAndSafetyOk 为以 keyimpressionsoptions 调用扣减隐私和安全 预算 所得的结果。

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

  8. matchedImpressions 为 空,则返回以 options直方图大小 调用创建全零直方图所得的结果。

  9. histogram 为以 matchedImpressionsoptions直方图大小optionsoptions权重 执行使用最后 n 次触点归因填充 直方图所得的结果。

  10. 返回 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 值数量 选择一个由实现定义的值, 该值是对 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 的值, 是一个正整数。此键是可选的。
给定一个标头值 input,要解析 Save-Impression 标头,运行以下步骤:
  1. dict解析 结构化字段所得的结果, 其中将 input_bytes 设置为 input,并将 field_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
一个包含字符串, 其中包含潜在可信 URL, 生成的报告(如果有)将通过 POST 发送到该 URL。 该 URL 可以是相对于响应 URL 的相对 URL。 其方案必须为 "https"。 此键为必需项。
给定一个标头值 input 和一个URL baseUrl,要解析 Measure-Conversion 标头,运行以下步骤:
  1. dict解析 结构化字段所得的结果, 其中将 input_bytes 设置为 input,并将 field_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 为以 baseUrl 为基准,将URL 解析器应用于 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. microEpsilonoptionsepsilon 乘以 1,000,000,然后向正 Infinity 方向取整。

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

  7. taskConfig 为按照 第 4.2 节[DAP] 所定义的方式,对 TaskConfiguration 实例 进行编码所生成的字节 序列,其值如下:

    1. 一个空的 task_info

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

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

    4. 值为 5 的 time_precision

    5. 值为 20 的 min_batch_size

    6. 值为 TBD 的 batch_mode(参见用于归因 API 的分布式 聚合协议 (DAP) 扩展 § batch-mode)。

    7. 一个空的 batch_config

    8. 值为 7 的 vdaf_type(参见对贡献施加 L1 范数界的向量求和 Prio 实例化 § dap)。

    9. 按照 PrioL1BoundSum 对贡献施加 L1 范数界的向量求和 Prio 实例化 § dap进行编码的 vdaf_configuration, 其中使用 lengthmaxValuechunkLength

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

  8. taskID 为通过 DAP 的任务 绑定与带内配置 § task-id 中描述的过程生成的字节 序列, 并传入 taskConfig

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

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

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

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

  13. time 为将从Unix 纪元now持续时间 除以 5 秒的持续时间 所得的整数, 并向负 Infinity 方向取整。

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

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

  15. reportMetadata 为由 reportIDtimeextensions 生成的已编码 DAP ReportMetadata

  16. encryptedInputShares 为一个 列表

  17. 对于 inputShares 中的每个 share, 按照 第 4.4.2.1 节中描述的加密份额方法执行:

    1. pkR 为从 options.聚合 服务所指示的聚合服务获取的聚合服务 HPKE 配置中相应角色的公钥。

      "dap-18-histogram" 的 URL 预期用于标识 DAP Leader 角色。 实现需要静态获取两个聚合器的 HPKE 配置; 参见 § 9.4 未配置的浏览器

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

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

    4. inputShareAAD 按照 InputShareAad 的结构, 由 taskIDreportMetadatapublicSharetaskConfig 构造。

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

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

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

    8. encryptedShare 追加encryptedInputShares

  18. report 为由 reportMetadatapublicShareencryptedInputShares (这两个值分别为 Leader 和 Helper 的加密输入份额) 以及从 DAP 聚合器获得的聚合服务 HPKE 配置 生成的已编码 DAP Report

  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() 调用的解析, 这会产生一个时间侧信道。 如果改为生成伪造响应,则来自 正确配置的用户代理的响应 与伪造响应之间的差异 可能会被观察到。 这可能涉及使用密钥标识符或 其他未加密的元数据。 密文长度的差异也可能泄露被加密内容的变化 或算法选择的变化。

检测过期或缺失的配置可能被用于 对进行指纹识别用户代理。 HPKE 配置不得按需获取, 因为这所花费的时间会向 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
[INFERNO]
Garrett A. Johnson. 炼狱:在线展示广告 实地实验指南. 2023-01-18. URL:https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3581396
[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);
};