-
Notifications
You must be signed in to change notification settings - Fork 240
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
API changes to make FLEDGE understand ad sizes #417
Conversation
FLEDGE.md
Outdated
* render: A dictionary describing the creative that should be rendered if this bid wins the auction. This includes: | ||
* url: The creative's URL. | ||
* size: A dictionary containing `width` and `height` fields, describing the creative's size (see the interest group declaration above). | ||
* adComponents: (optional) A list of up to 20 adComponent strings from the InterestGroup's adComponents field. Each value must match an adComponent renderUrl and size exactly. This field must not be present if the InterestGroup has no adComponent field. It is valid for this field not to be present even when adComponents is present. (See ["Ads Composed of Multiple Pieces"](#34-ads-composed-of-multiple-pieces) below.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back to the subject discussed on the Fledge call - https://github.com/WICG/turtledove/blob/main/meetings/2022-11-09-FLEDGE-call-minutes.md and in the github issue - #312 (comment):
to be able to implement carousel (or other type of animation in creative that present single product in two ways) we should define each product twice - which effectively - decrease this constraint to 10.
Could you consider two options:
- increase limit from 20 to 40 ?
- or limit 20 would only verify unique adComponent renderUrls (duplicated urls would be treated as single)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll discuss this and get back to you. From my perspective, the latter option sounds pretty unobjectionable, but I wasn't involved in picking the original max number of components so there might be something I'm missing.
@gtanzer Can you also update the release notes, in particular in which Chrome version this will be available ? |
@fhoering Good catch, updated the release notes. We would like to get these changes in for M111, but nothing is certain yet. |
FLEDGE.md
Outdated
@@ -136,14 +148,18 @@ The `dailyUpdateUrl` provides a mechanism for the group's owner to periodically | |||
|
|||
The `executionMode` attribute is optional. The default value (`"compatibility"`) will run each invocation of `generateBid` in a totally fresh execution environment, which prevents one invocation from directly passing data to a subsequent invocation, but has non-trivial execution costs as each execution environment must be initialized from scratch. The `"groupByOrigin"` mode will attempt to re-use the execution environment for interest groups with the same script that were joined on the same top-level origin, which saves a lot of these initialization costs. However, to avoid cross-site information leaking into `generateBid`, attempts to join or leave an interest group in `"groupByOrigin"` mode from more than one top-level origin will result in all `"groupByOrigin"` interest groups that were joined from the same top-level origin being removed. When the execution environment is re-used the script top-level will not be re-executed, with only the `generateBid` function being run the subsequent times. This mode is intended for interest groups that are extremely likely to be joined or left from a single top-level origin only, with the probability high enough that the penalty of removal if the requirement doesn't hold to be low enough for the performance gains to be a worthwhile trade-off. | |||
|
|||
The `ads` list contains the various ads that the interest group might show. Each entry is an object that includes both a rendering URL and arbitrary metadata that can be used at bidding time. | |||
The `ads` list contains the various ads that the interest group might show. Each entry is an object that includes a rendering URL, a named size group (see below), and arbitrary metadata that can be used at bidding time. These render URLs may contain macros `{%AD_WIDTH%}` and `{%AD_HEIGHT%}`, which will be automatically replaced with the appropriate width and height after an auction, so that the initial resource request can fetch appropriately sized assets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the concept of the size in the proposed change have a material impact on the behavior of the FLEDGE auction other than the substitution of macros in render URLs, and a K-anonymity check during the auction and reporting time?
That is, is there anything specific about the concept of a size that makes it worthwhile to have distinct size (comprised of width, height) semantics in the API? Does the concept of size introduced in the API impact (or need to impact) how a browser renders the winning ad?
A potential alternative would be a more generic concept of a "named creative variant" – that also can participate in a render URL macro substitution, as well as the K-anonymity checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the size returned from generateBid determines the size of the ad creative when it is loaded into a fenced frame from the ad creative's perspective, and the requestedSize passed into runAdAuction determines the size of the fenced frame from the embedder's perspective (unless overridden on the HTML element attributes). So the API does need to understand the width/height semantics. I thought I mentioned this but it looks like I forgot it when adapting the earlier proposal writeup. I'll fix it; thanks for noticing.
Are there any particular use cases for a "named creative variant" that you have in mind? We've previously talked about how fenced frames could support flexible sets of permissions (which would also need the API to have special understanding), and are thinking about how we might be able to handle things like native ads (which could pass an unstructured collection of information that the API doesn't need to understand, like you suggest).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any particular use cases for a "named creative variant" that you have in mind?
Didn't have immediate use cases in mind when I wrote this originally; perhaps, one could think about styling variants – background/highlight colors, fonts and text size, etc., while advertising essentially the same exact good or service, with styling depending on the publisher page context.
The reason I brought this up is to test whether the API complexity around an explicit concept of sizes is worth it, or whether some more general concept would suffice.
unless overridden on the HTML element attributes
It seems, then, that the embedder already has the ability to control the rendering size via FF attributes – andrequestedSize
would simply be an additional mechanism that does the same, not net new functionality, correct?
size returned from generateBid determines the size of the ad creative when it is loaded into a fenced frame from the ad creative's perspective
Does that impact rendering by the browser in some way? If so, how?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then in brief yes, it is necessary to have an explicit concept of sizes because it exists at the boundary between the embedder and the fenced frame content. For styling (this is what I meant by native ads), the fenced frame wouldn't need any understanding because the changes would be strictly inside the fenced frame content in JS, so the API could be more generic.
We are definitely still looking for ways to simplify the API while making it more flexible (in the long term). The main motivation for the k-anon check on sizes is to mitigate potential leaks from the network side channel in fenced frames, so if/when we can find a different solution there, we would likely be able to make this more generic/flexible (because there would be less concern about information flowing into the fenced frame).
It seems, then, that the embedder already has the ability to control the rendering size via FF attributes – and requestedSize would simply be an additional mechanism that does the same, not net new functionality, correct?
Correct, that's why it's forever-optional (not just opt-in for a transition period). But we figure that the publisher is probably telling the auction what size the ad slot is anyway, so they might as well use this field and avoid having to specify it again later in the HTML element attributes.
Does that impact rendering by the browser in some way? If so, how?
This is the browser's source of information for the size of the fenced frame's "inner frame" (i.e. the size of the content). In the old design, when you load a urn into a fenced frame, it freezes the size of the inner frame based on the size at the time of navigation (subject to an allow list), which causes all sorts of problems (privacy, but also performance because layout is asynchronous). In this new design, that frozen size comes synchronously from the urn/config instead.
FLEDGE.md
Outdated
The `adComponents` field contains the various ad components (or "products") that can be used to construct ["Ads Composed of Multiple Pieces"](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#34-ads-composed-of-multiple-pieces)). Similarly to the `ads` field, each entry is an object that includes both a rendering URL and arbitrary metadata that can be used at bidding time. Thanks to `ads` and `adsComponents` being separate fields, the buyer is able to update the `ads` field via daily update without losing `adComponents` stored in the interest group. | ||
The `adComponents` field contains the various ad components (or "products") that can be used to construct ["Ads Composed of Multiple Pieces"](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#34-ads-composed-of-multiple-pieces)). Similarly to the `ads` field, each entry is an object that includes a rendering URL, a named size group (see below), and arbitrary metadata that can be used at bidding time. Thanks to `ads` and `adsComponents` being separate fields, the buyer is able to update the `ads` field via daily update without losing `adComponents` stored in the interest group. | ||
|
||
The `adSizes` field contains a dictionary of named ad sizes. Each size has the format `{width: widthVal, height: heightVal}`, where the values can have either pixel units (e.g. `100` or `'100px'`) or screen dimension coordinates (e.g. `100sw` or `100sh`). For example, the size `{width: '100sw', height: 50}` describes an ad that is the width of the screen and 50 pixels tall. The size `{width: '100sw', height: '200sw'}` describes an ad that is the width of the screen and has a 1:2 aspect ratio. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful to describe more explicitly how these sizes would be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some description of this immediately below, namely:
- They're used to prefetch k-anonymity checks
- When an ad with one of these sizes wins an auction, the size is substituted into URL macros
- When the ad is loaded into a fenced frame, the browser freezes the fenced frame's inner dimensions to this size
FLEDGE.md
Outdated
|
||
The `adSizes` field contains a dictionary of named ad sizes. Each size has the format `{width: widthVal, height: heightVal}`, where the values can have either pixel units (e.g. `100` or `'100px'`) or screen dimension coordinates (e.g. `100sw` or `100sh`). For example, the size `{width: '100sw', height: 50}` describes an ad that is the width of the screen and 50 pixels tall. The size `{width: '100sw', height: '200sw'}` describes an ad that is the width of the screen and has a 1:2 aspect ratio. | ||
|
||
The `sizeGroups` field contains a dictionary of named lists of ad sizes. Each ad declared above must specify a size group, saying which sizes it might be loaded at (for filtering during the auction and k-anonymity checks). Each named ad size is also considered a size group, so you don't need to manually define singleton size groups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we clarify what filtering during the auction is being referred to here – and who (a browser, a buyer, or a seller) would be responsible for such filtering?
Below, it is mentioned that
optional
requestedSize
field recommends a frame size for the auction
and
Bidders inside the auction may pick a different size, but that resulting size will be scaled to fit inside the requested size.
This seems to imply that the browser would not be performing such filtering, and a seller and/or a buyer may choose – but do not have to – perform such filtering. Is that correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We haven't decided/specified what kind of filtering might happen yet. I meant that in the future, if there is demand for it, we could add the sizes to interest group filtering to help avoid unnecessary bidders. It's possible that you could fit that into the filtering framework already though; I'm not familiar with the details. I'll just delete this mention of filtering.
Hi @gtanzer, |
@michal-kalisz We're targeting M112 for it now. Everything will be fully backwards compatible for a while. In order to opt into the changes, you will have to declare ad sizes in the interest group, pick one of those sizes in generateBid, opt into resolving the auction to a FencedFrameConfig rather than a urn (for now at least, for implementation reasons), and then load that config into a fenced frame (rather than a urn iframe). If any of those aspects aren't present, it will default to the old behavior. But if you do opt in, you get size macro substitution and no size allowlist sooner. In the meantime, if you're interested in size macro substitution to avoid round trip latency, you can replicate it with deprecatedReplaceInURN. But that is obviously deprecated and will go away at some point (not sure exactly when). |
This CL adds 2 new size-related fields to joinAdInterestGroup: - adSizes: a dictionary that maps size names to a dictionary containing a width and height string. The width and height are expected to be in the format "##units". Acceptable values include "10px" and "200sw". The values must be > 0. Disallowed values include "-20px" and "0sw". - sizeGroups: a dictionary that maps group names to a list of size names This adds database support for this fields as well as parsing the fields and passing them over mojo. Right now, the field has no effect when running auctions. See Turtledove issue: WICG/turtledove#312 See Turtledove PR: WICG/turtledove#417 Fuchsia-Binary-Size: Size increase is unavoidable due to new Mojo types. Binary-Size: Size increase is unavoidable due to new Mojo types. Change-Id: I32f1fbb11988793172e7dbbbc50fbd9f86827ab3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4167800 Reviewed-by: Daniel Cheng <[email protected]> Reviewed-by: Russ Hamilton <[email protected]> Reviewed-by: Caleb Raitto <[email protected]> Commit-Queue: Liam Brady <[email protected]> Cr-Commit-Position: refs/heads/main@{#1101466}
@gtanzer thank you! |
M112 is in canary now. Has that referenced commit hit canary?
Would you kindly please clarify c & d? |
When I said M112, I meant branch cut for M112, i.e. Feb 23. Thanks for clarifying.
I'm actually not sure that we've documented c yet. It's with reference to these changes to fenced frames: WICG/fenced-frame#56 There is an optional field in the auction config, With respect to d: you can load urns in iframes rather than fenced frames, and iframes don't have any size restrictions, so the size allowlist doesn't apply: it's only relevant for fenced frames. I misspoke about size macro substitution: that will still work with urn iframes. |
This CL is a first step to add size fields to the return value of generateBid(). In https://crrev.com/c/4167800, blink::InterestGroup::Size is introduced for adding sizes to joinAdInterestGroup(). It is declared as a nested struct inside blink::InterestGroup. When working on adding size fields to the return value of generateBid(), we should reuse this Size struct, instead of creating a new one, for BidderWorkletBid. The way it being declared as a nested struct have a few drawbacks: 1. This struct seems to serve InterestGroup only at first glance, but it will be used to represent general size info for various FLEDGE APIs soon: runAdAuction(), scoreAd(), reportResult() and reportWin(). 2. Clients that only need the size struct's declaration must include interest_group.h entirely. 3. Cannot be forward declared. This CL decouples the nested blink::InterestGroup::Size, to a standalone struct blink::AdSize. Some minor notes: 1. Update Size's operator== to compare units as well. 2. Although the struct traits for Size was defined in the related CL, the type was not mapped because no mapping was specified the BUILD.gn. This CL added the type mapping. This will later be used in the follow-up CL on generateBid(). 3. Added unit tests for Size. See Turtledove issue: WICG/turtledove#312 See Turtledove PR: WICG/turtledove#417 Bug: http://b/239866637 Related CL on adding sizes to joinAdInterestGroup(): https://crrev.com/c/4167800 Change-Id: I4a4dd47607102599bbeb33d05aa1ca5e6928ec5b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296777 Commit-Queue: Xiaochen Zhou <[email protected]> Reviewed-by: Dominic Farolino <[email protected]> Reviewed-by: Russ Hamilton <[email protected]> Reviewed-by: Garrett Tanzer <[email protected]> Reviewed-by: Daniel Cheng <[email protected]> Cr-Commit-Position: refs/heads/main@{#1112228}
Co-authored-by: Paul Jensen <[email protected]>
@@ -297,6 +316,8 @@ else | |||
|
|||
This will cause the browser to execute the appropriate bidding and auction logic inside a collection of dedicated worklets associated with the buyer and seller domains. The `auctionSignals`, `sellerSignals`, and `perBuyerSignals` values will be passed as arguments to the appropriate functions that run inside those worklets — the `auctionSignals` are made available to everyone, while the other signals are given only to one party. | |||
|
|||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So one of the results of using this in a FF will be that the ff.width and ff.height will implicitly be set to the requestedSize w/h. Will the same be true in iframes using the opaque URN? We generally seem to be keeping the same API, want to confirm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also w/r/t:
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.
Is the theory that the API should allow this, but the seller can disallow it as a business choice via scoreAd?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, iframes with opaque urns don't respect respectedSize (or renderSize); they don't have any of the size restrictions that fenced frames do. In that case the only useful thing is the ability to macro renderSize into the ad creative url. But for now you could do that with deprecatedReplaceInURN.
And yes, the seller can disallow it if they want. It seems like you'd only want to do it as a fallback, since visual scaling obviously is unideal.
* bid: A numerical bid that will enter the auction. The seller must be in a position to compare bids from different buyers, therefore bids must be in some seller-chosen unit (e.g. "USD per thousand"). If the bid is zero or negative, then this interest group will not participate in the seller's auction at all. With this mechanism, the buyer can implement any advertiser rules for where their ads may or may not appear. While this returned value is expected to be a JavaScript Number, internal calculations dealing with currencies should be done with integer math that more accurately represent powers of ten. | ||
* render: A dictionary describing the creative that should be rendered if this bid wins the auction. This includes: | ||
* url: The creative's URL. | ||
* size: A dictionary containing `width` and `height` fields, describing the creative's size (see the interest group declaration above). When the ad is loaded in a fenced frame, the fenced frame's inner frame (i.e. the size visible to the ad creative) will be frozen to this size, and it will be unable to see changes to the frame size made by the embedder. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the "inner frame size" here referring to the same thing as:
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.
in the above section on requestSize?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the inner frame size is the size seen by the ad creative, which is determined by the bidder. The container size is the size seen by the embedder, determined by the embedder (no size information is returned from the auction API call).
@@ -732,7 +760,7 @@ The arguments to this function are: | |||
* sellerSignals: Like auctionConfig.sellerSignals, but passed via the [directFromSellerSignals](#25-additional-trusted-signals-directfromsellersignals) mechanism. These are the signals whose subresource URL ends in `?sellerSignals`. | |||
* auctionSignals: Like auctionConfig.auctionSignals, but passed via the [directFromSellerSignals](#25-additional-trusted-signals-directfromsellersignals) mechanism. These are the signals whose subresource URL ends in `?auctionSignals`. | |||
|
|||
The `browserSignals` argument must be handled carefully to avoid tracking. It certainly cannot include anything like the full list of interest groups, which would be too identifiable as a tracking signal. The `renderURL` can be included since it has already passed a k-anonymity check. The browser may limit the precision of the bid and desirability values by stochastically rounding them so that they fit into a floating point number with an 8 bit mantissa and 8 bit exponent to avoid these numbers exfiltrating information from the interest group's `userBiddingSignals`. On the upside, this set of signals can be expanded to include useful additional summary data about the wider range of bids that participated in the auction, e.g. the number of bids. Additionally, the `dataVersion` will only be present if the `Data-Version` header was provided in the response headers from the Trusted Scoring server. | |||
The `browserSignals` argument must be handled carefully to avoid tracking. It certainly cannot include anything like the full list of interest groups, which would be too identifiable as a tracking signal. The `renderURL` can be included since it has passed a k-anonymity check. Because `renderSize` will not be included in the k-anonymity check initially, it is not included in the browser signals. The browser may limit the precision of the bid and desirability values by stochastically rounding them so that they fit into a floating point number with an 8 bit mantissa and 8 bit exponent to avoid these numbers exfiltrating information from the interest group's `userBiddingSignals`. On the upside, this set of signals can be expanded to include useful additional summary data about the wider range of bids that participated in the auction, e.g. the number of bids. Additionally, the `dataVersion` will only be present if the `Data-Version` header was provided in the response headers from the Trusted Scoring server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the idea that it will be included in browserSignals once it's in included in the k tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, then it will be privacy-preserving to do so.
@@ -6,6 +6,16 @@ | |||
|
|||
* Functions that are called from Protected Audience worklets are now only accessible from inside the worklets, not from the global scope. See [#489](https://github.com/WICG/turtledove/issues/489) for more information. | |||
|
|||
## Chrome M114 | |||
|
|||
* Support the ability to specify `requestedSize` in the auction config, which is eventually stored in the winning fenced frame config's container size. The `requestedSize` may not be accessible through browser signals in the auction until M116, and is a lower priority because it is a convenience feature only (presumably the size of the ad slot is already passed in through other signals, if it is needed). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thiiiink there might be a need for some disambiguation here.
- The
requestedSize
is anauctionConfig
feature known to the publisher at auction time. - The
renderSize
is the size of the creative from the IG, and can be different than therequestedSize
. requestedSize
of the auction can get into the reporting functions through auction config and/or auction signals.renderSize
of the chosen creative would need to get in throughbrowserSignals
.
Is the intention here to say that as of 116 the renderSize
will be included in the k-anon check and therefore passed into reportResult
and reportWin
through the browserSignals
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not entirely sure what it means if different component auctions have different requestedSize
values w.r.t the top-level seller auction; in the expected PBJS workflow, the top-level auction config isn't known in advance, nor configured by the publisher; so what's the responsibility of the top-level seller in terms of handling different sizes coming back from component auctions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"that as of 116 the renderSize will be included in the k-anon check"
No, the size being included in the k-anon check will come later (and then yes, renderSize can be in the browser signals).
We just hadn't implemented requestedSize in browser signals until M116, no relation to k-anon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rdgordon-index I'm not sure how the top-level auction config wouldn't know the size of the ad; the caller needs to know how big to make the ad, right? (and doesn't get anything returned from the auction to indicate this) This is probably related to the other issue about lack of multi-size auctions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking about the expected PBJS integration -- where the sellers are responsible for the component auction configs, but GAM (via GPT) is responsible for building the top-level seller auction config thereafter; so it's the order-of-operations that makes this somewhat confusing if not all sellers (component or top-level) interpret the size array of a GPT slot in the same fashion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#908 talks about this as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Alonso Velasquez <[email protected]>
Co-authored-by: Alonso Velasquez <[email protected]>
SHA: 50ff31a Reason: push, by JensenPaul Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR integrates the proposal described in #312 (comment) .