Skip to content

Commit 71e54f7

Browse files
Merge pull request #208 from w3c/intermediary-queries
Define intermediary interactions with the API
2 parents e6966b1 + 11f236c commit 71e54f7

File tree

1 file changed

+155
-25
lines changed

1 file changed

+155
-25
lines changed

api.bs

Lines changed: 155 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ though this capability is not presently supported in the API.
297297
* As histogram size increases, noise becomes a problem
298298
-->
299299

300+
300301
# Overview of Operation # {#overview}
301302

302303
The Attribution API provides aggregate information about the
@@ -434,7 +435,7 @@ Three types of sites are recognized:
434435
of the [=relevant settings object=]
435436
at the time that {{Attribution/measureConversion()}} is invoked.
436437

437-
* An <dfn>intermediary site</dfn> is a [=site=]
438+
* An <dfn local-lt=intermediary|intermediaries>intermediary site</dfn> is a [=site=]
438439
that calls the API from any cross-site frame, such as an [=iframe=].
439440
The [=intermediary site=] is derived from the [=origin=]
440441
of the [=relevant settings object=]
@@ -594,6 +595,7 @@ dictionary AttributionImpressionOptions {
594595
required unsigned long histogramIndex;
595596
unsigned long matchValue = 0;
596597
sequence<USVString> conversionSites = [];
598+
sequence<USVString> conversionCallers = [];
597599
unsigned long lifetimeDays = 30;
598600
};
599601

@@ -623,10 +625,20 @@ The arguments to <a method for=Attribution>saveImpression()</a> are as follows:
623625
</dd>
624626
<dt><dfn>conversionSites</dfn></dt>
625627
<dd>
626-
The sites where [=conversions=] for this impression may occur, identified by
627-
their domain names. The <a method for=Attribution>measureConversion()</a>
628-
method will only attribute to this impression when called by one of the indicated
629-
sites. If empty, any site will match.
628+
The top-level [=conversion sites=] where [=conversions=] for this impression may occur,
629+
identified by their domain names.
630+
The <a method for=Attribution>measureConversion()</a> method
631+
will only attribute to this impression when called by one of the indicated sites.
632+
If empty, any [=conversion site=] will match.
633+
<dt><dfn>conversionCallers</dfn></dt>
634+
<dd>
635+
The [=intermediary sites=] or [=conversion sites=]
636+
that are able to [=common matching logic|select=] this impression for [=conversion=],
637+
identified by their domain names.
638+
The <a method for=Attribution>measureConversion()</a> method
639+
will only attribute to this impression when called by one of the indicated sites.
640+
This option includes both [=conversion sites=] and [=intermediary sites=].
641+
If empty, any site that invokes the API will match.
630642
<dt><dfn>lifetimeDays</dfn></dt>
631643
<dd>
632644
A positive "time to live" (in days) after which the [=impression=] can no
@@ -691,14 +703,14 @@ contribute to the histogram, i.e., will be uniformly zero.
691703
the [=impression sites=] that might have saved impressions
692704
({{AttributionConversionOptions/impressionSites}}),
693705
the [=intermediary sites=] that might have saved impressions
694-
({{AttributionConversionOptions/intermediarySites}}),
706+
({{AttributionConversionOptions/impressionCallers}}),
695707
and the choice of {{AttributionConversionOptions/matchValue}}.
696708

697709
<xmp highlight=js>
698710
const selectionDetails = {
699711
lookbackDays: 14,
700712
impressionSites: ["publisher.example", "other.example"],
701-
intermediarySites: ["ad-tech.example"],
713+
impressionCallers: ["ad-tech.example"],
702714
matchValue: [2],
703715
};
704716
</xmp>
@@ -745,7 +757,7 @@ dictionary AttributionConversionOptions {
745757
unsigned long lookbackDays;
746758
sequence<unsigned long> matchValue = [];
747759
sequence<USVString> impressionSites = [];
748-
sequence<USVString> intermediarySites = [];
760+
sequence<USVString> impressionCallers = [];
749761

750762
AttributionLogic logic = "last-touch";
751763
unsigned long value = 1;
@@ -783,11 +795,19 @@ The arguments to <a method for=Attribution>measureConversion()</a> are as follow
783795
<dt><dfn>matchValue</dfn></dt>
784796
<dd>A match value that can be used to select this [=impression=].</dd>
785797
<dt><dfn>impressionSites</dfn></dt>
786-
<dd>A [=set=] of impression sites. Only [=impressions=] recorded where the [=impression site=] is in this set are eligible to match this [=conversion=]. If empty, any site will match.</dd>
787-
<dt><dfn>intermediarySites</dfn></dt>
788798
<dd>
789-
A [=set=] of sites which called the <a method for=Attribution>saveImpression()</a> API.
790-
Only [=impressions=] recorded by scripts originating from one of the [=intermediary sites=]
799+
A [=set=] of impression sites.
800+
Only [=impressions=] recorded where the [=impression site=] is in this set
801+
are eligible to match this [=conversion=].
802+
If empty, any site will match.
803+
</dd>
804+
<dt><dfn>impressionCallers</dfn></dt>
805+
<dd>
806+
A [=set=] of sites,
807+
both [=impression sites=] and [=intermediary sites=],
808+
that might have called the <a method for=Attribution>saveImpression()</a> API.
809+
If not empty,
810+
only [=impressions=] recorded by one of the listed sites
791811
are eligible to match this [=conversion=].
792812
</dd>
793813
<dt><dfn>logic</dfn></dt>
@@ -810,8 +830,81 @@ The arguments to <a method for=Attribution>measureConversion()</a> are as follow
810830
</dd>
811831
</dl>
812832

833+
834+
## Role of Intermediaries ## {#intermediaries}
835+
836+
This API has support for its operation by [=intermediaries=]
837+
on behalf of [=top-level origin|top-level=] [[#sites|sites]].
838+
Advertising is frequently delegated to independent operators
839+
that are responsible for placement, bidding, and measurement.
840+
841+
[=Impressions=] that are saved by an intermediary
842+
record the identity of the [=intermediary site=].
843+
When [[#logic-matching|selecting]] impressions
844+
for [[#measure-conversion-api-operation|conversion measurement]],
845+
the [=intermediary site|intermediary site identity=] can be used to select impressions.
846+
847+
848+
## Histogram Construction ## {#histogram-definition}
849+
850+
Conceptually, each saved [=impression=] has a single histogram definition.
851+
Each [=impression=] has a single [=impression/Histogram Index=] attribute
852+
that determines where the [=validated conversion options/Value|value=]
853+
allocated to that [=impression=] appears in [[#histograms|the resulting histgram]].
854+
855+
Each invocation of {{PrivateAttribution/measureConversion()}}
856+
therefore needs to select [=impressions=] that have the same histogram definition.
857+
Though this applies to all uses of the API,
858+
consistent definition of histograms is especially important when [=impressions=]
859+
are [[#save-impression-api|saved]] and [[#measure-conversion-api|measured]]
860+
by multiple [=intermediaries=].
861+
862+
All [=impressions=] that might be [=common matching logic|selected=]
863+
when invoking {{PrivateAttribution/measureConversion()}}
864+
need to use the same histogram definition.
865+
The API provides several tools
866+
for ensuring that only the right [=impressions=] are chosen.
867+
868+
For saved [=impressions=]:
869+
870+
* [=impression/Match Value|Match values=] can be used to separate [=impressions=]
871+
by histogram definition.
872+
873+
* Use of an [=impression=] for [=conversion=] can be restricted
874+
to be visible only to {{PrivateAttribution/measureConversion()}}
875+
on a [=impression/Conversion Sites|set of conversion sites=].
876+
877+
* Use of an [=impression=] for [=conversion=] can be restricted
878+
to be visible only to {{PrivateAttribution/measureConversion()}}
879+
invoked by a [=impression/Conversion Callers|set of sites=].
880+
881+
As part of [=common matching logic=] at the point of [=conversion=]:
882+
883+
* [=validated conversion options/Match Values|a set of match values=],
884+
limits the set of [=impressions=].
885+
886+
* A set of [=validated conversion options/Impression Sites=],
887+
restricts the [=impression sites=] where [=impressions=] were saved.
888+
889+
* A set of [=validated conversion options/Impression Callers=],
890+
restricts the set of [=conversion sites=] or [=intermediary sites=]
891+
that saved [=impressions=].
892+
893+
These options provide sites with flexibility in how attribution selects histograms.
894+
It does not preclude the use of different histograms by a [=conversion site=].
895+
Multiple [=impressions=] can be saved
896+
with different histogram definitions
897+
provided that {{PrivateAttribution/measureConversion()}} invocations
898+
never [=common matching logic|select=] [=impressions=] with different histogram definitions.
899+
This ensures that [=conversions=] can be [=attribution|attributed=] to multiple histograms
900+
by invoking {{PrivateAttribution/measureConversion()}} multiple times.
901+
902+
813903
## Permissions Policy Integration ## {#permission-policy}
814904

905+
The ability to delegate to an intermediary
906+
is controlled by [[#permission-policy|Permission Policy]].
907+
815908
This specification defines two [=policy-controlled features=]:
816909

817910
* Invocation of the <a method for=Attribution>saveImpression()</a> API,
@@ -861,6 +954,9 @@ The [=impression store=] is a [=set=] of [=impression|impressions=]:
861954
<dfn>Intermediary Site</dfn>: The [=intermediary site=] that called <a>saveImpression()</a>,
862955
or `undefined` if the API was invoked by the [=impression site=].
863956
<dfn>Conversion Sites</dfn>: The [=set=] of [=conversion sites=] that were passed to <a>saveImpression()</a>.
957+
<dfn>Conversion Callers</dfn>: The [=set=] of sites,
958+
either [=conversion sites=] or [=intermediary sites=],
959+
that can select this [=impression=] when invoking <a>measureConversion()</a>.
864960
<dfn>Timestamp</dfn>: The time at which <a>saveImpression()</a> was called.
865961
<dfn>Lifetime</dfn>: The [=duration=] an [=/impression=] remains eligible for attribution, either from the call to <a>saveImpression()</a>, or a [=/user agent=]-defined limit.
866962
<dfn>Histogram Index</dfn>: The histogram index passed to <a>saveImpression()</a>.
@@ -1255,6 +1351,11 @@ The <dfn method for=Attribution>saveImpression(|options|)</dfn> method steps are
12551351
for each value in |options|.{{AttributionImpressionOptions/conversionSites}}.
12561352
1. If any result in |conversionSites| is failure, return
12571353
[=a promise rejected with=] a {{"SyntaxError"}} {{DOMException}} in |realm|.
1354+
1. Let |conversionCallers| be the [=set=] that is the result
1355+
of invoking [=parse a site=]
1356+
for each value in |options|.{{AttributionImpressionOptions/conversionCallers}}.
1357+
1. If any result in |conversionCallers| is failure, return
1358+
[=a promise rejected with=] a {{"SyntaxError"}} {{DOMException}} in |realm|.
12581359
1. Run the following steps [=in parallel=]:
12591360
1. Construct |impression| as a [=impression|saved impression=] comprising:
12601361
: [=impression/Match Value=]
@@ -1265,6 +1366,8 @@ The <dfn method for=Attribution>saveImpression(|options|)</dfn> method steps are
12651366
:: |intermediarySite|
12661367
: [=impression/Conversion Sites=]
12671368
:: |conversionSites|
1369+
: [=impression/Conversion Callers=]
1370+
:: |conversionCallers|
12681371
: [=impression/Timestamp=]
12691372
:: |timestamp|
12701373
: [=impression/Lifetime=]
@@ -1305,13 +1408,12 @@ The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps
13051408
1. Let |now| be |settings|' [=environment settings object/current wall time=].
13061409
1. Let |topLevelSite| (the [=conversion site=]) be the result of
13071410
[=obtain a site|obtaining a site=] from the [=top-level origin=].
1308-
1. The [=intermediary site=] is set to
1411+
1. Let |intermediarySite| be:
13091412
1. a value of `undefined` if the [=origin=] is [=same site=]
13101413
with the [=top-level origin=],
13111414
1. otherwise, the result of
13121415
[=obtain a site|obtaining a site=]
13131416
from |settings|' [=environment settings object/origin=].
1314-
<!-- TODO: the intermediary site is currently unused -->
13151417
1. Let |validatedOptions| be the result of
13161418
[=validate AttributionConversionOptions|validating=] |options|,
13171419
returning [=a promise rejected with=] any thrown reason.
@@ -1321,7 +1423,7 @@ The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps
13211423
|validatedOptions|' [=validated conversion options/histogram size=].
13221424
1. If the Attribution API is [[#opt-out|enabled]], set |report| to the
13231425
result of [=do attribution and fill a histogram=] with |validatedOptions|,
1324-
|topLevelSite|, and |now|.
1426+
|topLevelSite|, |intermediarySite|, and |now|.
13251427
1. Let |encryptedReport| be the result of encrypting |report|.
13261428
<!-- TODO: Define "encrypting" -->
13271429
1. Let |result| be a {{AttributionConversionResult}} with the following items:
@@ -1343,7 +1445,7 @@ The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps
13431445
<dfn>Lookback</dfn>: A positive [=duration=].
13441446
<dfn>Match Value</dfn>: A [=set=] of [=32-bit unsigned integers=].
13451447
<dfn>Impression Sites</dfn>: A [=set=] of [=sites=].
1346-
<dfn>Intermediary Sites</dfn>: A [=set=] of [=sites=].
1448+
<dfn>Impression Callers</dfn>: A [=set=] of [=sites=].
13471449
<dfn>Logic</dfn>: A {{AttributionLogic}}.
13481450
<dfn>Value</dfn>: A [=32-bit unsigned integer=].
13491451
<dfn>Max Value</dfn>: A [=32-bit unsigned integer=].
@@ -1381,10 +1483,10 @@ To <dfn>validate {{AttributionConversionOptions}}</dfn> |options|:
13811483
of invoking [=parse a site=]
13821484
for each value in |options|.{{AttributionConversionOptions/impressionSites}}.
13831485
1. If any result in |impressionSites| is failure, throw a {{"SyntaxError"}} {{DOMException}}.
1384-
1. Let |intermediarySites| be the [=set=] that is the result
1486+
1. Let |impressionCallers| be the [=set=] that is the result
13851487
of invoking [=parse a site=]
1386-
for each value in |options|.{{AttributionConversionOptions/intermediarySites}}.
1387-
1. If any result in |intermediarySites| is failure, throw a {{"SyntaxError"}} {{DOMException}}.
1488+
for each value in |options|.{{AttributionConversionOptions/impressionCallers}}.
1489+
1. If any result in |impressionCallers| is failure, throw a {{"SyntaxError"}} {{DOMException}}.
13881490
1. Return a [=validated conversion options=] with the following fields:
13891491
: [=validated conversion options/Aggregation Service=]
13901492
:: |options|.{{AttributionConversionOptions/aggregationService}}
@@ -1398,8 +1500,8 @@ To <dfn>validate {{AttributionConversionOptions}}</dfn> |options|:
13981500
:: |matchValue|
13991501
: [=validated conversion options/Impression Sites=]
14001502
:: |impressionSites|
1401-
: [=validated conversion options/Intermediary Sites=]
1402-
:: |intermediarySites|
1503+
: [=validated conversion options/Impression Callers=]
1504+
:: |impressionCallers|
14031505
: [=validated conversion options/Logic=]
14041506
:: |options|.{{AttributionConversionOptions/logic}}
14051507
: [=validated conversion options/Value=]
@@ -1423,7 +1525,9 @@ after the [=common matching logic=] is applied and privacy budgeting occurs.
14231525

14241526
<div algorithm>
14251527
To <dfn>do attribution and fill a histogram</dfn>, given
1426-
[=validated conversion options=] |options|, [=site=] |topLevelSite|,
1528+
[=validated conversion options=] |options|,
1529+
[=site=] |topLevelSite|,
1530+
[=site=] |intermediarySite|,
14271531
and [=moment=] |now|:
14281532

14291533
1. Let |matchedImpressions| be an [=set/is empty|empty=] [=set=].
@@ -1437,7 +1541,7 @@ To <dfn>do attribution and fill a histogram</dfn>, given
14371541
1. For each |epoch| from |startEpoch| to |currentEpoch|, inclusive:
14381542

14391543
1. Let |impressions| be the result of invoking [=common matching logic=]
1440-
with |options|, |topLevelSite|, |epoch|, and |now|.
1544+
with |options|, |topLevelSite|, |intermediarySite|, |epoch|, and |now|.
14411545

14421546
1. If |impressions| [=set/is empty|is not empty=]:
14431547

@@ -1476,7 +1580,9 @@ To <dfn>create an all-zero histogram</dfn>, given an integer |size|:
14761580

14771581
<div algorithm>
14781582
To perform <dfn>common matching logic</dfn>, given
1479-
[=validated conversion options=] |options|, [=site=] |topLevelSite|,
1583+
[=validated conversion options=] |options|,
1584+
[=site=] |topLevelSite|,
1585+
[=site=] |intermediarySite|,
14801586
[=epoch index=] |epoch|, and [=moment=] |now|:
14811587

14821588
1. Let |matching| be an [=set/is empty|empty=] [=set=].
@@ -1497,6 +1603,13 @@ To perform <dfn>common matching logic</dfn>, given
14971603
and [=set/contains|does not contain=] |topLevelSite|,
14981604
[=iteration/continue=].
14991605

1606+
1. If |intermediarySite| is not `undefined`, let |caller| be |intermediarySite|.
1607+
Otherwise, let |caller| be |topLevelSite|.
1608+
1609+
1. If |impression|'s [=impression/conversion callers=] [=set/is empty|is not empty=]
1610+
and [=set/contains|does not contain=] |caller|,
1611+
[=iteration/continue=].
1612+
15001613
1. If |options|' [=validated conversion options/match value=] [=set/is empty|is not empty=]
15011614
and [=set/contains|does not contain=] |impression|'s [=impression/match value=],
15021615
[=iteration/continue=].
@@ -1506,6 +1619,11 @@ To perform <dfn>common matching logic</dfn>, given
15061619
[=list/contains|does not contain=] |impression|'s [=impression/impression site=],
15071620
[=iteration/continue=].
15081621

1622+
1. If |options|' [=validated conversion options/impression callers=] [=set/is empty|is not empty=]
1623+
and [=set/contains|does not contain=] |impression|'s [=impression/intermediary site=]
1624+
or |impression|'s [=impression/impression site=],
1625+
[=iteration/continue=].
1626+
15091627
1. [=set/Append=] |impression| to |matching|.
15101628

15111629
1. Return |matching|.
@@ -1568,7 +1686,7 @@ set on a response requesting that the user agent invoke the
15681686
<a method for=Attribution>saveImpression()</a> API.
15691687

15701688
<pre class=example id=ex-save-impression-header>
1571-
Save-Impression: conversion-sites=("advertiser.example"), histogram-index=2, match-value=12, lifetime-days=7
1689+
Save-Impression: conversion-sites=("advertiser.example"), conversion-callers=("intermediary.example"), histogram-index=2, match-value=12, lifetime-days=7
15721690
</pre>
15731691

15741692
The following keys are defined, corresponding to the members of
@@ -1584,6 +1702,14 @@ the {{AttributionImpressionOptions}} dictionary passed to
15841702
[[RFC5890|Internationalized Domain Names]] therefore need to use [[RFC3492|punycode]].
15851703
This key is optional. If not supplied, an empty set is saved for [=impression/Conversion Sites=].
15861704
</dd>
1705+
<dt><dfn noexport><code>conversion-callers</code></dfn></dt>
1706+
<dd>
1707+
Value of <a dict-member for=AttributionImpressionOptions>conversionCallers</a>,
1708+
an [=structured header/inner list=] containing [=structured header/string|strings=].
1709+
Each string value includes a domain name using A-labels only;
1710+
[[RFC5890|Internationalized Domain Names]] therefore need to use [[RFC3492|punycode]].
1711+
This key is optional. If not supplied, an empty set is saved for [=impression/Conversion Callers=].
1712+
</dd>
15871713
<dt><dfn noexport><code>histogram-index</code></dfn></dt>
15881714
<dd>
15891715
Value of <a dict-member for=AttributionImpressionOptions>histogramIndex</a>,
@@ -1616,6 +1742,8 @@ To <dfn noexport>parse a `Save-Impression` header</dfn> given a [=header value=]
16161742
1. Let |histogramIndex| be |dict|["<code>[=save-impression/histogram-index=]</code>"].
16171743
1. Let |conversionSites| be |dict|["<code>[=save-impression/conversion-sites=]</code>"]
16181744
[=map/with default=] an empty [=structured header/inner list=].
1745+
1. Let |conversionCallers| be |dict|["<code>[=save-impression/conversion-callers=]</code>"]
1746+
[=map/with default=] an empty [=structured header/inner list=].
16191747
1. If any of |conversionSites|' [=list/items=] is not a [=structured header/string=], return an error.
16201748
1. Let |matchValue| be |dict|["<code>[=save-impression/match-value=]</code>"] [=map/with default=] 0.
16211749
1. If |matchValue| is not an [=structured header/integer=] or is less than 0, return an error.
@@ -1628,6 +1756,8 @@ To <dfn noexport>parse a `Save-Impression` header</dfn> given a [=header value=]
16281756
:: |matchValue|
16291757
: {{AttributionImpressionOptions/conversionSites}}
16301758
:: |conversionSites|
1759+
: {{AttributionImpressionOptions/conversionCallers}}
1760+
:: |conversionCallers|
16311761
: {{AttributionImpressionOptions/lifetimeDays}}
16321762
:: |lifetimeDays|
16331763

0 commit comments

Comments
 (0)