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

Creative pre-registration strategies #792

Open
rdgordon-index opened this issue Sep 11, 2023 · 58 comments
Open

Creative pre-registration strategies #792

rdgordon-index opened this issue Sep 11, 2023 · 58 comments

Comments

@rdgordon-index
Copy link
Contributor

As suggested in the explainer, sellers have the ability to fetch additional real-time signals based on a combination of renderURL and hostname (representing the publisher’s domain) that can be used during scoreAd() when scoring creatives. Specifically:

Similarly, sellers may want to fetch information about a specific creative, e.g. the results of some out-of-band ad scanning system

Checking whether the creative contents have been pre-approved by the seller. This could be implemented by an out-of-band creative review process…

In today’s programmatic ecosystem, buyers communicate their creative markup via the bid.adm during RTB, alongside other key bid metadata (advertiser domain, seat ID, IAB category, creative format, creative & campaign identifiers, etc.); however, no creative URL (aka renderURL) containing the markup is provided. As a result, there is no existing mechanism by which SSPs can obtain this URL for all existing creatives submitted in contextual auctions.

This necessarily means that all existing creatives are unable to be served in PA auctions, since creatives have to be pre-approved in order to be scored with a desirability > 0. Otherwise, the rejectReason for all PA creatives returned by scoreAd() would be pending-approval-by-exchange.

This also necessitates a mechanism to initiate such PA creative registration via renderURL, which poses some challenges, as outlined below.

The most naïve such mechanism, available today, would leverage the forDebuggingOnly.reportAdAuctionLoss() endpoint – that is, for any renderURL not found in the seller’s K/V server, initiate an API call to a seller endpoint to indicate that said renderURL has not yet been approved. According to #632 (comment), this function will be available until the end of 3PCD, and should suffice for short-term testing as well as during the 1% 3PCD time horizon.

Challenges with this approach:

  • A significant volume of unregistered created API calls from each device, for each such creative submitted via generateBid()

  • the K/V call doesn’t include a buyer origin - and the renderURL need not utilize the buyer origin – so there is no guaranteed way to map a URL to a given buyer (aka DSP)

  • Other key signals available in OpenRTB – such as adomain and seat – are not guaranteed to be made available to scoreAd() (and hence able to be passed into this debugging endpoint), despite them being required for creative registration. As quoted here

    The metadata accompanying the returned ad is not specified in this document, because sellers and buyers are free to establish whatever protocols they want here.

    As such, without an IAB standard for parameters like seat in renderURL, it’s unclear how buyers will be able to ensure that their creatives are being registered for all sellers.

Another alternative approach would be to somehow leverage the Private Aggregation API, but this shares all of the challenges above, as well as it being unclear how to bucket the fields required for registration (e.g. renderURL, seat, adomain). Furthermore, this also requires the immediate adoption of this API (and its requirement for TEE) in order to be able to start registering creatives, and as such, this does not seem like a short-term solution.

@MattMenke2
Copy link
Contributor

One thing we need to be careful with here is about leaking data - renderURLs haven't been checked for k-anonymity, and so requesting them can leak data (e.g., if we send them only when offered in a bid, then they could pass in a user ID for the publisher page that could be correlated with a user ID on the joining origin. 32 IGs could provide one bit of publisher page ID each, like: https://foo.test/bit-0-is-1?user=FreddyPharkas, https://foo.test/bit-1-is-0?user=FreddyPharkas, etc. Each URL has the full user ID in the joining origin, and one ordered bit from the top-level-site where the auction is running).

Sending renderURLs on IG join would be more practical, but we don't know the seller origin to send the information to, and we'd need the IG to opt-in to sending the information (normally, offering a bid is considered to provide that permission).

So I think we need to figure out the privacy story here on how we can implement this without creating a new cross-top-level-origin information leak.

@rdgordon-index
Copy link
Contributor Author

renderURLs haven't been checked for k-anonymity

Can you elaborate? As per https://github.com/WICG/turtledove/blob/main/FLEDGE.md#33-metadata-with-the-ad-bid, I wasn't expecting scoreAd() to ever receive a renderURL from generateBid() that didn't pass the k-anon check.

If generateBid() picks an ad whose rendering URL is not yet above the browser-enforced microtargeting prevention threshold, then the function will be called a second time, this time with a modified interestGroup argument that includes only the subset of the group's ads that are over threshold. (The under-threshold ad will, however, be counted towards the microtargeting thresholding for future auctions for this and other users.)

@michaelkleber
Copy link
Collaborator

Sending on IG join would be great, from the privacy POV. If only IGs declared which sellers they were willing to bit with, this would be the preferred approach. But that hasn't been a required part of IG metadata until now. I suspect that if we propose it we will hear push-back, but maybe I'm being too pessimistic? Roni, want to pop my bubble quickly?

Can you elaborate? As per https://github.com/WICG/turtledove/blob/main/FLEDGE.md#33-metadata-with-the-ad-bid, I wasn't expecting scoreAd() to ever receive a renderURL from generateBid() that didn't pass the k-anon check.

We do pass bids along to scoreAd() even if they are for ads below the k-anon bar — we need to do that, otherwise we could never learn whether they would have been the winner, which is the condition for warming up their k-anonymity count.

@MattMenke2
Copy link
Contributor

Only render URLs that win auctions (or rather, that would have won auctions) are registered with the k-anon server for the purposes of calculating k-anonymity, as otherwise, an ad could only be show to a single user, despite appearing in IGs for a lot of users. So if you're blocking ads that you've never seen before, they'll never reach the k-anon threshold. Therefore, this would need to be done for non-k-anon ads.

@MattMenke2
Copy link
Contributor

MattMenke2 commented Sep 12, 2023

And just to be clear - I mean the ads need to have won the top-level auction, in an environment that doesn't know whether they've met the k-anon threshold or not. My understanding is that you'd want to know the URL so it can be scanned before showing it anywhere. If that's not the case, and this can all be done after the ad has hit the k-anon threshold and we've already started showing the ad to users, this becomes much easier to do. We may need some sort of k-anon <renderURL, seller, component auction bool> check on how often an ad has won auctions, and once it's hit, have some way of conveying it to sellers, whether directly, or through an aggregation server of some sort.

@rdgordon-index
Copy link
Contributor Author

rdgordon-index commented Sep 12, 2023

My understanding is that you'd want to know the URL so it can be scanned before showing it anywhere.

Correct.

check on how often an ad has won auctions, and once it's hit, have some way of conveying it to sellers

To be clear, there's no desire to trigger this registration under the k-anon threshold; in other words, if a creative won't be shown to N devices, then there's no need to register it "before" it reaches this threshold.

@rdgordon-index
Copy link
Contributor Author

We do pass bids along to scoreAd() even if they are for ads below the k-anon bar

Only render URLs that win auctions (or rather, that would have won auctions) are registered with the k-anon server for the purposes of calculating k-anonymity

IMHO it isn't immediately obvious that from the explainer that this ever reaches scoreAd() -- though, upon further inspection, it's somewhat implied from this text in https://github.com/WICG/turtledove/blob/main/FLEDGE.md#12-interest-group-attributes (emphasis added):

The browser will provide protection against microtargeting, by only rendering an ad if the same rendering URL is being shown to a sufficiently large number of people (e.g. at least 100 people would have seen the ad, if it were allowed to show)

@MattMenke2
Copy link
Contributor

Agree that the explainer could be clearer on this point. I think this is the first case that's come up where the distinction really matters.

@rdgordon-index
Copy link
Contributor Author

rdgordon-index commented Sep 12, 2023

Sending on IG join would be great, from the privacy POV. If only IGs declared which sellers they were willing to bit with, this would be the preferred approach. But that hasn't been a required part of IG metadata until now. I suspect that if we propose it we will hear push-back, but maybe I'm being too pessimistic? Roni, want to pop my bubble quickly?

That would add complexity if an existing buyer/IG wanted to start working with a new seller, correct? Would updateURL allow for post-join updates to a seller list?

That being said, even if IG seller declaration were in place, that doesn't address the challenge of being able to leverage the metadata provided by generateBid() when registering these new creatives, as noted in the issue description. In other words, it's not solely about making renderURLs available off-device -- though that's definitely part of the challenge.

@rdgordon-index
Copy link
Contributor Author

as otherwise, an ad could only be show to a single user, despite appearing in IGs for a lot of users

Just so that I fully understand the privacy concern -- doesn't that situation arise the first time the ad across the k-anon threshold already?

@MattMenke2
Copy link
Contributor

I think we could pass along renderURLs to new sellers when fetching the updateURL without any major new privacy issues, though that would potentially add a bunch of network requests and overhead (We'd need up update new sellers about renderURLs, and update old sellers about new renderURLs, so if we inform sellers directly from Chrome, that could be a lot of extra traffic).

I don't think sending extra metadata specified by the IG affects the privacy characteristics here if we send the information on join (as opposed to on win on a 3P site, where it would need to be added to the k-anon check, at least). We are putting more complexity and overhead on the browser here for something that the browser doesn't really need to care about, unfortunately. Ideally we'd keep the browser API surface for this as minimal as possible.

@MattMenke2
Copy link
Contributor

Just so that I fully understand the privacy concern -- doesn't that situation arise the first time the ad across the k-anon threshold already?

So, ideally the DSP and SSP don't know when the ad reaches the k-anon threshold for the first time, so can't alter behavior based on that. It can only get so much information from loss reports, and auctions are run in a manner that limits information it can get out of them. Only doing the k-anon counting after it wins the auction is done in part to protect against exactly that sort of gaming the system.

@michaelkleber
Copy link
Collaborator

I'm still wondering whether we can find a safe way to make this happen at IG Join and Update time. Really this is kind of about the browser mediating a direct flow of information from DSP to SSP, if both of them are OK with us doing so. I'm thinking something like:

(1) Suppose SSP X has run auctions in the past [period of time] in which X has invited DSP Y to be a buyer and some Y IG has placed a bid. (Each browser instance could keep track of this.)

(2) Suppose the IG object on which DSP Y calls Join includes a new field 'OkayToTellSellersMyAdUrls': true.

If both of those are true, then at the moment of IG Join, it seems to me like it would be OK for the browser to contact that SSP's KV server — if we knew the base URL somehow — and ask for the associated KV signals for each renderURL in the IG. And then if no KV signals came back, we could send the renderURL to some SSP-chosen scan-queueing endpoint, maybe as identified by the SSP in the KV response.

This could even be one instead of two round-trips, since I don't think there's any need for the first one to go to a trusted server, this is just a question of what endpoints are set up to receive a lot of traffic (KV expecting calls on each auction) vs only a little (scan-queueing expecting traffic only when a new renderURL appears).

@rdgordon-index
Copy link
Contributor Author

and the renderURL need not utilize the buyer origin

As per the new guidance in https://github.com/WICG/turtledove/blob/main/FLEDGE.md#14-buyer-security-considerations :

the ads renderURLs should not be same-origin with the interest group’s owner

This confirms that there will be no a priori method to be able to associate a renderURL with a particular buyer (aka DSP), which is one of the challenges noted above.

@pm-harshad-mane
Copy link

This confirms that there will be no a priori method to be able to associate a renderURL with a particular buyer (aka DSP), which is one of the challenges noted above.

In this situation, DSPs should tell SSP partners which domain they will use in the renderingURL so that SSP can keep track of it on their KV server to recognize the DSP partner from the renderingURL.

@rdgordon-index
Copy link
Contributor Author

DSPs should tell SSP partners which domain they will use in the renderingURL

Agreed -- but it's also not clear that there will only be a single such render domain per DSP.

@JoelPM
Copy link
Contributor

JoelPM commented Oct 15, 2023

[I read through all the comments and think I understand what's being discussed/proposed, but apologies in advance if I rehash something or miss a point already made.]

I think @michaelkleber is on the right track when he says that we're looking for someone to mediate between the SSP and the DSP. However, the challenge with having it be the browser was already pointed out by @rdgordon-index in the initial description, as I think this still results in a "significant volume of unregistered created API calls from each device, for each such creative."

Could the K/V server be the point of coordination? It could provide an endpoint that can be queried for a list of renderURLs that have no data associated with them. It's effectively a list of cache misses. When the endpoint gets queried, it could take the extra step of filtering by checking which keys are still misses, though it doesn't have to.

Depending on how lookups get distributed geographically, it might help segment the data by region (assuming K/V servers are deployed in multiple regions and probably see different keys). This could help SSPs know which values need to be pushed to which K/V servers.

@rdgordon-index
Copy link
Contributor Author

https://developers.google.com/display-video/protected-audience/ssp-guide#metadata_with_ad_bid -- some recent updates from DV3 regarding ad metadata

@orrb1
Copy link
Collaborator

orrb1 commented Jan 19, 2024

Hi all. We've been exploring this issue, and have prepared a document that details a proposed solution, including a chronicle of several options considered and their respective pros/cons. Please take a look:
https://docs.google.com/document/d/1s0tTN25AiPwl3ocCFYOLqeKhetZCt_YFIYQEQ7wzHqI/edit?usp=sharing

Thanks.

@orrb1
Copy link
Collaborator

orrb1 commented Jan 19, 2024

Given the length of the document linked above, I believe it would be helpful to convey a high-level summary of that document here.

The design expressed in this document attempts to balance a few competing objectives:

  1. Ensure that all ads that a seller may be asked to score have been sent to that seller for creative scanning
  2. Don't overload sellers' servers with a firehose of ads to creative scan, and in particular avoid sending the same ad many more times than needed
  3. Minimize the privacy impact of sending ads for creative scanning

To this end, the design proposed has the following properties. The document explains each of these properties and their motivation in far greater detail.

  • Sellers expose an entrypoint at a well-known URI, e.g. https://www.example-ssp.com/.well-known/protected-audience-creative-scanning
  • Buyers can express metadata specifically intended for creative scanning, included alongside the renderURL in each ad in an interest group, and sent alongside the renderURL in requests to that entrypoint.
  • Buyers explicitly enumerate the sellers with which they participate in auctions and to whom the browser should send that buyer's ads for creative scanning. The buyer would do so using an entrypoint exposed at another well-known URI, e.g. https://www.example-dsp.com/.well-known/protected-audience-creative-scanning-buyer-config, and can override it for a specific interest group using seller capabilities.
  • Sellers can limit the rate at which ads are sent from each buyer using an entrypoint at another well-known URI, e.g. https://www.example-ssp.com/.well-known/protected-audience-creative-scanning-seller-config.

The majority of the document focuses on the question of when the browser would send ads to sellers' creative scanning entrypoints. The design alternative the document recommends proposes sending the ads of an interest group anytime that interest group is joined or updated, except that the browser would also keep track of which ads it already sent to each seller, so that it could reduce the volume of traffic sent to sellers' creative scanning entrypoint by sending each ad to each seller only once. To protect privacy, this deduplication would be partitioned by the joining site of the interest group.

Please see the document for more details, and provide your comments here on GitHub issue. Thanks.

@rdgordon-index
Copy link
Contributor Author

https://www.example-ssp.com/.well-known/protected-audience-creative-scanning?renderURL=<URL-encoded-renderURL>&metadata=<URL-encoded-metadata>

question: can we include interestGroupOwner as well?

@rdgordon-index
Copy link
Contributor Author

Though this approach relies on buyers explicitly enumerating all of the sellers with whom they participate in auctions, other approaches for determining the list of target sellers - e.g. having the browser remember, at auction time, which buyers participated in that auction - cause a potential leak of cross-site identity via the seller domain. Mitigating this leak requires an allowlist of sellers, making these approaches redundant, and leaving us no better option than the explicit enumeration.

Can you elaborate on the "potential leak" here? A buyer submitting a bid is effectively "allowing" the seller to scan their creatives.

@orrb1
Copy link
Collaborator

orrb1 commented Jan 19, 2024

https://www.example-ssp.com/.well-known/protected-audience-creative-scanning?renderURL=<URL-encoded-renderURL>&metadata=<URL-encoded-metadata>

question: can we include interestGroupOwner as well?

Yes, that sounds like a good idea. I've modified the document to reflect it. I've also added a change log at the bottom of the document to record any changes made from when the document was first posted here.

Though this approach relies on buyers explicitly enumerating all of the sellers with whom they participate in auctions, other approaches for determining the list of target sellers - e.g. having the browser remember, at auction time, which buyers participated in that auction - cause a potential leak of cross-site identity via the seller domain. Mitigating this leak requires an allowlist of sellers, making these approaches redundant, and leaving us no better option than the explicit enumeration.

Can you elaborate on the "potential leak" here? A buyer submitting a bid is effectively "allowing" the seller to scan their creatives.

This is a good question. The privacy risk described here would not be part of normal operation, but a malicious party could cause a leak in the following way. An auction is run on the user's device for which the seller is userID_on_publisher.adtechB.com, which the browser would remember had participated in an auction with a given buyer. At a later time, that buyer joins the user to an interest group for which an ad's renderURL is adtechA.com/userID_on_advertiser. The browser would then send a creative scanning request https://userID_on_publisher.adtechB.com/.well-known/protected-audience-creative-scanning?renderURL=adtechA.com/userID_on_advertiser&.... Attestation is insufficient to protect against this because it's enforced at eTLD+1 so that userID_on_publisher.adtechB.com would be allowed to run an auction under the attestation for adtechB.com. This is the reason why the browser can't automatically remember the seller-buyer mapping, and the design instead relies on buyers explicitly enumerating the sellers for which their ads should be sent for creative scanning.

@rdgordon-index
Copy link
Contributor Author

Attestation is insufficient to protect against this because it's enforced at eTLD+1

Technically true, but attestation also requires the ad tech vendor to indicate that they're not going do this kind of thing -- and because it's on the adtechB.com, that means that this ad tech would be in violation of their own attestation to the contrary.

@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 22, 2024

Thanks for the well-written and thought out proposal, @orrb1.
I have comments to post and find myself wanting to comment in situ such as on a PR, versus copy/paste/formatting the context into comment(s) in this issue.
Could the external doc be converted to a PR to, say, a "proposals" folder markdown doc?

@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 22, 2024

Buyers could specify the list of sellers to which they would want to send their ads for creative scanning by exposing an entrypoint at another well-known URI. The browser would issue a GET request to the buyer's server, e.g.
https://www.example-dsp.com/.well-known/protected-audience-creative-scanning-buyer-config

Suggestion to please use a consistent root path component for all Protected Audience .well-known URIs as Attribution Reporting has. We find this helpful for request routing.

@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 22, 2024

Buyers' Config Publishing

Since Chrome proposes to commit to fetching and persisting the new creative scanning config and you intend to extend sellerCapabilities, WDYT of generalizing this endpoint to publish using the single config scheme and affording future needs?

For example, https://www.example-dsp.com/.well-known/protected-audience/buyer-config

{
   "sellerCapabilities": {
     "https://seller1.com": { "creative-scanning" },
     "https://seller2.com": { "latency-stats", "creative-scanning" },
     "https://seller3.com": { "latency-stats" },
     "*": { "interest-group-counts" }
   }
}

An interest group can override the settings on any IG join, otherwise these are used. Same caveat mentioned in the explainer applies, that creative scanning cannot have a catch-all. The nifty new scanning declarations are yet another thing to hang onto every IG registration that counts against the size constraints.
In for a penny, in for a pound?

@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 22, 2024

Seller Configs

Same might apply on the seller side along with picking up the perBuyerXXX keyed dict pattern from auctionConfig.

For example, https://www.example-ssp.com/.well-known/protected-audience/seller-config

{
     "perBuyerCreativeSampling": {
       "https://www.example-dsp.com": { "sampling_rate": 1},  // Send all ads from this buyer
       "https://www.another-dsp.com": { "sampling_rate": 0},  // Don't send any ads from this buyer 
       "*": { "sampling_rate": 0.1}                           // Send 10% of ads from other buyers
     }     
     etc...
}

@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 22, 2024

Submitting Creatives

GET https://www.example-ssp.com/.well-known/protected-audience-creative-scanning?renderURL=<URL-encoded-renderURL>&interestGroupOwner=<URL-encoded-interest-group-owner>&metadata=<URL-encoded-metadata>

Chrome isn't consuming anything from the response, right? You can ditch the URL encoding by POSTing,

POST https://www.example-ssp.com/.well-known/protected-audience/creative-scanning

{
   "https://www.example-dsp.com": [
      {
        "renderURL": "https://some-adserver.com/...",   
        "metadata": {the renderURL's associated creativeScanningMetadata}
      }
   ]
}

Also free to send multiple creatives identified at the IG joining site as suggested in your perferred Option 2b.

@rdgordon-index
Copy link
Contributor Author

question: when would creativeScanningHistory table be purged? Any relationship to how/when IGs are cleared?

@rdgordon-index
Copy link
Contributor Author

Yes, we can include another pair of query parameters - adBuyer and adComponentBuyer - that reflects the buyer of each renderUrl and adComponentRenderUrl, respectively, in the key/value service request.

Excellent.

generateBid() does not get to include arbitrary data in the key/value request; it's only allowed to include data from the interest group (e.g. renderUrl). All of the other data proposed to be included in the key/value service request is similarly provided using the interest group.
This is equivalent from a privacy perspective because this all comes from the interest group and could have been included in the renderUrl. This is true even for data selected in generateBid(), e.g. ad size, because an interest group owner could have chosen for the interest group to have more ads, each with a different size encoded in its renderUrl.

If I've understood correctly, this still requires it to be part of IG join/update, and cannot be dynamic at generateBid() runtime, because whatever is part of the IG defintion is could be exfiltrated by the user agent to the K/V by means of the renderURL -- correct?

I'm also unclear on what benefits there would be for the data to be derived from generateBid() versus information encoded in the interest group. Is there information already provided in the response from generateBid() that could be used for creative scanning that we aren't already recommending be included in the key/value request? If you're suggesting new fields returned by generateBid(), what advantage would there be in asking DSPs to do so versus integrating that into their interest group?

This was more about the seller-specific nature of bidding, and hence metadata associated with the bid -- and when these values are known -- but this is probably a better question for the buy-side who will need to manage setting and updating these values. Today, we've asked for all of this information via adMetadata, hence I'm confident it can be determined in generateBid(), but I can't speak for IG join/update time.

Note that in the posting above, we noted that, in the long-term support for creative scanning, "Each renderURL will be sent for creative scanning only after that renderURL has met a privacy bar, for example, having been observed on multiple devices." This privacy bar will apply jointly to the render URL and its associated information - creativeScanningMetadata, ad size, and buyer.

Understood.

Just to clarify, in the description of how this could work posted above, the creativeScanningMetadata on both ad and ad components will be at the ad level, alongside the renderUrl and metadata fields. @rdgordon-index — In this question, you noted that, "if adCreativeScanningMetadata is at the IG-level (and hence not seller-specific)" Is this meant to imply that an interest group owner may have a different ad object for each seller? Assuming that each ad is intended for use with multiple sellers, creativeScanningMetadata could be used to convey the seat ID for each of multiple sellers, for example, by prefixing each seat ID with a prefix unique to each seller.

I think that speaks to the generic "string field whose URL-encoded value" of adCreativeScanningMetadata -- and that "It is buyers and sellers would agree to the structure of this field" -- I was simply noting that if this was derived in generateBid(), this wouldn't be necessary; but the explanation above seems to suggest that anything seller-specific would need to be encoded at IG time for all possible sellers, in advance, if I've understood correctly.

@rdgordon-index
Copy link
Contributor Author

Follow-up question: will creativeScanningMetadata be available in scoreAd()? Today, we get a lot of this information from adMetadata, and I'm curious how we might be able to avoid duplication.

@fhoering
Copy link
Contributor

@rdgordon-index - I'm also unclear on what benefits there would be for the data to be derived from generateBid() versus information encoded in the interest group. Is there information already provided in the response from generateBid() that could be used for creative scanning that we aren't already recommending be included in the key/value request? If you're suggesting new fields returned by generateBid(), what advantage would there be in asking DSPs to do so versus integrating that into their interest group?

With the current proposed system we, as a buyer, will be unable to provide the ad size to the seller via this creativeScanningMetadata metadata field because the ad size is only known via perBuyerSignals or auctionConfig at auction time. We could only provide the ad size for creative scanning if it can be injected during generateBid.
On the other hand, I'm not sure the ad size is necessary for creative scanning as render urls are mostly sizeless.

@rdgordon-index
Copy link
Contributor Author

We could only provide the ad size for creative scanning if it can be injected during generateBid.

#1088 is relevant here -- originally, there was no mechnaism for knowing what the size actually would be for a given auction -- requestedSize was since added, including by Prebid.js, so we should probably continue this discussion re: size.

@orrb1
Copy link
Collaborator

orrb1 commented Dec 2, 2024

Thank you all for your thoughtful responses. I'll address your questions inline below.

If I've understood correctly, this still requires it to be part of IG join/update, and cannot be dynamic at generateBid() runtime, because whatever is part of the IG defintion is could be exfiltrated by the user agent to the K/V by means of the renderURL -- correct?

Yes, this matches my understanding. As long as the extra data being included in the KV request for creative scanning comes from the interest group, we aren't exposing more information by sending that data, since it could otherwise be part of the renderURL.

Today, we've asked for all of this information via adMetadata, hence I'm confident it can be determined in generateBid(), but I can't speak for IG join/update time.

I believe this question was asked in the October 30 WICG call and someone representing a DSP said it wouldn't be an issue, though the call's notes don't seem to mention it. I think adomain and SeatID for each ad should be known at join/update time. If the concern is selecting the one appropriate for a specific seller, then the creativeScanningMetadata could include them for all sellers, each value labeled with the corresponding seller, and sellers could select their appropriate one.

Follow-up question: will creativeScanningMetadata be available in scoreAd()? Today, we get a lot of this information from adMetadata, and I'm curious how we might be able to avoid duplication.

This seems entirely reasonable. We could add a creativeScanningMetadata argument to scoreAd(), currently described in section 2.3 Scoring Bids of the explainer.

With the current proposed system we, as a buyer, will be unable to provide the ad size to the seller via this creativeScanningMetadata metadata field because the ad size is only known via perBuyerSignals or auctionConfig at auction time. We could only provide the ad size for creative scanning if it can be injected during generateBid.
On the other hand, I'm not sure the ad size is necessary for creative scanning as render urls are mostly sizeless.

The proposal above recommends taking the ad size as returned from generateBid() - the width and height optionally returned alongside an ad's renderURL as described in 3.2 On-Device Bidding of the explainer - and providing it alongside creativeScanningMetadata in the seller signals request via the adSizes and adComponentSizes query parameters. The size would not need to be repeated in creativeScanningMetadata.

Thanks again for the helpful feedback.

aarongable pushed a commit to chromium/chromium that referenced this issue Jan 2, 2025
See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I0fb23266c12a20046976c7a1b723136499a59a44
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6084483
Reviewed-by: Caleb Raitto <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Dave Tapuska <[email protected]>
Reviewed-by: Cammie Smith Barnes <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1401439}
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 9, 2025
This is needed to get to creative_scanning_metadata for them; it's not
really used in this CL on its own.

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677
Change-Id: I2cdb645c066914418220b012a322b7d346c8a6e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6158410
Reviewed-by: mmenke <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1404201}
@dmdabbs
Copy link
Contributor

dmdabbs commented Jan 15, 2025

Thanks for the update, @orrb1. Some feedback after discussion in the adtech wg:

(Roni) Follow-up question: will creativeScanningMetadata be available in scoreAd()? Today, we get a lot of this information from adMetadata, and I'm curious how we might be able to avoid duplication.

(OrrB): This seems entirely reasonable. We could add a creativeScanningMetadata argument to scoreAd(), currently described in section 2.3 Scoring Bids of the explainer.

Can you confirm that you will plumb creativeScanningMetadata associated with each bid into scoreAd()?

PA's Deals implementation introduced buyerAndSellerReportingId (aka BASRI) as carriage for a buyer's seat id as known to the seller. This value isn't proposed as a seller scoring KV fetch parameter. Sellers need seat for scoring (for everything, really), so as currently spec'd buyers are going to have to duplicate 'seat' in the creativeScanningMetadata structure. How about adding BASRI as a KV parameter?

Proposal currently specifies creativeScanningMetadata as a string as opposed to following the pattern/precedent set by IG.ads[].metadata that permits "any JSON serialisable value," which Chrome then stringifies via JSON.toString() internally. Can you follow the metadata handling?

aarongable pushed a commit to chromium/chromium that referenced this issue Jan 15, 2025
See WICG/turtledove#792 (comment) for more context.

Bug: 383513677
Change-Id: I9df5d3ca4f03e1d57a162e7981bab824331c2460
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6165448
Reviewed-by: mmenke <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1406780}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 23, 2025
(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 24, 2025
(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6149249
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1410923}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 24, 2025
(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6149249
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1410923}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 24, 2025
(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6149249
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1410923}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jan 28, 2025
…when enabled, a=testonly

Automatic update from web-platform-tests
FLEDGE: Send creative scanning metadata when enabled

(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6149249
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1410923}

--

wpt-commits: 4bf37c1b68359e880958eba87ec6223d8e0c1424
wpt-pr: 50247
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 28, 2025
(This required disabling the optimization of not sending it to the
worklet if sendCreativeScanningMetadata is off, since it's now passed to
the JS in that case).

See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677

Change-Id: I7b40f47c102a0e9d8160ab33cb9e4eb7553ab02a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6190108
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412359}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 28, 2025
(This required disabling the optimization of not sending it to the
worklet if sendCreativeScanningMetadata is off, since it's now passed to
the JS in that case).

See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677

Change-Id: I7b40f47c102a0e9d8160ab33cb9e4eb7553ab02a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6190108
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412359}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 28, 2025
(This required disabling the optimization of not sending it to the
worklet if sendCreativeScanningMetadata is off, since it's now passed to
the JS in that case).

See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677

Change-Id: I7b40f47c102a0e9d8160ab33cb9e4eb7553ab02a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6190108
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412359}
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Jan 28, 2025
…when enabled, a=testonly

Automatic update from web-platform-tests
FLEDGE: Send creative scanning metadata when enabled

(As part of V1 trusted scoring signals fetch).

See WICG/turtledove#792 (comment) for more context.

Bug: 383513677

Change-Id: I27e2a3357c3897edd1d1c612186a39a0afa91cc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6149249
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: mmenke <[email protected]>
Reviewed-by: Giovanni Ortuno Urquidi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1410923}

--

wpt-commits: 4bf37c1b68359e880958eba87ec6223d8e0c1424
wpt-pr: 50247
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 29, 2025
See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677
Change-Id: Ia3bd88a16ffa3cb0ef94f3b1987e3fd131682b64
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6208175
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1413028}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jan 31, 2025
…to scoreAd, a=testonly

Automatic update from web-platform-tests
FLEDGE: Pass creative scanning metadata to scoreAd

(This required disabling the optimization of not sending it to the
worklet if sendCreativeScanningMetadata is off, since it's now passed to
the JS in that case).

See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677

Change-Id: I7b40f47c102a0e9d8160ab33cb9e4eb7553ab02a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6190108
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412359}

--

wpt-commits: dcd3048a444e6cd2221e150189ee6a88a8a5c627
wpt-pr: 50341
@orrb1
Copy link
Collaborator

orrb1 commented Jan 31, 2025

Thanks for the follow-up questions, and for the discussion at the recent PA WICG Call. Responses inline.

Can you confirm that you will plumb creativeScanningMetadata associated with each bid into scoreAd()?

Yes, we will pass creativeScanningMetadata into scoreAd() as part of the browserSignals argument. We will do so for both the main ad as a new string-typed creativeScanningMetadata field of browserSignals, and for component ads as a new adComponentsCreativeScanningMetadata field of browserSignals, an array of strings-or-null.

PA's Deals implementation introduced buyerAndSellerReportingId (aka BASRI) as carriage for a buyer's seat id as known to the seller. This value isn't proposed as a seller scoring KV fetch parameter. Sellers need seat for scoring (for everything, really), so as currently spec'd buyers are going to have to duplicate 'seat' in the creativeScanningMetadata structure. How about adding BASRI as a KV parameter?

In PA WICG Call, we discussed how generateBid() must return a selectedBuyerAndSellerReportingId in order for that bid's buyerAndSellerReportingId to be included as a part of the browserSignals argument to scoreAd(). There was some feedback that it might be fairly standard to provide a selectedBuyerAndSellerReportingId, even if it's an empty string, so that buyerAndSellerReportingId would always be provided. As noted during that call, please recall that selecting a selectedBuyerAndSellerReportingId has k-anonymity implications as described in the Reporting IDs developer guide.


There's another important distinction between buyerAndSellerReportingId and creativeScanningMetadatabuyerAndSellerReportingId (and all of the other reporting ID fields) may only be provided on main ads, not component ads. In scoreAd(), you get one bid with one main ad and possibly some component ads. However, the seller signals request may contain multiple main ads and any number of associated component ads, so that you can't necessarily determine which main ad is associated with each component ad. It is guaranteed that component ads will be on the same seller signals request as their enclosing main ad.

Is it safe to assume that the seat expressed in buyerAndSellerReportingId for the main ad also applies to all of the component ads of a bid? Is it also safe to assume that any two ads/component ads that share an adomain would also share a seat? Combined, what I'm asking is - given the creativeScanningMetadata for all of the ads and component ads on a seller signals request, and the buyerAndSellerReportingId for the main ad alone, is that sufficient to infer the seat for the component ads in that request? If so, we could add a new query parameter, adBuyerAndSellerReportingIds, which would contain the buyerAndSellerReportingId for only the main ads of each seller signals request.

Proposal currently specifies creativeScanningMetadata as a string as opposed to following the pattern/precedent set by IG.ads[].metadata that permits "any JSON serialisable value," which Chrome then stringifies via JSON.toString() internally. Can you follow the metadata handling?

While metadata on the interest group and the adMetadata provided as an argument to scoreAd() are primarily intended to be provided as arguments to JavaScript functions, creativeScanningMetadata is primarily intended to be sent as a query parameter on the seller signals request. As a query parameter, creativeScanningMetadata is subject to both escaping and size limits on the request URL. As such, it's preferable for creativeScanningMetadata to be a simpler and more concise representation of the data needed for creative scanning, which is why we recommend having this field be string-typed instead of allowing any JSON-serializable value.

aarongable pushed a commit to chromium/chromium that referenced this issue Jan 31, 2025
Adds buyerAndSellerReportingId (BSRID) to the query parameters of
the BYOS scoring signals request URL for use in creative scanning
when `sendCreativeScanningMetadata` is set to true on the
auction config.

See
WICG/turtledove#792 (comment)
for more context (along with following comments)

Bug: 383513677
Change-Id: I77dced8bb39a55cf7b7ad9fb80c91fed8c9dad00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219861
Reviewed-by: Orr Bernstein <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1414406}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 31, 2025
Adds buyerAndSellerReportingId (BSRID) to the query parameters of
the BYOS scoring signals request URL for use in creative scanning
when `sendCreativeScanningMetadata` is set to true on the
auction config.

See
WICG/turtledove#792 (comment)
for more context (along with following comments)

Bug: 383513677
Change-Id: I77dced8bb39a55cf7b7ad9fb80c91fed8c9dad00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219861
Reviewed-by: Orr Bernstein <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1414406}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 31, 2025
Adds buyerAndSellerReportingId (BSRID) to the query parameters of
the BYOS scoring signals request URL for use in creative scanning
when `sendCreativeScanningMetadata` is set to true on the
auction config.

See
WICG/turtledove#792 (comment)
for more context (along with following comments)

Bug: 383513677
Change-Id: I77dced8bb39a55cf7b7ad9fb80c91fed8c9dad00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219861
Reviewed-by: Orr Bernstein <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1414406}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Feb 3, 2025
…g metadata in TSS request., a=testonly

Automatic update from web-platform-tests
FLEDGE: Include BSRID w/creative scanning metadata in TSS request.

Adds buyerAndSellerReportingId (BSRID) to the query parameters of
the BYOS scoring signals request URL for use in creative scanning
when `sendCreativeScanningMetadata` is set to true on the
auction config.

See
WICG/turtledove#792 (comment)
for more context (along with following comments)

Bug: 383513677
Change-Id: I77dced8bb39a55cf7b7ad9fb80c91fed8c9dad00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219861
Reviewed-by: Orr Bernstein <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1414406}

--

wpt-commits: 280743fe51500ca43b4162605270f965452dfb9a
wpt-pr: 50420
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Feb 5, 2025
…to scoreAd, a=testonly

Automatic update from web-platform-tests
FLEDGE: Pass creative scanning metadata to scoreAd

(This required disabling the optimization of not sending it to the
worklet if sendCreativeScanningMetadata is off, since it's now passed to
the JS in that case).

See
WICG/turtledove#792 (comment)
for more context.

Bug: 383513677

Change-Id: I7b40f47c102a0e9d8160ab33cb9e4eb7553ab02a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6190108
Commit-Queue: Maks Orlovich <[email protected]>
Reviewed-by: Orr Bernstein <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412359}

--

wpt-commits: dcd3048a444e6cd2221e150189ee6a88a8a5c627
wpt-pr: 50341
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Feb 5, 2025
…g metadata in TSS request., a=testonly

Automatic update from web-platform-tests
FLEDGE: Include BSRID w/creative scanning metadata in TSS request.

Adds buyerAndSellerReportingId (BSRID) to the query parameters of
the BYOS scoring signals request URL for use in creative scanning
when `sendCreativeScanningMetadata` is set to true on the
auction config.

See
WICG/turtledove#792 (comment)
for more context (along with following comments)

Bug: 383513677
Change-Id: I77dced8bb39a55cf7b7ad9fb80c91fed8c9dad00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219861
Reviewed-by: Orr Bernstein <[email protected]>
Commit-Queue: Maks Orlovich <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1414406}

--

wpt-commits: 280743fe51500ca43b4162605270f965452dfb9a
wpt-pr: 50420
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants