WICG / turtledove

TURTLEDOVE
https://wicg.github.io/turtledove/
Other
511 stars 215 forks source link

Allowing each interestGroup owner to be associated with multiple keys in perBuyerSignals #1211

Open ningwangpanda opened 1 week ago

ningwangpanda commented 1 week ago

In the Protected Audience API, each interestGroup owner is only associated with one key in perBuyerSignals, which defaults to the interestGroup owner, i.e., the buyer_origin. Currently, two DSPs from the same company (under the same domain) have to wire separate copies of perBuyerSignals to SSPs when their interestGroup owners are two different buyer_origins under the same domain, for example, dsp1.company.com and dsp2.company.com under company.com, even though their perBuyerSignals have common data. DSPs are optimizing the size of perBuyerSignals being sent to SSPs. Wiring perBuyerSignals twice is not an optimized solution due to extra bandwidth and process load. We propose that Chrome implement a mechanism to allow each interestGroup owner to be associated with perBuyerSignals shared across multiple interestGroup owners, so that DSPs can optimize wiring of perBuyersignals to SSPs across different DSPs from the same company without increasing load on wiring and impacting performance.

Here is our detailed proposal. Our proposal is only for the same contextual request that is eligible for multiple DSPs, which lands at the same contextual ad server. Serving and merging common perBuyerSignals from different DSP servers or across different contextual responses for the same ad slot are non-goals of this proposal.

We use DSP1 (dsp1.company.com) and DSP2 (dsp2.company.com) from company.com as an example. We also assume all interest groups of DSP1 have dsp1.company.com as the owner; all interest groups of DSP2 have dsp2.company.com as the owner.

DSP1 and DSP2 share the same contextual ad server from company.com. When both DSPs owned by the company are eligible to participate in auction, the contextual ad server wires common perBuyerSignals and perBuyerSignals specific to DSP1 and DSP2 according to the eligibility of DSP1 and DSP2 in the contextual response. Chrome will use all wired data to build the final perBuyerSignals (common perBuyerSignals and DSP-specific perBuyerSignals) for DSP1 and DSP2. The server wires DSP1-specific perBuyerSignals using dsp1.company.com; wires DSP2-specific perBuyerSignals using dsp2.company.com; wires common perBuyerSignals using company.com. The company.com domain does not own any interest groups; it is only being used to wire common perBuyerSignals.

per_buyer_signals = { 
         "https://www.company.com" : [common_per_buyer_signals] 
         "https://www.dsp1.company.com": [dsp1_specific_per_buyer_signals]
         "https://www.dsp2.company.com": [dsp2_specific_per_buyer_signals] 
 }

We propose that Chrome allows each interestGroup owner to be associated with multiple keys in perBuyerSignals for DSPs in the attestation files. For example, besides the default perBuyerSignals owned by interestGroup owners (i.e., buyer_origins), Chrome can allow DSPs to specify extra perBuyerSignals via a new key-value pair: <interestGroup owner, keys of extra perBuyerSignals>. The key-value pair will be static for DSPs. In the rare case that a company launches new DSPs, DSPs will update our attestation files.

{
     "enrollment_site": "https://www.company.com",
     "platform_attestations": [
       {
         "platform": "chrome",
         "attestations": {
           "protected_audience_api": {
             "perBuyerSignalsSharing": [
               {"https://www.dsp1.company.com": "https://www.company.com"},
               {"https://www.dsp2.company.com": "https://www.company.com"},
            ]
           }
         }
       }
     ]
}

In auction configs, interest groups owned by dsp1.company.com will be associated with company.com and dsp1.company.com in perBuyerSignals; interest groups owned by dsp2.company.com will be associated with company.com and dsp2.company.com in perBuyerSignals.

const myAuctionConfig = {
  'seller': 'https://www.example-ssp.com',

  // This should be a list of all DSPs that you wish to participate in this auction
  'interestGroupBuyers': ['https://www.dsp1.company.com', 'https://www.dsp2.company.com', ...],

  'perBuyerSignals': {'https://www.company.com': ...,
                      'https://www.dsp1.company.com': ...,
                      'https://www.dsp2.company.com': ...,
                      ...},
};
const result = await navigator.runAdAuction(myAuctionConfig);

In generateBid(), Chrome provides (common_per_buyer_signals and dsp1_specific_per_buyer_signals) for DSP1’s interest groups and (common_per_buyer_signals and dsp2_specific_per_buyer_signals) for DSP2’s interest groups.

generateBid(interestGroup, auctionSignals, perBuyerSignals,
    trustedBiddingSignals, browserSignals, directFromSellerSignals) {
  ...
  return {'ad': adObject,
          'bid': bidValue};
}
michaelkleber commented 1 week ago

It seems to me that you can accomplish this goal today, when the auction config is constructed:

const sharedCompanyDotComSignals = {'foo':123, 'bar':456};
const myAuctionConfig = {
  'seller': 'https://www.example-ssp.com',

  // This should be a list of all DSPs that you wish to participate in this auction
  'interestGroupBuyers': ['https://www.dsp1.company.com', 'https://www.dsp2.company.com'],

  'perBuyerSignals': {
                      'https://www.dsp1.company.com': {...sharedCompanyDotComSignals, 'dsp1signal':789},
                      'https://www.dsp2.company.com': {...sharedCompanyDotComSignals, 'dsp2signal':987}
                      },
};
const result = await navigator.runAdAuction(myAuctionConfig);
dmdabbs commented 1 week ago

It seems to me that you can accomplish this goal today, when the auction config is constructed:

It is possible that the evolving OpenRTB IG buyer intent signaling specification could be amended to provide carriage for "shared pbs" so that the seller/SSP can assemble the config.

Wiring perBuyerSignals twice is not an optimized solution due to extra bandwidth and process load.

If your sibling buyers share perBuyerSignals, might they also share prioritySignals? Seems unlikely, but thought I'd ask.

NB: Link above is to a proposed revision. The PR is here: https://github.com/InteractiveAdvertisingBureau/openrtb/pull/175.

ningwangpanda commented 3 days ago

We have explored the option of constructing perBuyerSignals with help from SSPs. We believe sharing perBuyerSignals in Chrome API is a superior solution due to the following considerations.

  1. SSPs need to make bid protocol changes coordinating with the ecosystem to merge perBuyerSignals for ALL DSPs that they work with.
  2. If an SSP works with some DSPs that would like to share perBuyerSignals, that SSP needs to equally support all DSPs that it works with. This implies that most, if not all, SSPs have to support perBuyerSignals sharing.
  3. OpenRTB is one of the exchange protocols. We will need most, if not all, exchange protocols to make corresponding changes.
  4. Some DSPs do not need to share perBuyerSignals. However, for DSPs that need to share perBuyerSignals, changes need to happen in all buying paths, including all exchange bids, direct buys and reservations.

Overall, Chrome API support is much cleaner because it automatically covers all DSPs, SSPs and exchanges.

Note that DSPs need to be able to regularly update common perBuyerSignals, thus using a variable and JS to send them once is not an option for DSPs.

const sharedCompanyDotComSignals = {'foo':123, 'bar':456};

Lastly, we do not plan to share prioritySignals at this moment.

dmdabbs commented 2 days ago

In generateBid(), Chrome provides (common_per_buyer_signals and dsp1_specific_per_buyer_signals) for DSP1’s interest groups and (common_per_buyer_signals and dsp2_specific_per_buyer_signals) for DSP2’s interest groups.

Today, Chrome is not opinionated about buyer signals - they're opaque "any JSON-serializable values." Since Chrome will be merging them you must be requiring them to be dictionaries for that to make sense. Your common signals illustration used arrays, so I assume this was simply a placeholder.

In any event, if our DSP decided we needed a second IG buyer domain with common signals as you describe, we would need the protocols to sellers/exchanges, such as OpenRTB, to accommodate "common pbs" as suggested earlier, else I do not see how we would provision the common signals to the auction.