forked from WICG/attribution-reporting-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.bs
3025 lines (2504 loc) · 152 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
Title: Attribution Reporting
Shortname: attribution-reporting
Level: 1
Status: CG-DRAFT
Group: wicg
Repository: WICG/attribution-reporting-api
URL: https://wicg.github.io/attribution-reporting-api
Editor: Charlie Harrison, Google Inc. https://google.com, [email protected]
Editor: John Delaney, Google Inc. https://google.com, [email protected]
Editor: Andrew Paseltiner, Google Inc. https://google.com, [email protected]
Abstract: An API to report that an event may have been caused by another cross-site event. These reports are designed to transfer little enough data between sites that the sites can't use them to track individual users.
Markup Shorthands: markdown on
Complain About: accidental-2119 on, missing-example-ids on
Assume Explicit For: on
</pre>
<pre class=link-defaults>
spec:html; type:element; text:a
spec:html; type:element; text:script
spec:html; type:dfn; text:feature separators
spec:html; type:dfn; text:follow the hyperlink
spec:html; type:dfn; text:navigation params
spec:html; type:dfn; text:tokenize the features argument
spec:html; type:dfn; text:window open steps
</pre>
<pre class="anchors">
spec: clear-site-data; type: dfn; urlPrefix: https://w3c.github.io/webappsec-clear-site-data/
text: clear DOM-accessible storage for origin; url: #abstract-opdef-clear-dom-accessible-storage-for-origin
spec: hr-time; type: dfn; urlPrefix: https://w3c.github.io/hr-time/
text: current wall time; url: #dfn-current-wall-time
text: duration; url: #dfn-duration
text: moment; url: #dfn-moment
spec: idl; type: dfn; urlPrefix: https://webidl.spec.whatwg.org/
text: throw; url: #dfn-throw
spec: uuid; type: dfn; urlPrefix: https://wicg.github.io/uuid/
text: generate a random UUID; url: #dfn-generate-a-random-uuid
</pre>
Introduction {#intro}
=====================
<em>This section is non-normative</em>
This specification describes how web browsers can provide a mechanism to the
web that supports measuring and attributing conversions (e.g. purchases) to ads
a user interacted with on another site. This mechanism should remove one need
for cross-site identifiers like third-party cookies.
## Overview ## {#overview}
Pages/embedded sites are given the ability to register [=attribution sources=] and
[=attribution triggers=], which can be linked by the User Agent to generate and
send [=attribution reports=] containing information from both of those events.
A reporter `https://reporter.example` embedded on `https://source.example` is able to
measure whether an iteraction on the page lead to an action on `https://destination.example`
by registering an [=attribution source=] with [=attribution source/attribution destinations=]
of « `https://destination.example` ». Reporters are able to register sources through a variety
of surfaces, but ultimately the reporter is required to provide the User Agent with an
HTTP-response header which allows the source to be eligible for attribution.
At a later point in time, the reporter, now embedded on `https://destination.example`,
may register an [=attribution trigger=]. Reporters can register triggers by sending an
HTTP-response header containing information about the action/event that occurred. Internally,
the User Agent attempts to match the trigger to previously registered source events based on
where the sources/triggers were registered and configurations provided by the reporter.
If the User Agent is able to attribute the trigger to a source, it will generate and
send an [=attribution report=] to the reporter via an HTTP POST request at a later point
in time.
# HTML monkeypatches # {#html-monkeypatches}
<h3 id="monkeypatch-attributionsrc">API for elements</h3>
<pre class="idl">
interface mixin HTMLAttributionSrcElementUtils {
[CEReactions, SecureContext] attribute USVString attributionSrc;
};
HTMLAnchorElement includes HTMLAttributionSrcElementUtils;
HTMLImageElement includes HTMLAttributionSrcElementUtils;
HTMLScriptElement includes HTMLAttributionSrcElementUtils;
</pre>
Add the following <a spec=html>content attributes</a>:
: <{a}>
:: `attributionsrc` - [=URL=] for attribution registration
: <{img}>
:: `attributionsrc` - [=URL=] for attribution registration
: <{script}>
:: `attributionsrc` - [=URL=] for attribution registration
Add the following content attribute descriptions:
: <{a}>
:: The <dfn for="a" element-attr>attributionsrc</dfn> attribute is a [=string=]
representing the [=URL=] of the resource that will register an
[=attribution source=] when the <{a}> is navigated.
: <{img}>
:: The <dfn for="img" element-attr>attributionsrc</dfn> attribute is a
[=string=] representing the [=URL=] of the resource that will register an
[=attribution source=] or [=attribution trigger=] when set.
: <{script}>
:: The <dfn for="script" element-attr>attributionsrc</dfn> attribute is a
[=string=] representing the [=URL=] of the resource that will register an
[=attribution source=] or [=attribution trigger=] when set.
The IDL attribute {{HTMLAttributionSrcElementUtils/attributionSrc}}
must <a spec=html>reflect</a> the respective content attribute of the same
name.
To <dfn>make background attributionsrc requests</dfn> given an
{{HTMLAttributionSrcElementUtils}} |element| and an [=eligibility=]
|eligibility|:
1. Let |attributionSrc| be |element|'s
{{HTMLAttributionSrcElementUtils/attributionSrc}}.
1. Let |tokens| be the result of
[=split a string on ASCII whitespace|splitting=] |attributionSrc| on ASCII
whitespace.
1. [=list/iterate|For each=] |token| of |tokens|:
1. <a spec="HTML" lt="parse a URL">Parse</a> |token|, relative to
|element|'s [=Node/node document=]. If that is not successful,
[=iteration/continue=]. Otherwise, let |url| be the resulting
[=URL record=].
1. Run [=make a background attributionsrc request=] with |url|,
|contextOrigin|, |eligibility|, and |element|'s [=Node/node document=].
Issue: Set |contextOrigin| properly.
Issue: Consider allowing the user agent to limit the size of |tokens|.
Whenever an <{img}> or a <{script}> |element| is created or |element|'s
{{HTMLAttributionSrcElementUtils/attributionSrc}} attribute is set or changed,
run [=make background attributionsrc requests=] with |element| and
"<code>[=eligibility/event-source-or-trigger=]</code>".
Issue: Monkeypatch <{img}> and <{script}> loading so that the presence of an
{{HTMLAttributionSrcElementUtils/attributionSrc}} attribute sets the
{{HTMLImageElement/src}} or {{HTMLScriptElement/src}} request's
[=request/Attribution Reporting eligibility=] to
"<code>[=eligibility/event-source-or-trigger=]</code>".
Modify [=follow the hyperlink=] as follows:
After the step
> If |subject|'s link types includes...
add the steps
1. Let |navigationSourceEligible| be false.
1. If |subject| has an `attributionsrc` attribute:
1. Set |navigationSourceEligible| to true.
1. [=Make background attributionsrc requests=] with |subject| and
"<code>[=eligibility/navigation-source=]</code>".
Add "and [=navigate/navigationSourceEligible=] set to
|navigationSourceEligible|" to the step
> [=Navigate=] <var ignore=''>targetNavigable</var>...
<h3 id="monkeypatch-window-open">Window open steps</h4>
Modify the [=tokenize the features argument=] as follows:
Replace the step
> [=Collect a sequence of code points=] that are not [=feature separators=] code
> points from |features| given |position|. Set |value| to the collected code
> points, [=ASCII lowercase|converted to ASCII lowercase=].
with
[=Collect a sequence of code points=] that are not [=feature separators=] code
points from |features| given |position|. Set |value| to the collected code
points, [=ASCII lowercase|converted to ASCII lowercase=]. Set
|originalCaseValue| to the collected code points.
Replace the step
> If |name| is not the empty string, then set |tokenizedFeatures|[|name|] to
> |value|.
with the steps
1. If |name| is not the empty string:
1. Switch on |name|:
<dl class="switch">
: "`attributionsrc`"
:: Run the following steps:
1. If |tokenizedFeatures|[|name|] does not [=map/exists|exist=],
[=map/set=] |tokenizedFeatures|[|name|] to a new [=list=].
1. [=list/Append=] |originalCaseValue| to |tokenizedFeatures|[|name|].
: Anything else
:: Set |tokenizedFeatures|[|name|] to |value|.
</dl>
Modify the [=window open steps=] as follows:
After the step
> Let |tokenizedFeatures| be the result of
> [=tokenize the features argument|tokenizing=] |features|.
add the steps
1. Let |navigationSourceEligible| be false.
1. If |tokenizedFeatures|["`attributionsrc`"] [=map/exists=]:
1. [=Assert=]: |tokenizedFeatures|["`attributionsrc`"] is a [=list=].
1. Set |navigationSourceEligible| to true.
1. Set |attributionSrcUrls| to a new [=list=].
1. [=list/iterate|For each=] |value| of
|tokenizedFeatures|["`attributionsrc`"]:
1. If |value| is the empty string, [=iteration/continue=].
1. Let |decodedSrcBytes| be the result of
[=string/percent-decode|percent-decoding=] |value|.
1. Let |decodedSrc| be the [=UTF-8 decode without BOM=] of
|decodedSrcBytes|.
1. <a spec="HTML" lt="parse a URL">Parse</a> |decodedSrc| relative to
the <a spec="HTML" lt="entry settings object">entry settings object</a>,
and set |urlRecord| to the resulting [=URL record=], if any. If
parsing failed, [=iteration/continue=].
1. [=list/Append=] |urlRecord| to |attributionSrcUrls|.
Issue: Use |attributionSrcUrls| with [=make a background attributionsrc request=].
In each step that calls [=navigate=], set [=navigate/navigationSourceEligible=]
to |navigationSourceEligible|.
# Navigation monkeypatches # {#navigation-monkeypatches}
Add the following item to [=navigation params=]:
: <dfn for="navigation params">navigationSourceEligible</dfn>
:: A boolean indicating whether the navigation can register a
[=source type/navigation=] [=attribution source|source=] in its response.
Defaults to false.
Modify [=navigate=] as follows:
Add an optional boolean parameter called <dfn for="navigate">
<var>navigationSourceEligible</var></dfn>, defaulting to false.
In the step
> Set <var ignore=''>navigationParams</var> to a new [=navigation params=]
> with...
add the property
: [=navigation params/navigationSourceEligible=]
:: |navigationSourceEligible|
Issue: Use/propagate [=navigation params/navigationSourceEligible=] to the
[=navigation request=]'s [=request/Attribution Reporting eligibility=].
# Network monkeypatches # {#network-monkeypatches}
<pre class="idl">
dictionary AttributionReportingRequestOptions {
required boolean eventSourceEligible;
required boolean triggerEligible;
};
partial dictionary RequestInit {
AttributionReportingRequestOptions attributionReporting;
};
partial interface XMLHttpRequest {
[SecureContext]
undefined setAttributionReporting(AttributionReportingRequestOptions options);
};
</pre>
A [=request=] has an associated
<dfn for=request>Attribution Reporting eligibility</dfn> (an [=eligibility=]).
Unless otherwise stated it is "<code>[=eligibility/unset=]</code>".
To <dfn>get an eligibility from {{AttributionReportingRequestOptions}}</dfn>
given an optional {{AttributionReportingRequestOptions}} |options|:
1. If |options| is null, return "<code>[=eligibility/unset=]</code>".
1. Let |eventSourceEligible| be |options|'s
{{AttributionReportingRequestOptions/eventSourceEligible}}.
1. Let |triggerEligible| be |options|'s
{{AttributionReportingRequestOptions/triggerEligible}}.
1. If (|eventSourceEligible|, |triggerEligible|) is:
<dl class="switch">
: (false, false)
:: Return "<code>[=eligibility/empty=]</code>".
: (false, true)
:: Return "<code>[=eligibility/trigger=]</code>".
: (true, false)
:: Return "<code>[=eligibility/event-source=]</code>".
: (true, true)
:: Return "<code>[=eligibility/event-source-or-trigger=]</code>".
</dl>
Issue: Check permissions policy.
"<code><dfn>Attribution-Reporting-Eligible</dfn></code>" is a
<a href="https://httpwg.org/specs/rfc8941.html#dictionary">Dictionary Structured
Header</a> set on a [=request=] that indicates which registrations, if
any, are allowed on the corresponding [=response=]. Its values are not specified
and its <dfn lt="eligible key">allowed keys</dfn> are:
<dl dfn-for="eligible key">
: "<dfn><code>event-source</code></dfn>"
:: An [=source type/event=] [=attribution source|source=] may be registered.
: "<dfn><code>navigation-source</code></dfn>"
:: A [=source type/navigation=] [=attribution source|source=] may be registered.
: "<dfn><code>trigger</code></dfn>"
:: A [=attribution trigger|trigger=] may be registered.
</dl>
To <dfn>set Attribution Reporting headers</dfn> given a
[=header list=] |headers| and an [=eligibility=] |eligibility|:
1. [=header list/Delete=] "<code>[=Attribution-Reporting-Eligible=]</code>" from
|headers|.
1. [=header list/Delete=] "<code>[=Attribution-Reporting-Support=]</code>" from
|headers|.
1. If |eligibility| is "<code>[=eligibility/unset=]</code>", return.
1. Let |dict| be an [=ordered map=].
1. If |eligibility| is:
<dl class="switch">
: "<code>[=eligibility/empty=]</code>"
:: Do nothing.
: "<code>[=eligibility/event-source=]</code>"
:: [=map/Set=] |dict|["<code>[=eligible key/event-source=]</code>"] to
true.
: "<code>[=eligibility/navigation-source=]</code>"
:: [=map/Set=] |dict|["<code>[=eligible key/navigation-source=]</code>"] to
true.
: "<code>[=eligibility/trigger=]</code>"
:: [=map/Set=] |dict|["<code>[=eligible key/trigger=]</code>"] to true.
: "<code>[=eligibility/event-source-or-trigger=]</code>"
:: [=map/Set=] |dict|["<code>[=eligible key/event-source=]</code>"] to
true and [=map/set=] |dict|["<code>[=eligible key/trigger=]</code>"]
to true.
1. [=header list/Set a structured field value=] given
("<code>[=Attribution-Reporting-Eligible=]</code>", |dict|) in |headers|.
1. [=Set an OS-support header=] in |headers|.
<h3 id="monkeypatch-fetch">Fetch monkeypatches</h4>
Modify [=fetch=] as follows:
After the step
> If |request|'s [=request/header list=] does not contain `Accept`...
add the step
1. [=Set Attribution Reporting headers=] with |request|'s
[=request/header list=] and |request|'s
[=request/Attribution Reporting eligibility=].
Modify {{Request/constructor(input, init)}} as follows:
In the step
> Set |request| to a new [=request=] with the following properties:
add the property
: [=request/Attribution Reporting eligibility=]
:: |request|'s [=request/Attribution Reporting eligibility=].
After the step
> If |init|["`priority`"] [=map/exists=], then:
add the step
1. If |init|["{{RequestInit/attributionReporting}}"] [=map/exists=], then set
|request|'s [=request/Attribution Reporting eligibility=] to the result of
[=get an eligibility from AttributionReportingRequestOptions=] with it.
<h3 id="monkeypatch-xmlhttprequest">XMLHttpRequest monkeypatches</h4>
An {{XMLHttpRequest}} object has an associated
<dfn id="xmlhttprequest-eligibility">Attribution Reporting eligibility</dfn> (an
[=eligibility=]). Unless otherwise stated it is
"<code>[=eligibility/unset=]</code>".
The {{XMLHttpRequest/setAttributionReporting(options)}} method must run these
steps:
1. If <a>this</a>'s
<a href="https://xhr.spec.whatwg.org/#concept-xmlhttprequest-state">state</a>
is not <i>opened</i>, then [=throw=] an
"{{InvalidStateError!!exception}}" {{DOMException}}.
1. If <a>this</a>'s
<a href="https://xhr.spec.whatwg.org/#send-flag">`send()` flag</a> is set,
then [=throw=] an "{{InvalidStateError!!exception}}" {{DOMException}}.
1. Set <a>this</a>'s <a href=#xmlhttprequest-eligibility>Attribution Reporting
eligibility</a> to the result of
[=get an eligibility from AttributionReportingRequestOptions=] with
|options|.
Modify {{XMLHttpRequest/send(body)}} as follows:
After the step:
> Let |req| be a new [=request=], initialized as follows...
Add the step:
1. [=Set Attribution Reporting headers=] with |req|'s [=request/header list=]
and <a>this</a>'s <a href=#xmlhttprequest-eligibility>Attribution Reporting
eligibility</a>.
# Permissions Policy integration # {#permission-policy-integration}
This specification defines a [=policy-controlled feature=] identified by the string "<code><dfn noexport>attribution-reporting</dfn></code>".
Its [=policy-controlled feature/default allowlist=] is <a href="https://w3c.github.io/webappsec-permissions-policy/#default-allowlist">`*`</a>.
# Clear Site Data integration # {#clear-site-data-integration}
In [=clear DOM-accessible storage for origin=], add the following step:
> 7. Run [=clear site data=] with |origin|.
To <dfn>clear site data</dfn> given an [=origin=] |origin|:
1. [=set/iterate|For each=] [=attribution source=] |source| of the [=attribution source cache=]:
1. If |source|'s [=attribution source/reporting endpoint=] and |origin| are [=same origin=],
[=set/remove=] |source| from the [=attribution source cache=].
1. [=set/iterate|For each=] [=event-level report=] |report| of the [=event-level report cache=]:
1. If |report|'s [=event-level report/reporting endpoint=] and |origin| are [=same origin=],
[=set/remove=] |report| from the [=event-level report cache=].
1. [=set/iterate|For each=] [=aggregatable report=] |report| of the [=aggregatable report cache=]:
1. If |report|'s [=aggregatable report/reporting endpoint=] and |origin| are [=same origin=],
[=set/remove=] |report| from the [=aggregatable report cache=].
Note: We deliberately do *not* remove matching entries from the
[=attribution rate-limit cache=], as doing so would allow a site to reset and
therefore exceed the intended rate limits at will.
# Structures # {#structures}
<h3 dfn-type=dfn>Trigger state</h3>
A trigger state is a [=struct=] with the following items:
<dl dfn-for="trigger state">
: <dfn>trigger data</dfn>
:: A non-negative 64-bit integer.
: <dfn>report window</dfn>
:: A non-negative integer.
</dl>
<h3 dfn-type=dfn>Randomized response output configuration</h3>
A randomized response output configuration is a [=struct=] with the following items:
<dl dfn-for="randomized response output configuration">
: <dfn>max attributions per source</dfn>
:: A positive integer.
: <dfn>trigger data cardinality</dfn>
:: A positive integer.
: <dfn>num report windows</dfn>
:: A positive integer.
</dl>
<h3 dfn-type=dfn>Randomized source response</h3>
A randomized source response is null or a [=set=] of [=trigger states=].
<h3 id="attribution-filtering">Attribution filtering</h3>
A <dfn>filter value</dfn> is an [=ordered set=] of [=strings=].
A <dfn>filter map</dfn> is an [=ordered map=] whose [=map/key|keys=] are [=strings=] and whose
[=map/value|values=] are [=filter values=].
<h3 dfn-type=dfn>Suitable origin</h3>
A suitable origin is an [=origin=] that is [=check if an origin is suitable|suitable=].
<h3 id="source-type-header">Source type</h3>
A <dfn>source type</dfn> is one of the following:
<dl dfn-for="source type">
: "<dfn><code>navigation</code></dfn>"
:: The source was associated with a top-level navigation.
: "<dfn><code>event</code></dfn>"
:: The source was not associated with a top-level navigation.
</dl>
<h3 dfn-type=dfn>Attribution source</h3>
An attribution source is a [=struct=] with the following items:
<dl dfn-for="attribution source">
: <dfn>source identifier</dfn>
:: A [=string=].
: <dfn>source origin</dfn>
:: A [=suitable origin=].
: <dfn>event ID</dfn>
:: A non-negative 64-bit integer.
: <dfn>attribution destinations</dfn>
:: An [=ordered set=] of [=sites=].
: <dfn>reporting endpoint</dfn>
:: A [=suitable origin=].
: <dfn>source type</dfn>
:: A [=source type=].
: <dfn>expiry</dfn>
:: A [=duration=].
: <dfn>event report window</dfn>
:: A [=duration=].
: <dfn>aggregatable report window</dfn>
:: A [=duration=].
: <dfn>priority</dfn>
:: A 64-bit integer.
: <dfn>source time</dfn>
:: A [=moment=].
: <dfn>number of event-level reports</dfn>
:: Number of [=event-level reports=] created for this [=attribution source=].
: <dfn>event-level attributable</dfn> (default true)
:: A [=boolean=].
: <dfn>dedup keys</dfn>
:: [=ordered set=] of [=event-level trigger configuration/dedup keys=] associated with this [=attribution source=].
: <dfn>randomized response</dfn>
:: A [=randomized source response=].
: <dfn>randomized trigger rate</dfn>
:: A number between 0 and 1 (both inclusive).
: <dfn>filter data</dfn>
:: A [=filter map=].
: <dfn>debug key</dfn>
:: Null or a non-negative 64-bit integer.
: <dfn>aggregation keys</dfn>
:: An [=ordered map=] whose [=map/key|keys=] are [=strings=] and whose [=map/value|values=] are
non-negative 128-bit integers.
: <dfn>aggregatable budget consumed</dfn>
:: A non-negative integer, total [=aggregatable contribution/value=] of all [=aggregatable contributions=] created with this [=attribution source=].
: <dfn>aggregatable dedup keys</dfn>
:: [=ordered set=] of [=aggregatable dedup key/dedup key|aggregatable dedup key values=] associated with this [=attribution source=].
: <dfn>debug reporting enabled</dfn>
:: A [=boolean=].
</dl>
An [=attribution source=] |source|'s <dfn for="attribution source">expiry time</dfn> is |source|'s [=attribution source/source time=] + |source|'s [=attribution source/expiry=].
An [=attribution source=] |source|'s <dfn for="attribution source">event report window time</dfn> is |source|'s [=attribution source/source time=] + |source|'s [=attribution source/event report window=].
An [=attribution source=] |source|'s <dfn for="attribution source">aggregatable report window time</dfn> is |source|'s [=attribution source/source time=] + |source|'s [=attribution source/aggregatable report window=].
An [=attribution source=] |source|'s <dfn for="attribution source">source site</dfn> is the result
of [=obtain a site|obtaining a site=] from |source|'s [=attribution source/source origin=].
<h3 dfn-type=dfn>Aggregatable trigger data</h3>
An aggregatable trigger data is a [=struct=] with the following items:
<dl dfn-for="aggregatable trigger data">
: <dfn>key piece</dfn>
:: A non-negative 128-bit integer.
: <dfn>source keys</dfn>
:: An [=ordered set=] of [=strings=].
: <dfn>filters</dfn>
:: A [=list=] of [=filter maps=].
: <dfn>negated filters</dfn>
:: A [=list=] of [=filter maps=].
</dl>
<h3 dfn-type=dfn>Aggregatable dedup key</h3>
An aggregatable dedup key is a [=struct=] with the following items:
<dl dfn-for="aggregatable dedup key">
: <dfn>dedup key</dfn>
:: Null or a non-negative 64-bit integer.
: <dfn>filters</dfn>
:: A [=filter map=].
: <dfn>negated filters</dfn>
:: A [=filter map=].
</dl>
<h3 dfn-type=dfn>Event-level trigger configuration</h3>
An event-level trigger configuration is a [=struct=] with the following items:
<dl dfn-for="event-level trigger configuration">
: <dfn>trigger data</dfn>
:: A non-negative 64-bit integer.
: <dfn>dedup key</dfn>
:: Null or a non-negative 64-bit integer.
: <dfn>priority</dfn>
:: A 64-bit integer.
: <dfn>filters</dfn>
:: A [=list=] of [=filter maps=].
: <dfn>negated filters</dfn>
:: A [=list=] of [=filter maps=].
</dl>
<h3 id="aggregation-coordinator-header">Aggregation coordinator</h3>
An <dfn>aggregation coordinator</dfn> is one of a user-agent-determined [=set=]
of [=strings=] that specifies which aggregation service deployment to use.
<h3 id="aggregatable-source-registration-time-configuration-header">Aggregatable source registration time configuration</h3>
An <dfn>aggregatable source registration time configuration</dfn> is one of the following:
<dl dfn-for="aggregatable source registration time configuration">
: "<dfn><code>exclude</code></dfn>"
:: "`source_registration_time`" is excluded from an [=aggregatable report=]'s [=aggregatable report/shared info=].
: "<dfn><code>include</code></dfn>"
:: "`source_registration_time`" is included in an [=aggregatable report=]'s [=aggregatable report/shared info=].
</dl>
<h3 dfn-type=dfn>Attribution trigger</h3>
An attribution trigger is a [=struct=] with the following items:
<dl dfn-for="attribution trigger">
: <dfn>attribution destination</dfn>
:: A [=site=].
: <dfn>trigger time</dfn>
:: A [=moment=].
: <dfn>reporting endpoint</dfn>
:: A [=suitable origin=].
: <dfn>filters</dfn>
:: A [=list=] of [=filter maps=].
: <dfn>negated filters</dfn>
:: A [=list=] of [=filter maps=].
: <dfn>debug key</dfn>
:: Null or a non-negative 64-bit integer.
: <dfn>event-level trigger configurations</dfn>
:: A [=set=] of [=event-level trigger configuration=].
: <dfn>aggregatable trigger data</dfn>
:: A [=list=] of [=aggregatable trigger data=].
: <dfn>aggregatable values</dfn>
:: An [=ordered map=] whose [=map/key|keys=] are [=strings=] and whose
[=map/value|values=] are non-negative 32-bit integers.
: <dfn>aggregatable dedup keys</dfn>
:: A [=list=] of [=aggregatable dedup key=].
: <dfn>serialized private state tokens</dfn>
:: A [=list=] of [=byte sequence=].
: <dfn>debug reporting enabled</dfn>
:: A [=boolean=].
: <dfn>aggregation coordinator</dfn>
:: An [=aggregation coordinator=].
: <dfn>aggregatable source registration time configuration</dfn>
:: An [=aggregatable source registration time configuration=].
</dl>
<h3 dfn-type=dfn>Attribution report</h3>
An attribution report is a [=struct=] with the following items:
<dl dfn-for="attribution report, aggregatable report, event-level report">
: <dfn>reporting endpoint</dfn>
:: A [=suitable origin=].
: <dfn>report time</dfn>
:: A [=moment=].
: <dfn>original report time</dfn>
:: A [=moment=].
: <dfn>delivered</dfn> (default false)
:: A [=boolean=].
: <dfn>report ID</dfn>
:: A [=string=].
: <dfn>source debug key</dfn>
:: Null or a non-negative 64-bit integer.
: <dfn>trigger debug key</dfn>
:: Null or a non-negative 64-bit integer.
</dl>
<h3 dfn-type=dfn>Event-level report</h3>
An event-level report is an [=attribution report=] with the following additional items:
<dl dfn-for="event-level report">
: <dfn>event ID</dfn>
:: A non-negative 64-bit integer.
: <dfn>source type</dfn>
:: A [=source type=].
: <dfn>trigger data</dfn>
:: A non-negative 64-bit integer.
: <dfn>randomized trigger rate</dfn>
:: A number between 0 and 1 (both inclusive).
: <dfn>trigger priority</dfn>
:: A 64-bit integer.
: <dfn>trigger time</dfn>
:: A [=moment=].
: <dfn>source identifier</dfn>
:: A string.
: <dfn>attribution destinations</dfn>
:: An [=ordered set =] of [=sites=].
</dl>
<h3 dfn-type=dfn>Aggregatable contribution</h3>
An aggregatable contribution is a [=struct=] with the following items:
<dl dfn-for="aggregatable contribution">
: <dfn>key</dfn>
:: A non-negative 128-bit integer.
: <dfn>value</dfn>
:: A non-negative 32-bit integer.
</dl>
<h3 dfn-type=dfn>Aggregatable report</h3>
An aggregatable report is an [=attribution report=] with the following additional items:
<dl dfn-for="aggregatable report">
: <dfn>source time</dfn>
:: A [=moment=].
: <dfn>contributions</dfn>
:: A [=list=] of [=aggregatable contributions=].
: <dfn>effective attribution destination</dfn>
:: A [=site=].
: <dfn>serialized private state token</dfn>
:: A [=byte sequence=].
: <dfn>aggregation coordinator</dfn>
:: An [=aggregation coordinator=].
: <dfn>source registration time configuration</dfn>
:: An [=aggregatable source registration time configuration=].
: <dfn>is null report</dfn> (default false)
:: A [=boolean=].
</dl>
<h3 id="attribution-rate-limits">Attribution rate-limits</h3>
A <dfn>rate-limit scope</dfn> is one of the following:
<ul dfn-for="rate-limit scope">
<li>"<dfn><code>source</code></dfn>"
<li>"<dfn><code>attribution</code></dfn>"
</ul>
An <dfn>attribution rate-limit record</dfn> is a [=struct=] with the following items:
<dl dfn-for="attribution rate-limit record">
: <dfn>scope</dfn>
:: A [=rate-limit scope=].
: <dfn>source site</dfn>
:: A [=site=].
: <dfn>attribution destination</dfn>
:: A [=site=].
: <dfn>reporting endpoint</dfn>
:: A [=suitable origin=].
: <dfn>time</dfn>
:: A [=moment=].
: <dfn>expiry time</dfn>
:: Null or a [=moment=].
</dl>
<h3 dfn-type=dfn>Attribution debug data</h3>
A <dfn>debug data type</dfn> is a non-empty string that specifies the set of data that is
contained in the [=attribution debug data/body=] of an [=attribution debug data=].
A <dfn>source debug data type</dfn> is a [=debug data type=] for source registrations.
Possible values are:
<ul dfn-for="source debug data type">
<li>"<dfn><code>source-destination-limit</code></dfn>"
<li>"<dfn><code>source-noised</code></dfn>"
<li>"<dfn><code>source-storage-limit</code></dfn>"
<li>"<dfn><code>source-success</code></dfn>"
<li>"<dfn><code>source-unknown-error</code></dfn>"
</ul>
A <dfn>trigger debug data type</dfn> is a [=debug data type=] for trigger registrations.
Possible values are:
<ul dfn-for="trigger debug data type">
<li>"<dfn><code>trigger-aggregate-deduplicated</code></dfn>"
<li>"<dfn><code>trigger-aggregate-no-contributions</code></dfn>"
<li>"<dfn><code>trigger-aggregate-insufficient-budget</code></dfn>"
<li>"<dfn><code>trigger-aggregate-storage-limit</code></dfn>"
<li>"<dfn><code>trigger-aggregate-report-window-passed</code></dfn>"
<li>"<dfn><code>trigger-attributions-per-source-destination-limit</code></dfn>"
<li>"<dfn><code>trigger-event-deduplicated</code></dfn>"
<li>"<dfn><code>trigger-event-excessive-reports</code></dfn>"
<li>"<dfn><code>trigger-event-low-priority</code></dfn>"
<li>"<dfn><code>trigger-event-no-matching-configurations</code></dfn>"
<li>"<dfn><code>trigger-event-noise</code></dfn>"
<li>"<dfn><code>trigger-event-report-window-passed</code></dfn>"
<li>"<dfn><code>trigger-event-storage-limit</code></dfn>"
<li>"<dfn><code>trigger-no-matching-source</code></dfn>"
<li>"<dfn><code>trigger-no-matching-filter-data</code></dfn>"
<li>"<dfn><code>trigger-reporting-origin-limit</code></dfn>"
<li>"<dfn><code>trigger-unknown-error</code></dfn>"
</ul>
An attribution debug data is a [=struct=] with the following items:
<dl dfn-for="attribution debug data">
: <dfn>data type</dfn>
:: A [=debug data type=].
: <dfn>body</dfn>
:: A [=map=] whose fields are determined by the [=attribution debug data/data type=].
</dl>
<h3 dfn-type=dfn>Attribution debug report</h3>
An attribution debug report is a [=struct=] with the following items:
<dl dfn-for="attribution debug report">
: <dfn>data</dfn>
:: A [=list=] of [=attribution debug data=].
: <dfn>reporting endpoint</dfn>
:: A [=suitable origin=].
</dl>
<h3 dfn-type=dfn>Triggering result</h3>
A <dfn>triggering status</dfn> is one of the following:
<ul dfn-for="triggering status">
<li>"<dfn><code>dropped</code></dfn>"
<li>"<dfn><code>noised</code></dfn>"
<li>"<dfn><code>attributed</code></dfn>"
</ul>
Note: "<code>[=triggering status/noised=]</code>" only applies for [=triggering event-level attribution=] when it is attributed
successfully but dropped as the noise was applied to the source.
A triggering result is a [=tuple=] with the following items:
<dl dfn-for="triggering result">
: <dfn>status</dfn>
:: A [=triggering status=].
: <dfn>debug data</dfn>
:: Null or an [=attribution debug data=].
</dl>
# Storage # {#storage}
A user agent holds an <dfn>attribution source cache</dfn>, which is an [=ordered set=] of [=attribution sources=].
A user agent holds an <dfn>event-level report cache</dfn>, which is an [=ordered set=] of [=event-level reports=].
A user agent holds an <dfn>aggregatable report cache</dfn>, which is an [=ordered set=] of [=aggregatable reports=].
A user agent holds an <dfn>attribution rate-limit cache</dfn>, which is an [=ordered set=] of [=attribution rate-limit records=].
The above caches are collectively known as the <dfn>attribution caches</dfn>. The [=attribution caches=] are
shared among all [=environment settings objects=].
Note: This would ideally use <a spec=storage>storage bottles</a> to provide access to the attribution caches.
However attribution data is inherently cross-site, and operations on storage would need to span across all storage bottle maps.
# Vendor-Specific Values # {#vendor-specific-values}
<dfn>Max source expiry</dfn> is a positive [=duration=] that controls the
maximum value that can be used as an [=attribution source/expiry=]. It must be
greater than or equal to 30 days.
<dfn>Max entries per filter data</dfn> is a positive integer that controls the
maximum [=map/size=] of an [=attribution source=]'s [=attribution source/filter data=].
<dfn>Max values per filter data entry</dfn> is a positive integer that
controls the maximum [=set/size=] of each [=map/value=] of an
[=attribution source=]'s [=attribution source/filter data=].
<dfn>Max aggregation keys per attribution</dfn> is a positive integer that
controls the maximum [=map/size=] of an [=attribution source=]'s
[=attribution source/aggregation keys=], the maximum [=set/size=] of an
[=aggregatable trigger data=]'s [=aggregatable trigger data/source keys=],
and the maximum [=map/size=] of an [=attribution trigger=]'s
[=attribution trigger/aggregatable values=].
<dfn>Max pending sources per source origin</dfn> is a positive integer that
controls how many [=attribution sources=] can be in the
[=attribution source cache=] per [=attribution source/source origin=].
<dfn>Navigation-source trigger data cardinality</dfn> is a positive integer
that controls the valid range of
[=event-level trigger configuration/trigger data=] for triggers that are
attributed to an [=attribution source=] whose
[=attribution source/source type=] is "<code>[=source type/navigation=]</code>":
0 <= [=event-level trigger configuration/trigger data=] < [=navigation-source trigger data cardinality=].
<dfn>Event-source trigger data cardinality</dfn> is a positive integer that
controls the valid range of [=event-level trigger configuration/trigger data=]
for triggers that are attributed to an [=attribution source=] whose
[=attribution source/source type=] is "<code>[=source type/event=]</code>":
0 <= [=event-level trigger configuration/trigger data=] < [=event-source trigger data cardinality=].
<dfn>Randomized response epsilon</dfn> is a non-negative double that controls
the randomized response probability of an [=attribution source=].
<dfn>Randomized null report rate excluding source registration time</dfn> is a
double between 0 and 1 (both inclusive) that controls the randomized number of null reports
generated for an [=attribution trigger=] whose [attribution trigger/aggregatable source registration time configuration]
is "<code>[=aggregatable source registration time configuration/exclude=]</code>".
<dfn>Randomized null report rate including source registration time</dfn> is a
double between 0 and 1 (both inclusive) that controls the randomized number of null reports
generated for an [=attribution trigger=] whose [attribution trigger/aggregatable source registration time configuration]
is "<code>[=aggregatable source registration time configuration/include=]</code>".
<dfn>Max event-level reports per attribution destination</dfn> is a positive integer that
controls how many [=event-level reports=] can be in the
[=event-level report cache=] per [=site=] in
[=event-level report/attribution destinations=].
<dfn>Max aggregatable reports per attribution destination</dfn> is a positive integer that controls how
many [=aggregatable reports=] can be in the [=aggregatable report cache=] per
[=aggregatable report/effective attribution destination=].
<dfn>Max attributions per navigation source</dfn> is a positive integer that
controls how many times a single [=attribution source=] whose
[=attribution source/source type=] is "<code>[=source type/navigation=]</code>" can create an
[=event-level report=].
<dfn>Max attributions per event source</dfn> is a positive integer that
controls how many times a single [=attribution source=] whose
[=attribution source/source type=] is "<code>[=source type/event=]</code>" can create an
[=event-level report=].
<dfn>Max destinations covered by unexpired sources</dfn> is a positive
integer that controls the maximum number of distinct [=sites=] across all [=attribution source/attribution destinations=]
for unexpired [=attribution sources=] with a given ([=attribution source/source site=], [=attribution source/reporting endpoint=]).
<dfn>Attribution rate-limit window</dfn> is a positive [=duration=] that
controls the rate-limiting window for attribution.
<dfn>Max source reporting endpoints per rate-limit window</dfn> is a positive
integer that controls the maximum number of distinct
[=attribution source/reporting endpoint|reporting endpoints=] for a
([=attribution rate-limit record/source site=],
[=attribution rate-limit record/attribution destination=]) that can create
[=attribution sources=] per [=attribution rate-limit window=].
<dfn>Max attribution reporting endpoints per rate-limit window</dfn> is a
positive integer that controls the maximum number of distinct
[=attribution trigger/reporting endpoint|reporting endpoints=] for a
([=attribution rate-limit record/source site=],
[=attribution rate-limit record/attribution destination=]) that can create
[=event-level reports=] per [=attribution rate-limit window=].
<dfn>Max attributions per rate-limit window</dfn> is a positive integer that
controls the maximum number of attributions for a
([=attribution rate-limit record/source site=],
[=attribution rate-limit record/attribution destination=],
[=attribution rate-limit record/reporting endpoint=]) per
[=attribution rate-limit window=].
<dfn>Allowed aggregatable budget per source</dfn> is a positive integer that controls the total
[=aggregatable report/required aggregatable budget=] of all [=aggregatable reports=] created for
an [=attribution source=].
<dfn>Min aggregatable report delay</dfn> is a non-negative [=duration=] that controls the minimum
delay to deliver an [=aggregatable report=].
<dfn>Randomized aggregatable report delay</dfn> is a positive [=duration=] that controls the
random delay to deliver an [=aggregatable report=].
<dfn>Default aggregation coordinator</dfn> is the [=aggregation coordinator=] that controls how to
obtain the public key for encrypting an [=aggregatable report=] by default.
# General Algorithms # {#general-algorithms}
<h3 id="serialize-integer">Serialize an integer</h3>
To <dfn>serialize an integer</dfn>, represent it as a string of the shortest possible decimal number.
Issue: This would ideally be replaced by a more descriptive algorithm in Infra. See
<a href="https://github.com/whatwg/infra/issues/201">infra/201</a>
<h3 id="serialize-destinations">Serialize attribution destinations</h3>
To <dfn>serialize [=event-level report/attribution destinations=]</dfn> |destinations|, run the following steps:
1. [=Assert=]: |destinations| is not [=set/is empty|empty=].
1. Let |destinationStrings| be a [=list=].
1. [=list/iterate|For each=] |destination| in |destinations|:
1. [=Assert=]: |destination| is not the [=opaque origin=].