@@ -457,6 +457,7 @@ This is detectable because it can change the set of fields that are read from th
457
457
the current day in UTC, increment its count. If not, [=list/insert=] a new [=tuple=]
458
458
the time set to the current UTC day and a count of 1.
459
459
1. Store |interestGroup| in the [=user agent=] 's [=interest group set=] .
460
+ 1. Run [=update k-anonymity cache for interest group=] for |interestGroup|.
460
461
1. Return |p|.
461
462
462
463
</div>
@@ -1873,16 +1874,16 @@ To <dfn>generate and score bids</dfn> given an [=auction config=] |auctionConfig
1873
1874
1. If |originalAds| is not null:
1874
1875
1. Set |ig|'s [=interest group/ads=] to a new [=list=] of [=interest group ad=] .
1875
1876
1. [=list/For each=] |ad| in |originalAds|:
1876
- 1. If [=query ad k-anonymity count =] given |ig| and |ad|'s
1877
- [=interest group ad/render url =] returns true, [=list/append=] |ad| to |ig|'s
1878
- [=interest group/ads=] .
1877
+ 1. Compute |adHashCode| by getting the result of [=compute the key hash of ad =] given |ig| and |ad|.
1878
+ 1. If [=query k-anonymity cache =] given |adHashCode| returns true,
1879
+ [=list/append=] |ad| to |ig|'s [= interest group/ads=] .
1879
1880
1. Let |originalAdComponents| be |ig|'s [=interest group/ad components=] .
1880
1881
1. If |originalAdComponents| is not null:
1881
1882
1. Set |ig|'s [=interest group/ad components=] to a new [=list=] of [=interest group ad=] .
1882
1883
1. [=list/For each=] |adComponent| in |originalAdComponents|:
1883
- 1. If [=query component ad k-anonymity count =] given |adComponent|'s
1884
- [=interest group ad/render url =] returns true, [=list/append=] |adComponent| to |ig|'s
1885
- [=interest group/ad components=] .
1884
+ 1. Compute |componentAdHashCode| by getting the result of [=compute the key hash of component ad =] given |adComponent|.
1885
+ 1. If [=query k-anonymity cache =] given |componentAdHashCode| returns true,
1886
+ [=list/append=] |adComponent| to |ig|'s [= interest group/ad components=] .
1886
1887
1. If |perBuyerCumulativeTimeout| is not null and is < |perBuyerTimeout|, then set
1887
1888
|perBuyerTimeout| to |perBuyerCumulativeTimeout|.
1888
1889
1. Let |generateBidStartTime| be |settings|'s
@@ -3849,70 +3850,80 @@ might choose to require a [=k-anonymity=] threshold of fifty users over a seven
3849
3850
will maintain the count over the chosen duration and compare the count to the chosen [=k-anonymity=]
3850
3851
threshold when responding to [=query k-anonymity count=] .
3851
3852
3853
+ The [=user agent=] must maintain a <dfn>k-anonymity cache</dfn> as a [=map=] whose [=map/keys=] are
3854
+ [=SHA-256=] hashes of the [=k-anonymity keys=] for all of the [=interest group/ads=] and [=interest group/ad components=]
3855
+ in the [=user agent=] 's [=interest group set=] and whose [=map/values=] are [=k-anonymity records=] .
3856
+ This allows the browser to rerun portions of an auction without incurring the delay (and added side channels)
3857
+ from querying the server during an auction.
3858
+
3852
3859
<div algorithm>
3853
- To <dfn>query k-anonymity count</dfn> given a |hashCode|:
3860
+ To <dfn>query k-anonymity count</dfn> given a [=SHA-256=] |hashCode|:
3854
3861
1. If the [=k-anonymity server=] has recorded at least [=k-anonymity threshold=] users
3855
3862
seeing |hashCode| over the last [=k-anonymity duration=] , return true.
3856
- Otherwise return false.
3863
+ Otherwise, return false.
3857
3864
1. Return true if it is above the threshold, otherwise return false.
3858
3865
</div>
3859
3866
3860
3867
<div algorithm>
3861
- To <dfn>query ad k-anonymity count</dfn> given an [=interest group=] |ig| and a [=URL=] |ad|:
3862
- 1. Let |keyString| be the [=string/concatenation=] of the following strings separated with U+000A LF:
3863
- 1. "AdBid"
3864
- 1. the [=serialization of an origin|serialization=] of |ig|'s [=interest group/owner=]
3865
- 1. the [=URL serializer|serialization=] of |ig|'s [=interest group/bidding url=]
3866
- 1. the [=URL serializer|serialization=] of |ad|.
3867
- 1. Let |keyHash| be the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3868
+ To <dfn>query k-anonymity cache</dfn> given a [=SHA-256=] |hashCode|:
3869
+ 1. If the [=user agent=] 's [=k-anonymity cache=] does not [=map/contain=] |hashCode|, then return false.
3870
+ 1. Let |record| be the [=user agent=] 's [=k-anonymity cache=] [|hashCode|] .
3871
+ 1. If the difference between [=current wall time=] and |record|'s [=k-anonymity record/timestamp=] is more than 7 days then return false.
3872
+ 1. Return |record|'s [=k-anonymity record/is k-anonymous=] .
3873
+ </div>
3868
3874
3869
- 1. Return the result of [=query k-anonymity count|querying the k-anonymity count=] given |keyHash|.
3875
+ <div algorithm>
3876
+ To <dfn>compute the key hash of ad</dfn> given an [=interest group=] |ig| and an [=interest group ad=] |igAd|:
3877
+ 1. Let |keyString| be the [=k-anonymity key=] formed from the [=string/concatenation=] of the following strings separated with U+000A LF:
3878
+ * "AdBid"
3879
+ * the [=serialization of an origin|serialization=] of |ig|'s [=interest group/owner=]
3880
+ * the [=URL serializer|serialization=] of |ig|'s [=interest group/bidding url=]
3881
+ * the [=URL serializer|serialization=] of |igAd|'s [=interest group ad/render url=] .
3882
+ 1. Return the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3870
3883
</div>
3871
3884
3872
3885
<div algorithm>
3873
3886
To <dfn>compute the key hash of reporting ID</dfn> given an [=interest group=] |ig| and an
3874
3887
[=interest group ad=] |igAd|:
3875
- 1. Let |keyString| be the [=string/concatenation=] of the following strings separated with U+000A (LF):
3888
+ 1. Let |keyString| be a [=k-anonymity key=] formed from the [=string/concatenation=] of the following strings separated with U+000A (LF):
3876
3889
3877
- 1. "NameReport"
3878
- 1. the [=serialization of an origin|serialization=] of |ig|'s [=interest group/owner=]
3879
- 1. the [=URL serializer|serialization=] of |ig|'s [=interest group/bidding url=]
3880
- 1. the [=URL serializer|serialization=] of |igAd|'s [=interest group ad/render url=]
3881
- 1. If |igAd|'s [=interest group ad/buyer and seller reporting ID=]
3890
+ * "NameReport"
3891
+ * the [=serialization of an origin|serialization=] of |ig|'s [=interest group/owner=]
3892
+ * the [=URL serializer|serialization=] of |ig|'s [=interest group/bidding url=]
3893
+ * the [=URL serializer|serialization=] of |igAd|'s [=interest group ad/render url=]
3894
+ * If |igAd|'s [=interest group ad/buyer and seller reporting ID=]
3882
3895
[=map/exists=] :
3883
- 1. "BuyerAndSellerReportingId"
3884
- 1. |igAd|'s [=interest group ad/buyer and seller reporting ID=]
3885
- 1. Otherwise, if |igAd|'s [=interest group ad/buyer reporting ID=]
3896
+ * "BuyerAndSellerReportingId"
3897
+ * |igAd|'s [=interest group ad/buyer and seller reporting ID=]
3898
+ * Otherwise, if |igAd|'s [=interest group ad/buyer reporting ID=]
3886
3899
[=map/exists=] :
3887
- 1. "BuyerReportingId"
3888
- 1. |igAd|'s [=interest group ad/buyer reporting ID=]
3889
- 1. Otherwise:
3890
- 1. "IgName"
3891
- 1. |ig|'s [=interest group/name=] .
3892
- 1. Return the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3900
+ * "BuyerReportingId"
3901
+ * |igAd|'s [=interest group ad/buyer reporting ID=]
3902
+ * Otherwise:
3903
+ * "IgName"
3904
+ * |ig|'s [=interest group/name=] .
3905
+ 1. Return the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3893
3906
</div>
3894
3907
3895
3908
<div algorithm>
3896
- To <dfn>query component ad k-anonymity count </dfn> given a [=URL =] |ad |:
3897
- 1. Let |keyString| be the [=string/concatenation=] of the following strings separated with U+000A LF:
3909
+ To <dfn>compute the key hash of component ad </dfn> given an [=interest group ad =] |igAd |:
3910
+ 1. Let |keyString| be the [=string/concatenation=] of the following strings separated with U+000A LF:
3898
3911
1. "ComponentBid"
3899
- 1. the [=URL serializer|serialization=] of |ad|.
3900
- 1. Let |keyHash| be the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3901
-
3902
- 1. Return the result of [=query k-anonymity count|querying the k-anonymity count=] given |keyHash|.
3912
+ 1. the [=URL serializer|serialization=] of |igAd|.
3913
+ 1. Return the [=SHA-256=] hash of the [=ASCII encoding=] of |keyString|.
3903
3914
</div>
3904
3915
3905
3916
<div algorithm>
3906
3917
To <dfn>query generated bid k-anonymity count</dfn> given a [=generated bid=] |bid|:
3907
- 1. If [=query ad k-anonymity count=] given |bid|'s [=generated bid/ad descriptor=]' s
3908
- [=ad descriptor/url=] returns false, return false.
3918
+ 1. Compute the |adHashCode| following [=compute the key hash of ad=] with the |bid| 's [=generated bid/interest group=] and |bid|' s [=generated bid/ad descriptor=] .
3919
+ 1. If [=query k-anonymity cache=] for |adHashCode| returns false, return false.
3909
3920
1. If |bid|'s [=generated bid/ad component descriptors=] is not null:
3910
3921
1. [=set/For each=] |adComponentDescriptor| in |bid|'s
3911
3922
[=generated bid/ad component descriptors=] :
3912
- 1. If [=query component ad k-anonymity count=] given |adComponentDescriptor|'s
3913
- [=ad descriptor/url=] returns false, return false.
3923
+ 1. Compute the |componentAdHashCode| by getting the result of [=compute the key hash of component ad=] with |adComponentDescriptor|'s
3924
+ [=ad descriptor/url=] .
3925
+ 1. If [=query k-anonymity cache=] for |componentAdHashCode| returns false, return false.
3914
3926
1. Return true.
3915
-
3916
3927
</div>
3917
3928
3918
3929
<div algorithm>
@@ -3922,6 +3933,26 @@ threshold when responding to [=query k-anonymity count=].
3922
3933
1. Return the result of [=query k-anonymity count|querying the k-anonymity count=] given |keyHash|.
3923
3934
</div>
3924
3935
3936
+ <div algorithm>
3937
+ To <dfn>update k-anonymity cache for key</dfn> given a [=SHA-256=] |hashCode|:
3938
+ 1. Let |record| be a new [=k-anonymity record=] .
3939
+ 1. Set |record|'s [=k-anonymity record/timestamp=] field to the [=current wall time=] .
3940
+ 1. Set |record|'s [=k-anonymity record/is k-anonymous=] field to the result of executing [=query k-anonymity count=] for |hashCode|.
3941
+ 1. [=map/Set=] |record|[|hashCode|] to |record|.
3942
+ </div>
3943
+
3944
+ <div algorithm>
3945
+ To <dfn>update k-anonymity cache for interest group</dfn> given an [=interest group=] |ig|:
3946
+ 1. [=list/For each=] |igAd| of |ig|'s [=interest group/ads=] :
3947
+ 1. Compute the |adHashCode| following [=compute the key hash of ad=] for |ig| and |igAd|.
3948
+ 1. Run [=update k-anonymity cache for key=] on |adHashCode|.
3949
+ 1. Compute the |adReportingHashCode| following [=compute the key hash of reporting ID=] .
3950
+ 1. Run [=update k-anonymity cache for key=] on |adReportingHashCode|.
3951
+ 1. [=list/For each=] |componentAd| of |ig|'s [=interest group/ad components=] :
3952
+ 1. Compute the |componentAdHashCode| following [=compute the key hash of component ad=] for |componentAd|.
3953
+ 1. Run [=update k-anonymity cache for key=] on |componentAdHashCode|.
3954
+ </div>
3955
+
3925
3956
<div algorithm>
3926
3957
To <dfn>increment k-anonymity count</dfn> given a |hashCode|:
3927
3958
1. Ask the [=k-anonymity server=] to record that this [=user agent=] has seen |hashCode|.
@@ -4825,6 +4856,7 @@ navigating to another page. Some implementations, such as Chromium, have chosen
4825
4856
Note: Implementations can consider loading only a portion of these interest groups
4826
4857
at a time to avoid issuing too many requests at once.
4827
4858
1. Let |ig| be a deep copy of |originalInterestGroup|.
4859
+ 1. Run [=update k-anonymity cache for interest group=] for |ig|.
4828
4860
1. Let |request| be a new [=request=] with the following properties:
4829
4861
: [=request/URL=]
4830
4862
:: |ig|'s [=interest group/update url=]
@@ -6665,10 +6697,8 @@ To <dfn>try to reach component ads target considering k-anonymity</dfn>, given a
6665
6697
1. Let |selectedComponents| be a new [=list=] of [=ad descriptors=] .
6666
6698
1. [=set/For each=] |i| of [=list/get the indices=] of |generatedBid|:
6667
6699
1. Let |candidateComponent| be |generatedBid|'s [=generated bid/ad component descriptors=] [|i|] .
6668
- 1. If [=query component ad k-anonymity count=] given |candidateComponent|'s [=interest group ad/render url=] returns true:
6669
-
6670
- Issue: TODO: change to query k-anonymity cache instead.
6671
- (<a href="https://github.com/WICG/turtledove/issues/1150">WICG/turtledove#1150</a> )
6700
+ 1. Compute |componentAdHashCode| by getting the result of [=compute the key hash of component ad=] given |candidateComponent|'s [=interest group ad/render url=] .
6701
+ 1. If [=query k-anonymity cache=] given |componentAdHashCode| returns true:
6672
6702
1. [=list/Append=] |candidateComponent| to |selectedComponents|.
6673
6703
1. Otherwise:
6674
6704
1. If |i| < |generatedBid|'s [=generated bid/number of mandatory ad components=] , return false.
@@ -7013,6 +7043,19 @@ A <dfn>real time reporting contribution</dfn> is a [=struct=] with the following
7013
7043
Reports when a latency (e.g., `generateBid()` execution latency) is greater than this threshold.
7014
7044
</dl>
7015
7045
7046
+ <h3 id=k-anonymity-records>K-Anonymity Records</h3>
7047
+ A <dfn>k-anonymity key</dfn> is a [=string=] used as a key for tracking k-anonymity status.
7048
+
7049
+ A <dfn>k-anonymity record</dfn> is a timestamped cache of the k-anonymity status
7050
+ for a given [=k-anonymity key=] . These records are stored in the [=user agent=] .
7051
+
7052
+ <dl dfn-for="k-anonymity record">
7053
+ : <dfn>is k-anonymous</dfn>
7054
+ :: A {{boolean}} indicating whether the [=k-anonymity key=] indicated by this record was reported as k-anonymous.
7055
+ : <dfn>timestamp</dfn>
7056
+ :: The [=moment=] when the k-anonymity status in this record was last fetched.
7057
+ </dl>
7058
+
7016
7059
# Privacy Considerations # {#privacy-considerations}
7017
7060
7018
7061
Protected Audience aims to advance the privacy of remarketing and custom audience
0 commit comments