Grundlagen der Private Aggregation API

Wichtige Konzepte der Private Aggregation API

An wen richtet sich dieses Dokument?

Mit der Private Aggregation API können aggregierte Daten aus Worklets mit Zugriff auf websiteübergreifende Daten erhoben werden. Die hier beschriebenen Konzepte sind wichtig für Entwickler, die Berichtsfunktionen in der Shared Storage API und der Protected Audience API erstellen.

  • Wenn Sie ein Entwickler sind, der ein Berichtssystem für die websiteübergreifende Analyse erstellt.
  • Wenn Sie Marketer, Data Scientist oder ein anderer Nutzer von Zusammenfassungsberichten sind, können Sie anhand dieser Mechanismen Designentscheidungen treffen, um einen optimierten Zusammenfassungsbericht abzurufen.

Wichtige Begriffe

Bevor Sie dieses Dokument lesen, sollten Sie sich mit den wichtigsten Begriffen und Konzepten vertraut machen. Jeder dieser Begriffe wird hier ausführlich beschrieben.

  • Ein Aggregationsschlüssel (auch als Bucket bezeichnet) ist eine vordefinierte Sammlung von Datenpunkten. Sie möchten beispielsweise eine Sammlung von Standortdaten erstellen, in der der Browser den Ländernamen angibt. Ein Aggregationsschlüssel kann mehrere Dimensionen enthalten, z. B. Land und ID Ihres Content-Widgets.
  • Ein aggregierbarer Wert ist ein einzelner Datenpunkt, der in einem Aggregationsschlüssel erfasst wird. Wenn Sie messen möchten, wie viele Nutzer aus Frankreich Ihre Inhalte gesehen haben, ist France eine Dimension im Aggregationsschlüssel und der viewCount von 1 ist der aggregierbare Wert.
  • Aggregierbare Berichte werden in einem Browser generiert und verschlüsselt. Für die Private Aggregation API enthält dies Daten zu einem einzelnen Ereignis.
  • Der Aggregationsdienst verarbeitet Daten aus aggregierbaren Berichten, um einen Zusammenfassungsbericht zu erstellen.
  • Ein Zusammenfassungsbericht ist die endgültige Ausgabe des Aggregationsdienstes. Er enthält aggregierte Nutzerdaten mit Rauschen und detaillierte Conversion-Daten.
  • Ein Worklet ist ein Infrastrukturteil, mit dem Sie bestimmte JavaScript-Funktionen ausführen und Informationen an den Anfragenden zurückgeben können. Innerhalb eines Worklets können Sie JavaScript ausführen, aber nicht mit der Seite interagieren oder mit ihr kommunizieren.

Workflow für die Private Aggregation API

Wenn Sie die Private Aggregation API mit einem Aggregationsschlüssel und einem aggregierbaren Wert aufrufen, generiert der Browser einen aggregierbaren Bericht. Die Berichte werden an Ihren Server gesendet, der sie in Batches zusammenfasst. Die Batchberichte werden später vom Aggregationsdienst verarbeitet und ein Zusammenfassungsbericht wird generiert.

Die Daten fließen vom Client zum Collector und dann zum Aggregationsdienst, um einen Zusammenfassungsbericht zu erstellen.
Datenfluss vom Client zum Collector
:
  1. Wenn Sie die Private Aggregation API aufrufen, generiert und sendet der Client (Browser) den aggregierbaren Bericht an Ihren Server, damit er erfasst werden kann.
  2. Ihr Server sammelt die Berichte von den Clients und fasst sie in Batches zusammen, die an den Aggregationsdienst gesendet werden.
  3. Sobald Sie genügend Berichte gesammelt haben, fassen Sie sie in einem Batch zusammen und senden Sie sie an den Aggregationsdienst, der in einer vertrauenswürdigen Ausführungsumgebung ausgeführt wird, um einen Zusammenfassungsbericht zu erstellen.

Der in diesem Abschnitt beschriebene Workflow ähnelt der Attribution Reporting API. Beim Attributionsreporting werden jedoch Daten aus einem Impressionsereignis und einem Conversion-Ereignis verknüpft, die zu unterschiedlichen Zeiten stattfinden. Bei der privaten Aggregation wird ein einzelnes, websiteübergreifendes Ereignis analysiert.

Aggregationsschlüssel

Ein Aggregationsschlüssel (kurz „Schlüssel“) stellt den Bucket dar, in dem die aggregierbaren Werte zusammengefasst werden. Eine oder mehrere Dimensionen können im Schlüssel codiert werden. Eine Dimension stellt einen Aspekt dar, zu dem Sie mehr Informationen erhalten möchten, z. B. die Altersgruppe der Nutzer oder die Anzahl der Impressionen einer Werbekampagne.

Angenommen, Sie haben ein Widget, das auf mehreren Websites eingebettet ist, und möchten das Land der Nutzer analysieren, die Ihr Widget gesehen haben. Sie möchten Fragen wie „Wie viele der Nutzer, die mein Widget gesehen haben, stammen aus Land X?“ beantworten. Um diese Frage zu beantworten, können Sie einen Aggregationsschlüssel einrichten, der zwei Dimensionen codiert: Widget-ID und Länder-ID.

Der Schlüssel, der für die Private Aggregation API bereitgestellt wird, ist ein BigInt, der aus mehreren Dimensionen besteht. In diesem Beispiel sind die Dimensionen die Widget-ID und die Länder-ID. Angenommen, die Widget-ID kann bis zu vier Ziffern lang sein, z. B. 1234, und jedes Land wird in alphabetischer Reihenfolge einer Zahl zugeordnet, z. B. Afghanistan ist 1, Frankreich ist 61 und Simbabwe ist 195. Der aggregierbare Schlüssel wäre also 7 Ziffern lang. Die ersten 4 Zeichen sind für WidgetID und die letzten 3 Zeichen für CountryID reserviert.

Angenommen, der Schlüssel steht für die Anzahl der Nutzer aus Frankreich (Landes-ID 061), die die Widget-ID 3276 gesehen haben. Der Aggregationsschlüssel ist 3276061.

Aggregationsschlüssel
Widget-ID Landes-ID
3276 061

Der Aggregationsschlüssel kann auch mit einem Hashing-Mechanismus wie SHA-256 generiert werden. Der String {"WidgetId":3276,"CountryID":67} kann beispielsweise gehasht und dann in einen BigInt-Wert von 42943797454801331377966796057547478208888578253058197330928948081739249096287n umgewandelt werden. Wenn der Hashwert mehr als 128 Bit hat, können Sie ihn kürzen, damit er den maximal zulässigen Bucket-Wert von 2^128−1 nicht überschreitet.

In einem Shared Storage-Worklet können Sie auf die Module crypto und TextEncoder zugreifen, mit denen Sie einen Hash generieren können. Weitere Informationen zum Generieren eines Hash finden Sie unter SubtleCrypto.digest() auf MDN.

Im folgenden Beispiel wird beschrieben, wie Sie einen Bucket-Schlüssel aus einem gehashten Wert generieren können:

async function convertToBucket(data) {
  // Encode as UTF-8 Uint8Array
  const encodedData = new TextEncoder().encode(data);

  // Generate SHA-256 hash
  const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);

  // Truncate the hash
  const truncatedHash = Array.from(new Uint8Array(hashBuffer, 0, 16));

  // Convert the byte sequence to a decimal
  return truncatedHash.reduce((acc, curr) => acc * 256n + BigInt(curr), 0n);
}

const data = {
  WidgetId: 3276,
  CountryID: 67
};

const dataString = JSON.stringify(data);
const bucket = await convertToBucket(dataString);

console.log(bucket); // 126200478277438733997751102134640640264n

Aggregierbarer Wert

Aggregierbare Werte werden für jeden Schlüssel über viele Nutzer hinweg summiert, um aggregierte Statistiken in Form von Zusammenfassungswerten in Zusammenfassungsberichten zu generieren.

Kehren wir nun zur Beispielfrage zurück: „Wie viele der Nutzer, die mein Widget gesehen haben, kommen aus Frankreich?“ Die Antwort auf diese Frage könnte so aussehen: „Ungefähr 4.881 Nutzer, die meine Widget-ID 3276 gesehen haben, stammen aus Frankreich.“ Der aggregierbare Wert ist für jeden Nutzer 1 und „4.881 Nutzer“ ist der aggregierte Wert, der die Summe aller aggregierbaren Werte für diesen Aggregationsschlüssel ist.

Aggregationsschlüssel Aggregierbarer Wert
Widget-ID Landes-ID Anzahl der Aufrufe
3276 061 1

In diesem Beispiel wird der Wert für jeden Nutzer, der das Widget sieht, um 1 erhöht. In der Praxis kann der aggregierbare Wert skaliert werden, um das Signal-Rausch-Verhältnis zu verbessern.

Budget für Beiträge

Jeder Aufruf der Private Aggregation API wird als Beitrag bezeichnet. Zum Schutz der Privatsphäre der Nutzer ist die Anzahl der Beiträge, die von einer einzelnen Person erhoben werden können, begrenzt.

Wenn Sie alle aggregierbaren Werte für alle Aggregationsschlüssel addieren, muss die Summe kleiner als das Beitragsbudget sein. Das Budget wird pro Worklet-Ursprung und pro Tag festgelegt und ist für Protected Audience API- und Shared Storage-Worklets separat. Für den Tag wird ein gleitendes Fenster von etwa den letzten 24 Stunden verwendet. Wenn durch einen neuen aggregierbaren Bericht das Budget überschritten würde, wird der Bericht nicht erstellt.

Das Beitragsbudget wird durch den Parameter L1 dargestellt und ist auf 216 (65.536) pro zehn Minuten pro Tag mit einem Backstop von 220 (1.048.576) festgelegt. Weitere Informationen zu diesen Parametern

Der Wert des Beitragsbudgets ist willkürlich, aber das Rauschen wird daran angepasst. Mit diesem Budget können Sie das Signal-Rausch-Verhältnis für die zusammengefassten Werte maximieren (weitere Informationen finden Sie im Abschnitt Rauschen und Skalierung).

Weitere Informationen zu Beitragsbudgets Weitere Informationen finden Sie unter Beitragsbudget.

Beitragslimit pro Bericht

Je nach Anrufer kann das Beitragslimit unterschiedlich sein. Bei Shared Storage sind diese Limits Standardwerte, die überschrieben werden können. Derzeit sind Berichte, die für Aufrufer der Shared Storage API generiert werden, auf 20 Beiträge pro Bericht begrenzt. Andererseits ist die Anzahl der Beiträge pro Bericht für Aufrufer der Protected Audience API auf 100 begrenzt. Diese Grenzwerte wurden so gewählt, dass die Anzahl der eingebetteten Beiträge und die Größe der Nutzlast in einem ausgewogenen Verhältnis stehen.

Bei Shared Storage werden Beiträge, die im Rahmen eines einzelnen run()- oder selectURL()-Vorgangs erfolgen, in einem Bericht zusammengefasst. Bei Protected Audience werden Beiträge eines einzelnen Ursprungs innerhalb einer Auktion zusammengefasst.

Beiträge mit Padding

Beiträge werden durch eine Padding-Funktion weiter modifiziert. Durch das Auffüllen der Nutzlast werden Informationen zur tatsächlichen Anzahl der Beiträge im aggregierbaren Bericht geschützt. Durch das Auffüllen wird die Nutzlast mit null Beiträgen (d. h. mit dem Wert 0) auf eine feste Länge gebracht.

Zusammenfassbare Berichte

Sobald der Nutzer die Private Aggregation API aufruft, generiert der Browser aggregierbare Berichte, die später vom Aggregation Service verarbeitet werden, um Zusammenfassungsberichte zu erstellen. Ein aggregierbarer Bericht ist im JSON-Format und enthält eine verschlüsselte Liste von Beiträgen, die jeweils ein {aggregation key, aggregatable value}-Paar sind. Aggregierbare Berichte werden mit einer zufälligen Verzögerung von bis zu einer Stunde gesendet.

Die Beiträge sind verschlüsselt und können außerhalb des Aggregation Service nicht gelesen werden. Der Aggregationsdienst entschlüsselt die Berichte und erstellt einen Zusammenfassungsbericht. Der Verschlüsselungsschlüssel für den Browser und der Entschlüsselungsschlüssel für den Aggregation Service werden vom Koordinator ausgestellt, der als Key Management Service fungiert. Der Koordinator führt eine Liste der binären Hashes des Dienst-Images, um zu prüfen, ob der Aufrufer den Entschlüsselungsschlüssel empfangen darf.

Beispiel für einen aggregierbaren Bericht mit aktiviertem Debug-Modus:

  "aggregation_service_payloads": [
    {
      "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAE0mlvcGVyYXRpb25paGlzdG9ncmFt",
      "key_id": "2cc72b6a-b92f-4b78-b929-e3048294f4d6",
      "payload": "a9Mk3XxvnfX70FsKrzcLNZPy+00kWYnoXF23ZpNXPz/Htv1KCzl/exzplqVlM/wvXdKUXCCtiGrDEL7BQ6MCbQp1NxbWzdXfdsZHGkZaLS2eF+vXw2UmLFH+BUg/zYMu13CxHtlNSFcZQQTwnCHb"
    }
  ],
  "debug_key": "777",
  "shared_info": "{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"5bc74ea5-7656-43da-9d76-5ea3ebb5fca5\",\"reporting_origin\":\"https://localhost:4437\",\"scheduled_report_time\":\"1664907229\",\"version\":\"0.1\"}"

Die zusammenfassbaren Berichte können auf der Seite chrome://private-aggregation-internals eingesehen werden:

Seite mit Interna der Private Aggregation API
Seite „Private Aggregation API internals“

Zu Testzwecken kann die Schaltfläche „Ausgewählte Berichte senden“ verwendet werden, um den Bericht sofort an den Server zu senden.

Zusammenfassbare Berichte erfassen und in Batches zusammenfassen

Der Browser sendet die aggregierbaren Berichte an den Ursprung des Worklets, das den Aufruf der Private Aggregation API enthält, über den aufgeführten bekannten Pfad:

  • Für Shared Storage: /.well-known/private-aggregation/report-shared-storage
  • Für Protected Audience: /.well-known/private-aggregation/report-protected-audience

An diesen Endpunkten benötigen Sie einen Server, der als Collector fungiert und die von den Clients gesendeten aggregierbaren Berichte empfängt.

Der Server sollte dann Berichte in Batches zusammenfassen und den Batch an den Aggregationsdienst senden. Erstellen Sie Batches basierend auf den Informationen, die in der unverschlüsselten Nutzlast des aggregierbaren Berichts verfügbar sind, z. B. im Feld shared_info. Idealerweise sollten die Batches mindestens 100 Berichte enthalten.

Sie können die Batch-Verarbeitung täglich oder wöchentlich durchführen. Diese Strategie ist flexibel. Sie können die Batching-Strategie für bestimmte Ereignisse ändern, bei denen Sie mit einem höheren Volumen rechnen, z. B. an Tagen des Jahres, an denen mehr Impressionen erwartet werden. Batches sollten Berichte mit derselben API-Version, demselben Berichtsursprung und derselben geplanten Berichtszeit enthalten.

Filter-IDs

Mit der Private Aggregation API und dem Aggregation Service können Filter-IDs verwendet werden, um Messungen auf einer detaillierteren Ebene zu verarbeiten, z. B. pro Werbekampagne, anstatt die Ergebnisse in größeren Abfragen zu verarbeiten.

Private Aggregation und Filter-IDs für den Aggregationsdienst.
Private Aggregation API und Aggregation Service-Filter-IDs

Hier sind einige grobe Schritte, die Sie auf Ihre aktuelle Implementierung anwenden können, um die Funktion noch heute zu nutzen.

Schritte für Shared Storage

Wenn Sie die Shared Storage API in Ihrem Ablauf verwenden:

  1. Definieren Sie, wo Sie Ihr neues Shared Storage-Modul deklarieren und ausführen möchten. Im folgenden Beispiel haben wir die Moduldatei filtering-worklet.js genannt und unter filtering-example registriert.

    (async function runFilteringIdsExample () {
    await window.sharedStorage.worklet.addModule('filtering-worklet.js');
    await window.sharedStorage.run('filtering-example', {
      keepAlive: true,
      privateAggregationConfig: {
        contextId: 'example-id',
        filteringIdMaxBytes: 8 // optional
      }
    }});
    })();
    

    filteringIdMaxBytes kann für jeden Bericht konfiguriert werden. Wenn sie nicht festgelegt ist, wird standardmäßig 1 verwendet. Dieser Standardwert soll verhindern, dass die Nutzlastgröße und damit die Speicher- und Verarbeitungskosten unnötig steigen. Weitere Informationen

  2. Wenn Sie in filtering-worklet.js einen Beitrag an privateAggregation.contributeToHistogram(...) im Shared Storage-Worklet übergeben, können Sie eine Filter-ID angeben.

    // Within  filtering-worklet.js
    class FilterOperation {
      async run() {
        let contributions = [{
          bucket: 1234n,
          value: 56,
          filteringId: 3n // defaults to 0n if not assigned, type bigint
        }];
    
        for (const c of contributions) {
          privateAggregation.contributeToHistogram(c);
        }
        
    }
    });
    
    register('filtering-example', FilterOperation);
    
  3. Aggregierbare Berichte werden an den von Ihnen definierten Endpunkt /.well-known/private-aggregation/report-shared-storage gesendet. Weitere Informationen zu den erforderlichen Änderungen an den Jobparametern des Aggregationsdienstes

Nachdem die Batchverarbeitung abgeschlossen und an den bereitgestellten Aggregationsdienst gesendet wurde, sollten die gefilterten Ergebnisse im endgültigen Zusammenfassungsbericht angezeigt werden.

Protected Audience-Schritte

Wenn Sie die Protected Audience API in Ihrem Ablauf verwenden:

  1. In Ihrer aktuellen Implementierung von Protected Audience können Sie Folgendes festlegen, um Private Aggregation zu nutzen. Im Gegensatz zu Shared Storage ist es noch nicht möglich, die maximale Größe der Filter-ID zu konfigurieren. Standardmäßig beträgt die maximale Größe der Filter-ID 1 Byte und wird auf 0n festgelegt. Diese werden in Ihren Protected Audience-Berichtsfunktionen (z. B. reportResult() oder generateBid()) festgelegt.

    const contribution = {
      ...
      filteringId: 0n
    };
    
    privateAggregation.contributeToHistogram(contribution);
    
  2. Aggregierbare Berichte werden an den von Ihnen definierten Endpunkt /.well-known/private-aggregation/report-protected-audience gesendet. Nachdem die Batchverarbeitung abgeschlossen und an den bereitgestellten Aggregationsdienst gesendet wurde, sollten die gefilterten Ergebnisse im endgültigen Zusammenfassungsbericht angezeigt werden. Die folgenden Erklärungen für die Attribution Reporting API und die Private Aggregation API sind verfügbar, ebenso wie der ursprüngliche Vorschlag.

Weitere Informationen finden Sie in unserem Leitfaden zum Filtern von IDs im Aggregation Service oder in den Abschnitten zur Attribution Reporting API.

Zusammenfassungsdienst

Der Dienst wird in einer TEE ausgeführt, entschlüsselt die aggregierbaren Berichte und fügt Rauschen hinzu, um den endgültigen Zusammenfassungsbericht zu erstellen.
Der Dienst wird in einer TEE ausgeführt, entschlüsselt die aggregierbaren Berichte und fügt Rauschen hinzu, um den endgültigen Zusammenfassungsbericht zu erstellen.

Der Aggregationsdienst empfängt verschlüsselte aggregierbare Berichte vom Collector und generiert Zusammenfassungsberichte. Weitere Strategien zum Batch-Aggregieren von Berichten in Ihrem Collector finden Sie in unserem Batching-Leitfaden.

Der Dienst wird in einer vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) ausgeführt, die ein gewisses Maß an Sicherheit für Datenintegrität, Datenvertraulichkeit und Codeintegrität bietet. Wenn Sie mehr darüber erfahren möchten, wie Koordinatoren zusammen mit TEEs verwendet werden, lesen Sie hier mehr über ihre Rolle und ihren Zweck.

Zusammenfassende Berichte

In Zusammenfassungsberichten können Sie die Daten sehen, die Sie mit hinzugefügtem Rauschen erhoben haben. Sie können Zusammenfassungsberichte für eine bestimmte Gruppe von Schlüsseln anfordern.

Ein Übersichtsbericht enthält eine Reihe von Schlüssel/Wert-Paaren im JSON-Wörterbuchstil. Jedes Paar enthält:

  • bucket: Der Aggregationsschlüssel als binärer Zahlenstring. Wenn der verwendete Aggregationsschlüssel „123“ ist, lautet der Bucket „1111011“.
  • value: Der zusammengefasste Wert für ein bestimmtes Zielvorhaben, der aus allen verfügbaren aggregierbaren Berichten mit hinzugefügtem Rauschen summiert wird.

Beispiel:

[
  {"bucket":` `"111001001",` `"value":` `"2558500"},
  {"bucket":` `"111101001",` `"value":` `"3256211"},
  {"bucket":` `"111101001",` `"value":` `"6536542"},
]

Rauschen und Skalierung

Um die Privatsphäre der Nutzer zu schützen, fügt der Aggregationsdienst jedem Zusammenfassungswert einmal Rauschen hinzu, wenn ein Zusammenfassungsbericht angefordert wird. Die Nebengeräuschwerte werden zufällig aus einer Laplace-Wahrscheinlichkeitsverteilung gezogen. Sie haben zwar keinen direkten Einfluss darauf, wie Rauschen hinzugefügt wird, können aber die Auswirkungen von Rauschen auf die Messdaten beeinflussen.

Die Rauschverteilung ist unabhängig von der Summe aller aggregierbaren Werte. Je höher die aggregierbaren Werte sind, desto geringer sind die Auswirkungen des Rauschens.

Angenommen, die Rauschverteilung hat eine Standardabweichung von 100 und ist auf null zentriert. Wenn der erfasste aggregierbare Berichtswert (oder „aggregatable value“) nur 200 beträgt, würde die Standardabweichung des Rauschens 50% des aggregierten Werts betragen. Wenn der aggregierbare Wert jedoch 20.000 ist, beträgt die Standardabweichung des Rauschens nur 0,5% des aggregierten Werts. Der aggregierbare Wert von 20.000 hätte also ein viel höheres Signal-Rausch-Verhältnis.

Wenn Sie Ihren aggregierbaren Wert mit einem Skalierungsfaktor multiplizieren, können Sie das Rauschen reduzieren. Der Skalierungsfaktor gibt an, um wie viel Sie einen bestimmten aggregierbaren Wert skalieren möchten.

Das Rauschen ist unabhängig vom aggregierten Wert konstant.
Rauschen ist unabhängig vom aggregierten Wert konstant.

Wenn Sie die Werte mit einem größeren Skalierungsfaktor skalieren, wird das relative Rauschen verringert. Dadurch wird jedoch auch die Summe aller Beiträge in allen Gruppen schneller erreicht. Wenn Sie die Werte durch Auswahl einer kleineren Skalierungsfaktorkonstante herunterskalieren, erhöht sich das relative Rauschen, aber das Risiko, das Budgetlimit zu erreichen, sinkt.

Skalieren Sie den aggregierbaren Wert auf das Beitragsbudget.
Aggregierbaren Wert auf das Beitragsbudget abstimmen
:

Um einen geeigneten Skalierungsfaktor zu berechnen, teilen Sie das Beitragbudget durch die maximale Summe der aggregierbaren Werte für alle Schlüssel.

Weitere Informationen finden Sie in der Dokumentation zum Beitragsbudget.

Feedback geben

Die Private Aggregation API befindet sich in der aktiven Diskussion und kann sich in Zukunft ändern. Wenn Sie diese API ausprobieren und Feedback haben, freuen wir uns darauf.