Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional slot-size parameters to trustedBiddingSignalsURL requests #928

Merged
merged 16 commits into from
Jan 5, 2024
20 changes: 12 additions & 8 deletions FLEDGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const myGroup = {
'executionMode': ...,
'trustedBiddingSignalsURL': ...,
'trustedBiddingSignalsKeys': ['key1', 'key2'],
'trustedBiddingSignalsSlotSizeMode' : 'slot-size',
MattMenke2 marked this conversation as resolved.
Show resolved Hide resolved
'userBiddingSignals': {...},
'ads': [{renderUrl: shoesAd1, sizeGroup: 'group1', ...},
{renderUrl: shoesAd2, sizeGroup: 'group2', ...},
Expand All @@ -130,10 +131,10 @@ const myGroup = {
{renderUrl: gymShoes, sizeGroup; 'group2', ...},
{renderUrl: gymTrainers1, sizeGroup: 'size4', ...},
{renderUrl: gymTrainers2, sizeGroup: 'size4', ...}],
'adSizes': {'size1': {width: width1, height: height1},
'size2': {width: width2, height: height2},
'size3': {width: width3, height: height3},
'size4': {width: width4, height: height4}},
'adSizes': {'size1': {width: 'width1', height: 'height1'},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other size as string thing typos...

Each size has the format {width: widthVal, height: heightVal},
pixel units (e.g. 100 or '100px')
{width: '100sw', height: 50}

Thanks for the reminder re. normalized:

Sizes are strings with case suffixes, and parsing rules I haven't fully grokked yet. If this allows multiple variants of the same value (e.g., "100 PX", "100px", I don't think we want to preserve the exact details of how the string was formatted, to minimize side channels, and URL variation based on who created the AuctionConfig.

Quesitons, perhaps OT from the TBSU parameter, but adjacent...

  • is leading/trailing whitespace removed from sizes (or sizegroup names)
  • what happens when encountering a negative width/height
  • what happens when encountering an unknown width/height suffix ('px,sw,sh')
  • what happens when encountering an inappropriate width or height suffix ('sw,sh')

And specific to the TBSU parameter,

  • pixels are the default (values without suffix are pixels). So will any values specifying px/PX be normalized (either internally [shaves storage bytes]) or in the TBSU param to remove the 'px'?

Copy link
Contributor Author

@MattMenke2 MattMenke2 Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I'm looking at the regexp our size parser uses, and it looks pretty rigid: R"(^\s*((?:0|(?:[1-9][0-9]*))(?:.[0-9]+)?)(px|sw|sh)?\s*$)".

Looks like the only thing it allows are leading/trailing whitespace, and trailing zeroes. It's case sensitive, does not allow negatives (though does allow 0), allows no whitespace between units, no unrecognized units (so just px, sw, sh, and empty, which is the same as pixels), no leading zeroes / leading "0x", etc. So I think we'll basically just remove leading/trailing whitespace, and potentially trailing 0's and the decimal if there are only zeroes after it. We basically parse the information we can from the value, store that.

When we want a string, we have to serialize that back to a string. We could remember the original string and what we parse it to, but that seems not great in terms of IG size and extra information leakage.

I think if there's demand for it, we could at least remember the "px" vs empty, though that would require a database format update, and we'd have to force pre-existing IGs into one bucket or the other.

Copy link
Contributor

@dmdabbs dmdabbs Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

does not allow negatives (though does allow 0)

What's the use case for a 0 anything banner dimension?

So I think we'll basically just remove ... and potentially trailing 0's and the decimal if there are only zeroes after it.

No legit/practical use for fractional/decimal pixel-specified banner sizes.

We basically parse the information we can from the value, store that.

So you store the extracted string, then.

No, no demand for anything more. Just wanting to understand how it is parsed / normailzed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not allow negatives (though does allow 0)

What's the use case for a 0 anything banner dimension?

None that I'm aware of - I'm just describing what the existing parser does, at least according to my reading of it. Presumably at some point we'll require it to match a valid ad sizes, or at least silently throw away invalid sizes (for better forward compatibility, if new ad sizes are expected to occasionally be added).

Copy link
Contributor

@dmdabbs dmdabbs Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None that I'm aware of - I'm just describing what the existing parser does, at least according to my reading of it.

Appreciate your readout.

Presumably at some point we'll require it to match a valid ad sizes, or at least silently throw away invalid sizes (for better forward compatibility, if new ad sizes are expected to occasionally be added).

Right. In PA there's no notion of 'globally valid' ad sizes. Sure, IAB has standard banner sizes, but in the spec the IG owner determines their creative assets' sizes. And that's fine, since they could have agreements for non-standard sizes with pubs, or use them in O&O cases, &c.

Want to better understand why the browser should permit a top-level seller to embed a 0-anything or fractional dimension banner. That's OT to this new TBS mode param.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now added a description of the two transformations normalized does.

Looking at the code, we have an IsValidAdSize() method that rejects size 0, but we don't actually seem to call it when parsing ad sizes, so I think 0 is actually not allowed, we're just not disallowing it the way we should be (I think we might currently kill a renderer process if we see it? That's not good - anyhow, I'll work on that).

'size2': {width: 'width2', height: 'height2'},
'size3': {width: 'width3', height: 'height3'},
'size4': {width: 'width4', height: 'height4'}},
'sizeGroups:' {'group1': ['size1', 'size2', 'size3'],
'group2': ['size3', 'size4']},
'auctionServerRequestFlags': ['omit-ads'],
Expand Down Expand Up @@ -313,7 +314,8 @@ const myAuctionConfig = {
'trustedScoringSignalsURL': ...,
'interestGroupBuyers': ['https://www.example-dsp.com', 'https://buyer2.com', ...],
'auctionSignals': {...},
'requestedSize': {width: 100, height: 200},
'requestedSize': {width: '100', height: '200'},
'allSlotsRequestedSizes': [{width: '100', height: '200'}, {width: '200', height: '300'}, ...],
'directFromSellerSignals': 'https://www.example-ssp.com/...',
'sellerSignals': {...},
'sellerTimeout': 100,
Expand Down Expand Up @@ -371,6 +373,8 @@ This will cause the browser to execute the appropriate bidding and auction logic

The optional `requestedSize` field recommends a frame size for the auction, which will be available to bidders in browser signals. This size should be specified in the same format as the sizes in the `adSizes` field of `joinAdInterestGroup`. For convenience, the returned fenced frame config will automatically populate a `<fencedframe>`'s `width` and `height` attributes with the `requestedSize` when loaded, though the element's size attributes can still be modified if you want to change the element's container size. Bidders inside the auction may pick a different content size for the ad, and that resulting size will be visually scaled to fit inside the element's container size.

`allSlotsRequestedSizes` may optionally be used to specify the size of all ad slots on the page, to be passed to each interest group's `trustedBuyerSignalsURL`, for interest groups that request it. All sizes in the list must be distinct.

The optional `directFromSellerSignals` field can also be used to pass signals to the auction, similar to `sellerSignals`, `perBuyerSignals`, and `auctionSignals`. The difference is that `directFromSellerSignals` are trusted to come from the seller because the content loads from a [subresource bundle](https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md) loaded from a seller's origin, ensuring the authenticity and integrity of the signals. For more details, see [2.5 directFromSellerSignals](#25-additional-trusted-signals-directfromsellersignals).

In some cases, multiple SSPs may want to participate in an auction, with the winners of separate auctions being passed up to another auction, run by another SSP. To facilitate these "component auctions", `componentAuctions` can optionally contain additional auction configurations for each seller's "component auction". The winning bid of each of these "component auctions" will be passed to the "top-level" auction. How bids are scored in this case is further described in [2.4 Scoring Bids in Component Auctions](#24-scoring-bids-in-component-auctions). The `AuctionConfig` of component auctions may not have their own `componentAuctions`. When `componentAuctions` is non-empty, `interestGroupBuyers` must be empty. That is, for any particular Protected Audience auction, either there is a single seller and no component auctions, or else all bids come from component auctions and the top-level auction can only choose among the component auctions' winners.
Expand Down Expand Up @@ -589,11 +593,11 @@ Buyers have three basic jobs in the on-device ad auction:
#### 3.1 Fetching Real-Time Data from a Trusted Server


Buyers may want to make on-device decisions that take into account real-time data (for example, the remaining budget of an ad campaign). This need can be met using the interest group's `trustedBiddingSignalsURL` and `trustedBiddingSignalsKeys` fields. Once a seller initiates an on-device auction on a publisher page, the browser checks each participating interest group for these fields, and makes an uncredentialed (cookieless) HTTP fetch to a URL of the form:
Buyers may want to make on-device decisions that take into account real-time data (for example, the remaining budget of an ad campaign). This need can be met using the interest group's `trustedBiddingSignalsURL`, `trustedBiddingSignalsKeys`, and, optionally, `trustedBiddingSignalsSlotSizeMode` fields. Once a seller initiates an on-device auction on a publisher page, the browser checks each participating interest group for these fields, and makes an uncredentialed (cookieless) HTTP fetch to a URL of the form:

https://www.kv-server.example/getvalues?hostname=publisher.com&keys=key1,key2&interestGroupNames=name1,name2&experimentGroupId=12345
https://www.kv-server.example/getvalues?hostname=publisher.com&keys=key1,key2&interestGroupNames=name1,name2&experimentGroupId=12345&slot-size=100,200

The base URL `https://www.kv-server.example/getvalues` comes from the interest group's `trustedBiddingSignalsURL`, the hostname of the top-level webpage where the ad will appear `publisher.com` is provided by the browser, `experimentGroupId` comes from `perBuyerExperimentGroupIds` if provided, `keys` is a list of `trustedBiddingSignalsKeys` strings, and `interestGroupNames` is a list of the names of the interest groups that data is being fetched for. The requests may be coalesced (for efficiency) across any number of interest groups that share a `trustedBiddingSignalsURL` (which means they also share an owner).
The base URL `https://www.kv-server.example/getvalues` comes from the interest group's `trustedBiddingSignalsURL`, the hostname of the top-level webpage where the ad will appear `publisher.com` is provided by the browser, `experimentGroupId` comes from `perBuyerExperimentGroupIds` if provided, `keys` is a list of `trustedBiddingSignalsKeys` strings, and `interestGroupNames` is a list of the names of the interest groups that data is being fetched for. `trustedBiddingSignalsSlotSizeMode` is one of `none` (which is the default), `slot-size`, and `all-slots-requested-sizes`. In the second case, `&slotSize=<width>,<height>` is appended to the URL, where width and height are the normalized width and height from the `requestedSize` of the top-level auction's AuctionConfig. In the `all-slots-requested-sizes` case, `&slotSizes=<width1>,<height1>,<width2>,<height2>,...` is appended, where all sizes are taken from the top-level auction's `allSlotsRequestedSizes` value. If the corresponding value is not present in the top-level auction, no value is appended. The requests may be coalesced (for efficiency) across any number of interest groups that share a `trustedBiddingSignalsURL` and `trustedBiddingSignalsSlotSizeMode` (which means they also share an owner).

The response from the server should be a JSON object of the form:

Expand Down