Skip to content

Commit bf20967

Browse files
Add k-anonymity cache (WICG#1005)
* Add k-anonymity cache * Fix missing /div * Fix some other issues * add missing / * fix var names * fix var names again * Address comments * Add , * Address comments * fix build * Address comments * Fix merge issues * Update spec.bs Co-authored-by: Dominic Farolino <[email protected]> * Remove extra assertions about [=in parallel=] --------- Co-authored-by: Dominic Farolino <[email protected]>
1 parent 25066c6 commit bf20967

File tree

1 file changed

+89
-46
lines changed

1 file changed

+89
-46
lines changed

spec.bs

Lines changed: 89 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ This is detectable because it can change the set of fields that are read from th
457457
the current day in UTC, increment its count. If not, [=list/insert=] a new [=tuple=]
458458
the time set to the current UTC day and a count of 1.
459459
1. Store |interestGroup| in the [=user agent=]'s [=interest group set=].
460+
1. Run [=update k-anonymity cache for interest group=] for |interestGroup|.
460461
1. Return |p|.
461462

462463
</div>
@@ -1873,16 +1874,16 @@ To <dfn>generate and score bids</dfn> given an [=auction config=] |auctionConfig
18731874
1. If |originalAds| is not null:
18741875
1. Set |ig|'s [=interest group/ads=] to a new [=list=] of [=interest group ad=].
18751876
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=].
18791880
1. Let |originalAdComponents| be |ig|'s [=interest group/ad components=].
18801881
1. If |originalAdComponents| is not null:
18811882
1. Set |ig|'s [=interest group/ad components=] to a new [=list=] of [=interest group ad=].
18821883
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=].
18861887
1. If |perBuyerCumulativeTimeout| is not null and is &lt; |perBuyerTimeout|, then set
18871888
|perBuyerTimeout| to |perBuyerCumulativeTimeout|.
18881889
1. Let |generateBidStartTime| be |settings|'s
@@ -3849,70 +3850,80 @@ might choose to require a [=k-anonymity=] threshold of fifty users over a seven
38493850
will maintain the count over the chosen duration and compare the count to the chosen [=k-anonymity=]
38503851
threshold when responding to [=query k-anonymity count=].
38513852

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+
38523859
<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|:
38543861
1. If the [=k-anonymity server=] has recorded at least [=k-anonymity threshold=] users
38553862
seeing |hashCode| over the last [=k-anonymity duration=], return true.
3856-
Otherwise return false.
3863+
Otherwise, return false.
38573864
1. Return true if it is above the threshold, otherwise return false.
38583865
</div>
38593866

38603867
<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>
38683874

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|.
38703883
</div>
38713884

38723885
<div algorithm>
38733886
To <dfn>compute the key hash of reporting ID</dfn> given an [=interest group=] |ig| and an
38743887
[=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):
38763889

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=]
38823895
[=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=]
38863899
[=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|.
38933906
</div>
38943907

38953908
<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:
38983911
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|.
39033914
</div>
39043915

39053916
<div algorithm>
39063917
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.
39093920
1. If |bid|'s [=generated bid/ad component descriptors=] is not null:
39103921
1. [=set/For each=] |adComponentDescriptor| in |bid|'s
39113922
[=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.
39143926
1. Return true.
3915-
39163927
</div>
39173928

39183929
<div algorithm>
@@ -3922,6 +3933,26 @@ threshold when responding to [=query k-anonymity count=].
39223933
1. Return the result of [=query k-anonymity count|querying the k-anonymity count=] given |keyHash|.
39233934
</div>
39243935

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+
39253956
<div algorithm>
39263957
To <dfn>increment k-anonymity count</dfn> given a |hashCode|:
39273958
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
48254856
Note: Implementations can consider loading only a portion of these interest groups
48264857
at a time to avoid issuing too many requests at once.
48274858
1. Let |ig| be a deep copy of |originalInterestGroup|.
4859+
1. Run [=update k-anonymity cache for interest group=] for |ig|.
48284860
1. Let |request| be a new [=request=] with the following properties:
48294861
: [=request/URL=]
48304862
:: |ig|'s [=interest group/update url=]
@@ -6665,10 +6697,8 @@ To <dfn>try to reach component ads target considering k-anonymity</dfn>, given a
66656697
1. Let |selectedComponents| be a new [=list=] of [=ad descriptors=].
66666698
1. [=set/For each=] |i| of [=list/get the indices=] of |generatedBid|:
66676699
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:
66726702
1. [=list/Append=] |candidateComponent| to |selectedComponents|.
66736703
1. Otherwise:
66746704
1. If |i| &lt; |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
70137043
Reports when a latency (e.g., `generateBid()` execution latency) is greater than this threshold.
70147044
</dl>
70157045

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+
70167059
# Privacy Considerations # {#privacy-considerations}
70177060

70187061
Protected Audience aims to advance the privacy of remarketing and custom audience

0 commit comments

Comments
 (0)