Skip to content

Latest commit

 

History

History
356 lines (241 loc) · 29.1 KB

Fenced_Frames_Ads_Reporting.md

File metadata and controls

356 lines (241 loc) · 29.1 KB

FLEDGE has been renamed to Protected Audience API. To learn more about the name change, see the blog post

Objective

As part of FLEDGE, interest based ads are rendered in fenced frames which are special embedded frames that do not have any communication channels with the publisher page, unlike iframes. Since fenced frames do not have any contextual information, part of the reporting that ads require needs to be done via separate JS contexts called reporting worklets. The other part of the reporting which is based on user behavior in relation to the rendered ad comes from the fenced frame. There is thus a requirement from ads infrastructure to be able to correlate these two parts of reporting. Note that this correlation is required only for event-level reporting.

For invalid ad traffic detection, signals are collected about the publisher, the browser and the user behavior on the ad. Out of these three categories, signals about the publisher are available in the reporting worklet while those about the browser and user behavior are available inside the fenced frame. We therefore need a channel for signals within the fenced frame to be communicated to the reporting worklet.

Seller ad-tech reports the auction result via reportResult() and the buyer reports it via reportWin(). These are implemented in the seller’s and buyer’s reporting worklets, respectively. These are already correlated with the contextual ad request but additionally, they need to be correlated with the events related to the fenced frame e.g. impressions, interactions and clicks. We therefore need a channel for events within the fenced frame to be correlated to the information in the reporting worklet and sent out on the network to support event-level reporting. In the long-term, these events could only be exfiltrated using an aggregate report.

An ID provided to runAdAuction to identify a contextual query/ad cannot be passed on to the fenced frame because the reporting worklet has publisher information and that could be encoded and passed to the fenced frame defeating the fenced frame’s privacy guarantees. Therefore the higher level idea is for the browser to take the signals provided by the fenced frame and correlate it with the ID passed to it by the reporting worklet and send out the correlated data to the ad-tech server.

From a privacy perspective, it is also important to note that the additional information (from what the worklet already knows) that the fenced frame is sending to the browser and eventually to the ad-tech server, cannot contribute to identifying the user since the fenced frame does not have access to cookies/unpartitioned storage.

While Protected Audience supports rendering ads in iframes, the features outlined in this document will also apply to iframes created using the Protected Audience API.

Design

The following summarizes the sequence of events for the buyer and seller. Distinguishing these flows here, since in principle, one should be able to report without the help of the other but with an opt-in from the ad's origin for maintaining web's security principles for origins.

high level diagram

Seller (SSP) flow of events

  1. SSP will generate an event identifier, say sellerEventId, at contextual ad request time.
  2. SSP will provide the sellerEventId to the auction via auctionConfig, which will be available in the reporting worklet for the SSP.
  3. In reportResult(), the sellerEventId, along with any other contextual response fields relevant for reporting, will be available so that the result can be joined to the corresponding contextual query.
  4. Once the winning ad is rendered in the fenced frame, the fenced frame can also communicate other events to the browser e.g. what user interaction happened. Since the fenced frames run the buyer’s scripts, the buyer can also decide what information to be volunteered to the seller via the reportEvent API.
  5. The solution proposed in this document allows the seller’s reporting worklet to register a URL to which data should be sent for events reported by the fenced frame.

Buyer (DSP) flow of events

  1. If the DSP participates in the contextual ad request, it will generate an event identifier, say buyerEventId, at contextual ad request/response time which is returned to the SSP as part of the perBuyerSignals, which the SSP in turn would specify in navigator.runAdAuction call. For DSPs that do not participate, buyerEventId could just be an ID that the worklet creates.
  2. Browser will provide the buyerEventId to the reporting worklet for the DSP via reportWin() as part of the perBuyerSignals. This enables the result to be joined with the corresponding contextual query.
  3. Fenced frame can also communicate other events to the browser e.g. a click happened along with click coordinates.
  4. The solution proposed in this document allows the buyer’s reporting worklet to register a URL in reportWin(), to which data should be sent, when events happen in the fenced frame.

APIs

The following new APIs will be added for achieving this.

reportEvent (preregistered destination URL)

There are two variants of the reportEvent API for event-level reporting that are invoked with different sets of parameters. In the first variant, fenced frames can invoke the reportEvent API to tell the browser to send a beacon with event data to a URL registered by the worklet in registerAdBeacon (see below). Depending on the declared destination, the beacon is sent to either the buyer's or the seller's registered URL. Examples of such events are mouse hovers, clicks (which may or may not lead to navigation e.g. video player control element clicks), etc.

This API is available from all documents in a fenced frame tree (i.e., the ad creative URL that won the Protected Audience auction). Child iframe or redirected documents that are same-origin to the mapped URL of the fenced frame config can call this API without any restrictions. Cross-origin child iframe documents can only call this API if there is opt-in from both the fenced frame root and the cross-origin document. The fenced frame root opts in by being served with a new Allow-Cross-Origin-Event-Reporting response header set to true. The cross-origin document opts in by calling reportEvent with crossOriginExposed=true. See TURTLEDOVE issue #1077 for the motivation behind cross-origin support.

The browser processes the beacon by sending an HTTP POST request, like the existing navigator.sendBeacon. The POST request is sent immediately or as soon as the corresponding registerAdBeacon is invoked, and is done asynchronously to avoid blocking other actions.

Note window.fence here is a new namespace for APIs that are only available from within a fenced frame. In the interim period when FLEDGE supports rendering the winning ad in an iframe, window.fence will also be available in such an iframe.

Enrollment Requirement

The reporting destination URL registered by registerAdBeacon is required to have its site (scheme, eTLD+1) attested for Protected Audience API, otherwise the beacon is not allowed to be sent to this reporting destination. Please see the Privacy Sandbox enrollment attestation model.

Parameters

Event type and data: Includes the event type and data associated with an event. When an event type e.g. click matches to the event type registered in registerAdBeacon, the data will be used by the browser as the request body in the request sent to the registered URL.

Destination type: List of values to determine whose registered beacons are reported, can be a combination of the following destination types:

  • buyer: the bidder in the FLEDGE auction.

  • seller: the top-level seller that is running the auction.

  • component-seller: the seller for a component auction in a multi-level auction.

  • direct-seller: the seller that ran the auction that the buyer bid in, whether that was a top-level auction or a component auction.

One report will be processed for each destination specified. So if both component-seller and direct-seller are both specified for a multi-level auction then two reports will be processed for the seller from the component auction (one for the component-seller destination and one for the direct-seller destination).`

Cross-origin exposed: A boolean that determines whether the data can be used to send reporting beacons using information from an ancestor fenced frame's config whose mapped URL is cross-origin to the invoking document's origin.

Example

To send a request with the POST request body '{"clickX":"123","clickY":"456"}' to the URL registered for buyer and seller when a user click happens:

window.fence.reportEvent({
  'eventType': 'click',
  'eventData': JSON.stringify({'clickX': '123', 'clickY': '456'}),
  'destination':['buyer', 'seller']
});

To send a request with the POST request body 'an example string' to the URL registered for component-seller when a user click happens:

window.fence.reportEvent({
  'eventType': 'click',
  'eventData': 'an example string',
  'destination':['component-seller']
});

To send a request with the POST request body '' to the URL registered for buyer when a user click happens:

window.fence.reportEvent({
  'eventType': 'click',
  'destination':['buyer']
});

To send a request from a document that is cross-origin to the fenced frame config's mapped URL with the POST request body 'an example string' to the URL registered for buyer when a user click happens:

window.fence.reportEvent({
  'eventType': 'click',
  'eventData': 'an example string',
  'destination':['buyer'],
  'crossOriginExposed': true
});

reportEvent (custom destination URL with substitution of preregistered macros)

In the second reportEvent variant, fenced frames can invoke the reportEvent API to tell the browser to send a beacon to a specified destination URL, where macros in the URL are substituted to values registered by the buyer's worklet in registerAdMacro (see below). This specified URL must be a valid HTTPS URL.

Unlike reportEvent to a preregistered destination, here the browser processes the beacon by sending an HTTP GET request, as per feedback here: #477 (comment).

This API is available in the same contexts as reportEvent to a preregistered destination, i.e., all documents in a fenced frame tree, with opt-in requirements for documents that are cross-origin to the mapped URL. However, there are additional restrictions on the origin of the destination URL. The interest group declaration includes an allowlist of origins that may receive reports using this mode of reportEvent (custom destination URL with macro substitution). If at any point a report is attempted to a disallowed origin, access to this mode of reportEvent will be shut off for any ad loaded from this fenced frame config, for privacy reasons (to prevent reidentification by using the allowlist to encode cross-site data about a user in binary with its choices of allowed/disallowed origins). Note that this only applies to this mode of reportEvent: reportEvent to a preregistered destination will still work.

Example

Here is an example that makes the interest group include an allowlist of origins (e.g. https://adtech.example) to receive report events.

const myGroup = {
  ...
  'ads': [
    {
      renderUrl: '...',
      allowedReportingOrigins: [
        'https://adtech.example'
      ]
    }
  ],
  ...
};
const joinPromise = navigator.joinAdInterestGroup(myGroup);

Enrollment Requirement

The reporting destination URL specified in reportEvent's destinationURL field is required to have its site (scheme, eTLD+1) attested for Protected Audience API, otherwise the beacon is not allowed to be sent to this reporting destination. Please see the Privacy Sandbox enrollment attestation model.

Parameters

Destination URL: Includes the desired destination URL for the report, with macros to be substituted based on the buyer worklet's specified values.

Example

Here is an example that will substitute ${PUBLISHER_ID} and ${SOURCE_URL_ENC} macros based on values specified in the buyer worklet.

window.fence.reportEvent({
  'destinationURL': 'https://adtech.example/impression?cid=555&pub_id=${PUBLISHER_ID}&site=${SOURCE_URL_ENC}&t=123'
});

In this example, the reporting destination eTLD+1 is "adtech.example". The Privacy Sandbox enrollment attestation model requires its site (scheme, eTLD+1) "https://adtech.example" to be enrolled as defined in site-based enrollment. Otherwise the beacon will not be sent.

registerAdBeacon

A similar API was initially discussed here: #99 for reporting clicks. The idea is that the buyer and seller side worklets are able to register a URL with the browser in their reportWin and reportResult APIs. A beacon will be sent to the registered URL when events are reported by the fenced frame via reportEvent.

Parameters

A map from event type to reporting URL, where the event type corresponds to the eventType value passed to reportEvent(). The event type enables worklets (for buyer, seller, or component seller) to register distinct reporting URLs for different event types. The reporting URL is the location where a beacon is sent once the fenced frame delivers the corresponding event via reportEvent().

Worklets can add a buyer event identifier, seller event identifier, or any other relevant information as query parameters to this URL.

Example

registerAdBeacon({
 'click': 'https://adtech.example/click?buyer_event_id=123',
});

In this example, the reporting destination eTLD+1 is "adtech.example". The Privacy Sandbox enrollment attestation model requires its site (scheme, eTLD+1) "https://adtech.example" to be enrolled as defined in site-based enrollment. Otherwise the beacon will not be sent when there is a click event.

registerAdMacro

Bidder worklets are able to register macros with the browser in their reportWin() function. The registered macro values are used to substitute macros in the destination URL of the reportEvent() API's parameter.

Parameters

Two strings. macro name It’s case sensitive, e.g., “PUBLISHER_ID”.

macro value The value of the macro that is used to substitute the macro (e.g., ${PUBLISHER_ID}) in reportEvent() API’s destination URL parameter.

These strings should be URL-encoded (percent encoded). If either of these strings contains characters that are impossible in URL-encoded strings (i.e., any characters besides the unreserved characters here and %), the registerAdMacro call will fail with a type error. This is to prevent substituted macros from escaping URL parameters in the destination URL template, e.g. substituting https://ad.com?param=${PARAM} with (PARAM, innocuous_value?malicious_param=malicious_value).

Example

registerAdMacro(‘PUBLISHER_ID’, ‘123a’);
registerAdMacro(‘SOURCE_URL_ENC’, ‘http%3A%2F%2Fpub%2Eexample%2Fpage’);

Support for Attribution Reporting

Goals

  • While fenced frames still have unrestricted network access and FLEDGE supports event-level reporting, the solution below takes advantage of the registerAdBeacon/reportEvent information flow to enable registering attribution sources. ARA attribution triggering is unchanged for registered FLEDGE impressions.
  • Improve the ergonomics of triggering ad beacons based on clicks.

The changes below will be available in Chrome starting M112.

registerAdBeacon

The reportResult and reportWin worklet code will be able to register two new events, called 'reserved.top_navigation_start' and 'reserved.top_navigation_commit', via registerAdBeacon():

registerAdBeacon({
 'reserved.top_navigation_start': 'https://adtech.example/click?buyer_event_id=123',
 'reserved.top_navigation_commit': 'https://adtech.example/click?buyer_event_id=123',
});

The new events, if registered, implies that an automatic beacon will be sent by the browser to the registered URL when a top-level navigation is invoked from within the fenced frame and the navigation was preceded by a call to window.fence.setReportEventDataForAutomaticBeacons. These events are not triggered by the fenced frame's initial navigation and commit (e.g. when rendering the original ad), only subsequent ones (e.g. when triggered by a user clicking on the ad). More specifically, a reserved.top_navigation_start beacon will be sent when a top-level navigation begins and a reserved.top_navigation_commit beacon will be sent when the navigation successfully completes. This will impact top-level navigation initiated from the fenced frame in the same tab (via unfencedTop target) or in a different tab. Note that this beacon is gated on a transient user activation (e.g. a click). More details about the beacon are below.

reportEvent

The beacons that are generated from a reportEvent invocation or via an automatic beacon will now be automatically eligible for attribution, i.e. the browser appends the Attribution-Reporting-Eligible HTTP request header. The beacon responses can then register attribution sources as usual, as described here.

Redirects

As mentioned in the explainer above, reportEvent beacons are POST requests and carry eventData in the request's body. The same will be true for automatic beacon requests. Note that for any server redirects of the initial request, the browser sends a GET request and does not include the initial request's body. For attribution registration flow, if the eventData needs to be used as part of the redirected request, it must be explicitly passed on as part of the redirect URL.

Enrollment Requirement

For redirects, the redirect URL is not checked for enrollment and attestation. This is because the browser does not add any data directly to the redirect URL. Only the initial reporting destination is checked for attestation for Protected Audience API. The initial reporting destination is responsible for acting in accordance with its attestation if it decides to share any data via the redirect.

API to populate event data for automatic beacons

Since automatic beacons are automatically generated by the browser, there needs to be some way for those beacons to be associated with a destination and include event data, as it happens in reportEvent generated beacons. To achieve this, a new setReportEventDataForAutomaticBeacons API can be invoked from within the fenced frame:

window.fence.setReportEventDataForAutomaticBeacons({
  'eventType': 'reserved.top_navigation_commit',
  'eventData': 'an example string',
  'destination': ['seller', 'buyer'],
});

If setReportEventDataForAutomaticBeacons is invoked, the browser will send an automatic beacon to all URLs registered via registerAdBeacon for the given event, but it will only send an event data body (the information in eventData) with the HTTP request to destinations specified in the destination field. This means that invoking setReportEventDataForAutomaticBeacons acts as an opt-in by the fenced frame document to allow sending the beacon to all registered URLs, aligning with cross-origin security principles.

The ad frame's page can also opt in to sending automatic beacons by being served with a new Allow-Fenced-Frame-Automatic-Beacons response header. When set to true, automatic beacons will be sent to all registered destinations, but will not include any event data with it.

This table shows the relationship between setReportEventDataForAutomaticBeacons and Allow-Fenced-Frame-Automatic-Beacons and how automatic beacons are sent out:

No setReportEvent...() setReportEvent... ()
No Allow-...-Beacons: true none Beacon sent with data
Allow-...-Beacons: true Beacon sent - no data Beacon sent with data

Currently, the only eventTypes that setReportEventDataForAutomaticBeacons allows are 'reserved.top_navigation_start' and 'reserved.top_navigation_commit'. Note that the script invoking this API can volunteer this information to a given destination type or not, similar to reportEvent, using the destination field.

If invoked multiple times, the latest invocation before the top-level navigation would be the one that’s honored.

Automatic beacon data can be manually cleared out by calling setReportEventDataForAutomaticBeacons with an empty destination list.

window.fence.setReportEventDataForAutomaticBeacons({
  'eventType': 'reserved.top_navigation_start',
  'destination': [],
});

setReportEventDataForAutomaticBeacons can also be invoked in the click handler of an anchor tag, and will be sent on navigation:

<script>
function addBeaconData(element) {
  const data = element.id + " was clicked.";
  let beacon_event = {
    eventType: "reserved.top_navigation_commit",
    eventData: data,
    destination: ["buyer"],
  }
  window.fence.setReportEventDataForAutomaticBeacons(beacon_event);
}
</script>
<a onclick="addBeaconData(this)" id="link1" href="somesite.com" target="_blank">Click me!</a>

The beacon data will be in place by the time that the navigation starts. When the navigation commits, the automatic beacon will be sent out with event data set to "link1 was clicked.".

Send Automatic Beacons Once

The dictionary passed into setReportEventDataForAutomaticBeacons also takes an optional once boolean that defaults to false. If once is set to true, the automatic beacon will only be sent for the next event. Beacons will not be sent for subsequent events until setReportEventDataForAutomaticBeacons is invoked again. When used with a click handler, this can be used to send beacon data only for specific top-level navigations, rather than for every top-level navigation.

For example, if a frame has multiple links that can perform top-level navigations, but only one of the links is of interest for analytics purposes, setReportEventDataForAutomaticBeacons() can be called in that link's click handler with once set to true. This will ensure that, if another link is clicked after the link with the associated automatic beacon, that other link will not result in an automatic beacon being sent out.

window.fence.setReportEventDataForAutomaticBeacons({
  'eventType': 'reserved.top_navigation_start',
  'eventData': 'an example string',
  'destination': ['seller', 'buyer'],
  'once': true,
});

Cross-Origin Support

Data for automatic beacons can only be set by documents that are same-origin to the mapped URL of the fenced frame config. However, cross-origin documents in child iframes of the main ad frame can still send automatic beacons, if the document and the data are both opted in.

A cross-origin document will be considered opted into sending automatic beacons if it is served with the response header Allow-Fenced-Frame-Automatic-Beacons: true.

To opt in the data, the dictionary passed into setReportEventDataForAutomaticBeacons takes an optional crossOriginExposed boolean that defaults to false. If set to true, the automatic beacon data can be used if a cross-origin document wants to send an automatic beacon and is opted in. A document will use the data of the first ancestor frame that has automatic beacon data registered for the event type being sent.

window.fence.setReportEventDataForAutomaticBeacons({
  'eventType': 'reserved.top_navigation_start',
  'eventData': 'an example string',
  'destination': ['seller', 'buyer'],
  'crossOriginExposed': true,
});

Credentials in Beacons

When 3rd party cookies are enabled, automatic beacon requests only (not beacons sent manually through reportEvent) allow credentials (cookies) to be set in headers. This was requested by #866 in order to help with migration and ARA debugging. These requests are subject to CORS and only occur after opt-in by virtue of calling the setReportEventDataForAutomaticBeacons API or using the Allow-Fenced-Frame-Automatic-Beacons: true response header in cross-origin iframes/component ad frames.

Enrollment Requirement

The reporting destination URL registered by setReportEventDataForAutomaticBeacons is required to have its site (scheme, eTLD+1) attested for Protected Audience API, otherwise the automatic beacon is not allowed to be sent to this reporting destination. Please see the Privacy Sandbox enrollment attestation model.

Support for Ad Components

For ad components rendered in fenced frames, the support for event-level reporting described below is available in Chrome starting M114. For ad components rendered in iframes, the support will be available in Chrome starting M115. The support works for all combinations of the top-level ad and ad component being rendered in iframes and/or Fenced Frames.

Goal

When a rendered ad is composed of multiple pieces, it is useful to detect user clicks that happened on ad components.

Design

Event Type and Reporting Destination

For fenced frames rendering the ad components under the top-level ad fenced frame, the automatic beacon event type and corresponding reporting destination registered for the top-level fenced frame are reused when beacons are sent from the ad component fenced frames.

Restricted to send automatic beacons only

  • Invocation of the reportEvent API from an ad component fenced frame is disallowed.
  • The only supported beacons to be sent from an ad component fenced frame are the reserved.top_navigation_start and reserved.top_navigation_commit automatic beacons. Note these beacons are gated on a user activation (e.g. click).
  • To ensure that there is no arbitrary data that can be received at the server from the component ad, the eventData field via window.fence.setReportEventDataForAutomaticBeacons, if specified, will be ignored. This ensures that information from the component ad URL is not revealed in the event report, or else it could lead to the join of two independently k-anonymous URLs (parent and component ad) at the receiving server.
  • Automatic beacons will be sent from a component fenced frame (with no event data) when there is a user activation (e.g. click) on the ad component fenced frame, which results in a top-level navigation. The ad component must still opt in using the Allow-Fenced-Frame-Automatic-Beacons: true response header or invoking setReportEventDataForAutomaticBeacons before the beacon can send.
window.fence.setReportEventDataForAutomaticBeacons({
  'eventType': 'reserved.top_navigation_commit',
  'destination':['seller', 'buyer']
});