Skip to content

Commit

Permalink
Merge branch 'main' into comalgo
Browse files Browse the repository at this point in the history
  • Loading branch information
qingxinwu authored Jan 9, 2024
2 parents 507a13d + 2a80ffe commit 6d93eb0
Show file tree
Hide file tree
Showing 22 changed files with 3,520 additions and 760 deletions.
180 changes: 148 additions & 32 deletions FLEDGE.md

Large diffs are not rendered by default.

71 changes: 32 additions & 39 deletions FLEDGE_Key_Value_Server_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,10 @@ provides more context about these namespaces.
The server can be configured to run in slightly different modes depending on
whether it is serving the DSP use case or the SSP use case.

### Subkey
### Hostname

For a given key, a subkey may be used to further specify a dedicated value
override.

During the query, the browser sets the hostname as the subkey value. When a
query to a particular subkey does not match any existing entry, the server
system can automatically fallback to a default value for the key, specified by
not setting the subkey during data updates.
During the query, the browser sets the hostname. This matches the hostname
described in the main explainer.

## Query API Version 1

Expand All @@ -57,16 +52,15 @@ This is the mechanism for the browser client to fetch real-time bidding signals.
The API is called during the ad auction process, as described in the
[FLEDGE explainer](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#31-fetching-real-time-data-from-a-trusted-server).

The returned values are purely dependent on the keys (namespace + key + subkey),
The returned values are purely dependent on the keys (namespace + key + hostname),
except for advanced use cases explicitly agreed upon between browsers and ad
tech platforms. A potential advanced use case being discussed is how to provide
country-level IPGeo information to the bidders. The API provides read-only
access to the key/value data.

As mentioned in the Mutating API section below, possible data staleness may
occur. Different values may be returned for the same keys if reads happen during
data updates, due to the distributed nature of the system. But if the data is
stable, requests are deterministic.
Possible data staleness may occur. Different values may be returned for the
same keys if reads happen during data updates, due to the distributed nature
of the system. But if the data is stable, requests are deterministic.

### Form

Expand All @@ -75,7 +69,7 @@ GET `https://www.kv-server.example/v1/getvalues`
### Examples

```
https://www.dsp-kv-server.example/v1/getvalues?subkey=publisher.com&keys=key1,key2
https://www.dsp-kv-server.example/v1/getvalues?hostname=publisher.com&keys=key1,key2&interestGroupNames=name1,name2
https://www.ssp-kv-server.example/v1/getvalues?renderUrls=url1,url2&adComponentRenderUrls=url3,url4
```

Expand Down Expand Up @@ -137,11 +131,9 @@ https://www.ssp-kv-server.example/v1/getvalues?renderUrls=url1,url2&adComponentR
</td>
</tr>
<tr>
<td>subkey
<td>hostname
</td>
<td>The browser sets the hostname of the publisher page to be the value.
<p>
If no specific value is available in the system for this subkey, a default value will be returned. The default value corresponds to the key when the subkey is not set.
</td>
<td>DSP
</td>
Expand Down Expand Up @@ -365,13 +357,13 @@ If the restrictions are not followed by the client, for example due to misconfig
"type": "object",
"additionalProperties": false,
"properties": {
"context": {
"description": "global context shared by all partitions",
"metadata": {
"description": "global metadata shared by all partitions",
"type": "object",
"additionalProperties": false,
"properties": {
"subkey": {
"description": "Auxiliary key. For Chrome, it is the hostname of the top-level frame calling runAdAuction(). Set if sent to the trusted bidding signals server.",
"hostname": {
"description": "The hostname of the top-level frame calling runAdAuction().",
"type": "string"
}
}
Expand All @@ -389,26 +381,27 @@ If the restrictions are not followed by the client, for example due to misconfig
"description": "Unique id of the partition in this request",
"type": "number"
},
"compressionGroup": {
"compressionGroupId": {
"description": "Unique id of a compression group in this request. Only partitions belonging to the same compression group will be compressed together in the response",
"type": "number"
},
"keyGroups": {
"arguments": {
"type": "array",
"items": {
"description": "All keys from this group share some common attributes",
"description": "One group of keys and common attributes about them",
"type": "object",
"additionalProperties": false,
"properties": {
"tags": {
"description": "List of tags describing this key group's attributes",
"description": "List of tags describing this group's attributes",
"type": "array",
"items": {
"type": "string"
}
},
"keyList": {
"data": {
"type": "array",
"description": "List of keys to get values for",
"items": {
"type": "string"
}
Expand All @@ -419,14 +412,14 @@ If the restrictions are not followed by the client, for example due to misconfig
},
"required": [
"id",
"compressionGroup",
"keyGroups"
"compressionGroupId",
"arguments"
]
}
}
},
"required": [
"context",
"metadata",
"partitions"
]
}
Expand All @@ -436,20 +429,20 @@ Example trusted bidding signals request from Chrome:

```json
{
"context": {
"subkey": "example.com"
"metadata": {
"hostname": "example.com"
},
"partitions": [
{
"id": 0,
"compressionGroup": 0,
"keyGroups": [
"compressionGroupId": 0,
"arguments": [
{
"tags": [
"structured",
"groupNames"
],
"keyList": [
"data": [
"InterestGroup1"
]
},
Expand All @@ -458,7 +451,7 @@ Example trusted bidding signals request from Chrome:
"custom",
"keys"
],
"keyList": [
"data": [
"keyAfromInterestGroup1",
"keyBfromInterestGroup1"
]
Expand All @@ -467,14 +460,14 @@ Example trusted bidding signals request from Chrome:
},
{
"id": 1,
"compressionGroup": 0,
"keyGroups": [
"compressionGroupId": 0,
"arguments": [
{
"tags": [
"structured",
"groupNames"
],
"keyList": [
"data": [
"InterestGroup2",
"InterestGroup3"
]
Expand All @@ -484,7 +477,7 @@ Example trusted bidding signals request from Chrome:
"custom",
"keys"
],
"keyList": [
"data": [
"keyMfromInterestGroup2",
"keyNfromInterestGroup3"
]
Expand Down
5 changes: 5 additions & 0 deletions FLEDGE_browser_bidding_and_auction_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ fetch('https://www.example-ssp.com/auction', { <b>adAuctionHeaders: true</b>,
</pre>
Note that `adAuctionHeaders` only works with HTTPS requests.

Response blobs can also be retrieved using an `iframe` navigation by specifying the `adAuctionHeaders` attribute on the iframe element. As with the Fetch flag, the `adAuctionHeaders` iframe attribute prepares the browser to look for `Ad-Auction-Result` HTTP response headers:
```html
<iframe src="https://www.example-ssp.com/auction" adAuctionHeaders></iframe>
```

For each response blob sent back to the browser, the seller’s server attaches a response header containing the base64url encoded (RFC 4648 section 5) SHA-256 hash of the response blob:

```
Expand Down
29 changes: 16 additions & 13 deletions FLEDGE_extended_PA_reporting.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,30 @@ with an arbitrary `event_key` within `generateBid`, `scoreAd`, `reportWin`, and

### Example 1: Correlating bidding signals with click information.

We consider the scenario where a buyer wants to learn the click through rate of ads when a user has
We consider the scenario where a buyer wants to learn the click-through rate of ads when a user has
been in an interest group for a given time.

The buyer may implement `getImpressionReportBucket()` and `getClickReportBucket()` which map an
interest group and the time the user has spent in that interest group to a 128-bit integer.
To generate the bucket that represent interest group age, the buyer may implement `getImpressionReportBucket()` and `getClickReportBucket()` functions which return buckets that map an interest group and the time the user has spent in that interest group to a 128-bit integer as `BigInt`. The `browserSignals.recency` value inside `generateBid()` specifies the duration in minutes since the user joined the interest group.

The buyer can then do the following during generateBid (when the above information is available)
Once the buckets have been derived, the buyer can call Private Aggregation inside `generateBid()`:

```
function generateBid(interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, browserSignals) {
//
privateAggregation.contributeToHistogramOnEvent(“reserved.win”, {
bucket: getImpressionReportBucket(),
bucket: getImpressionReportBucket(), // 128-bit integer as BigInt
value: 1
});
privateAggregation.contributeToHistogramOnEvent("click", {
bucket: getClickReportBuckets(), // 128-bit integer as BigInt
value: 1
});
}
```

The above logic will trigger a report if the generated bid wins (see
[reserved.win](#reporting-bidding-data-for-wins)). And another one, if the user later clicks on the
winning ad (this needs to be triggered by the fenced frame itself, see
[reportPrivateAggregationEvent](#reporting-bidding-data-associated-with-an-event-in-a-frame). When
the buyer receives an aggregated report they can infer what the click-through-rate (CTR) was for
users on different “interest group age” buckets.
The impression report will be sent if the [`reserved.win`](#reporting-bidding-data-for-wins) event is triggered, which is a reserved event for when the bid wins the auction. The click report will be sent if the `click` event is triggered by the [`window.fence.reportEvent("click")`](#reporting-bidding-data-associated-with-an-event-in-a-frame) call originating from the fenced frame of the ad.

The buyer can then generate the summary report of the impression count and click count to infer the click-through rate of the users in different interest group age buckets.

### Example 2: Getting the average bid gap for an ad.

Expand Down Expand Up @@ -204,6 +201,12 @@ Where `signalBucket` and `signalValue` is a dictionary which consists of:
* 6: indicates seller rejected bid because “Creative Filtered - Language Exclusions”
* 7: indicates seller rejected bid because “Creative Filtered - Category Exclusions”
* 8: indicates seller rejected bid because "Creative Filtered - Did Not Meet The K-anonymity Threshold"
* 9: indicates bid produced by `generateBid()` was rejected because it failed a currency check (e.g. the bid returned by `generateBid()` doesn't match
what's specified by `perBuyerCurrency`)
* 10: indicates bid passed through or altered by `scoreAd()` was rejected
because it failed a currency check (e.g. the bid returned or passed through
by `scoreAd()` in a component auction doesn't match the `sellerCurrency` of
its auction or the `perBuyerCurrency` required by the top-level auction)
* Perhaps other values indicating:
* generateBid() hitting timeout
* The auction was aborted (i.e. calling endAdAuction())
Expand Down Expand Up @@ -294,7 +297,7 @@ const auctionConfig = {

The seller is able to measure the following for each buyer, assuming permission is granted via the indicated `sellerCapabilities` for that seller:
* `interestGroupCount`: The number of the interest groups which could participate in the auction
(i.e. the number of intererest groups on the machine for this buyer -- note the count *isn't* limited by the auction config's `perBuyerGroupLimits`). This requires the `interest-group-counts` `sellerCapabilities` permission.
(i.e. the number of interest groups on the machine for this buyer -- note the count *isn't* limited by the auction config's `perBuyerGroupLimits`). This requires the `interest-group-counts` `sellerCapabilities` permission.
* `bidCount`: The number of valid bids generated by this buyer. This requires the `interest-group-counts` `sellerCapabilities` permission.
* `totalGenerateBidLatency`: The sum of execution time for all generateBids() in milliseconds. This requires the `latency-stats` `sellerCapabilities` permission.
* `totalSignalsFetchLatency`: The total time spent fetching trusted buyer signals in milliseconds. If the interest group didn't fetch any trusted signals, then 0 milliseconds is reported. This requires the `latency-stats` `sellerCapabilities` permission.
Expand Down
10 changes: 8 additions & 2 deletions FLEDGE_k_anonymity_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,14 @@ this, we're exploring options that include having the client request tokens
at a constant rate and discard unused tokens.

`Query` is a read-only API, so it doesn't have the same abuse concerns as
`Join`. We won't require Private State Tokens, or a Google Account, for a browser
to call `Query`.
`Join`. While we will not require Private State Tokens, or a Google Account,
for a browser to call `Query`, the Query Server will take certain measures
against set abuse to prevent the privacy of end users from being
compromised. If the Query Server has evidence indicating that a set is
corrupted and is more likely to leak identifying information about members,
it will report the k-anonymity status of the set to be `false` until the
risk to users' privacy has been addressed.


#### Differential privacy of public data

Expand Down
Loading

0 comments on commit 6d93eb0

Please sign in to comment.