Principes de base de l'API Private Agrégation

Concepts clés de l'API Private Aggregation

À qui s'adresse ce document ?

L'API Private Aggregation permet de collecter des données agrégées à partir de Worklets ayant accès à des données intersites. Les concepts partagés ici sont importants pour les développeurs qui créent des fonctions de reporting dans le stockage partagé et l'API Protected Audience.

  • Si vous êtes un développeur, vous créez un système de création de rapports pour les mesures intersites.
  • Si vous êtes un marketeur, un data scientist ou un autre consommateur de rapports récapitulatifs, comprendre ces mécanismes vous aidera à prendre des décisions de conception pour récupérer un rapport récapitulatif optimisé.

Termes clés

Avant de lire ce document, il peut être utile de vous familiariser avec les termes et concepts clés. Chacun de ces termes est décrit en détail ici.

  • Une clé d'agrégation (également appelée "bucket") est un ensemble prédéterminé de points de données. Par exemple, vous pouvez collecter un bucket de données de localisation dans lequel le navigateur indique le nom du pays. Une clé d'agrégation peut contenir plusieurs dimensions (par exemple, le pays et l'ID de votre widget de contenu).
  • Une valeur agrégable est un point de données individuel collecté dans une clé d'agrégation. Si vous souhaitez mesurer le nombre d'utilisateurs français qui ont vu votre contenu, France est une dimension de la clé d'agrégation, et le viewCount de 1 est la valeur agrégable.
  • Les rapports agrégables sont générés et chiffrés dans un navigateur. Pour l'API Private Aggregation, il contient des données sur un seul événement.
  • Le service d'agrégation traite les données de rapports agrégables pour créer un rapport récapitulatif.
  • Un rapport récapitulatif est la sortie finale du service d'agrégation. Il contient des données utilisateur agrégées avec bruit et des données de conversion détaillées.
  • Un worklet est un élément d'infrastructure qui vous permet d'exécuter des fonctions JavaScript spécifiques et de renvoyer des informations au demandeur. Dans un worklet, vous pouvez exécuter du code JavaScript, mais vous ne pouvez pas interagir ni communiquer avec la page externe.

Workflow d'agrégation privée

Lorsque vous appelez l'API Private Aggregation avec une clé d'agrégation et une valeur agrégable, le navigateur génère un rapport agrégable. Les rapports sont envoyés à votre serveur qui les regroupe par lot. Les rapports par lot sont traités ultérieurement par le service d'agrégation, puis un rapport récapitulatif est généré.

Les données circulent du client vers le collecteur, puis vers le service d'agrégation pour générer un rapport récapitulatif.
  1. Lorsque vous appelez l'API Private Aggregation, le client (navigateur) génère et envoie le rapport agrégable à votre serveur pour qu'il soit collecté.
  2. Le serveur collecte les rapports des clients et les regroupe par lots pour les envoyer au service d'agrégation.
  3. Une fois que vous avez collecté suffisamment de rapports, vous pouvez les regrouper et les envoyer au service d'agrégation, qui s'exécute dans un environnement d'exécution approuvé, pour générer un rapport récapitulatif.

Le workflow décrit dans cette section est semblable à l'API Attribution Reporting. Toutefois, Attribution Reporting associe les données collectées à partir d'un événement d'impression et d'un événement de conversion, qui se produisent à des moments différents. L'agrégation privée mesure un seul événement intersite.

Clé d'agrégation

Une clé d'agrégation ("clé" en abrégé) représente le bucket dans lequel les valeurs agrégables seront accumulées. Une ou plusieurs dimensions peuvent être encodées dans la clé. Une dimension représente un aspect sur lequel vous souhaitez obtenir plus d'informations, comme la tranche d'âge des utilisateurs ou le nombre d'impressions d'une campagne publicitaire.

Par exemple, si vous avez un widget intégré sur plusieurs sites et que vous souhaitez analyser le pays des utilisateurs qui l'ont vu, Vous souhaitez obtenir des réponses à des questions telles que "Combien d'utilisateurs ayant vu mon widget viennent du pays X ?". Pour générer un rapport sur cette question, vous pouvez configurer une clé d'agrégation qui encode deux dimensions: l'ID de widget et l'ID de pays.

La clé fournie à l'API Private Aggregation est une clé BigInt composée de plusieurs dimensions. Dans cet exemple, les dimensions sont l'ID du widget et l'ID du pays. Imaginons que l'ID de widget puisse comporter jusqu'à quatre chiffres (par exemple, 1234) et que chaque pays est associé à un nombre alphabétique (par exemple, l'Afghanistan correspond à 1, la France à 61 et le Zimbabwe à "195"). Par conséquent, la clé agrégable comporte sept chiffres, les quatre premiers caractères étant réservés à WidgetID et les trois derniers à CountryID.

Supposons que la clé représente le nombre d'utilisateurs de France (ID de pays 061) qui ont vu l'ID de widget 3276. La clé d'agrégation est 3276061.

Clé d'agrégation
ID du widget ID du pays
3276 061

La clé d'agrégation peut également être générée avec un mécanisme de hachage, tel que SHA-256. Par exemple, la chaîne {"WidgetId":3276,"CountryID":67} peut être hachée, puis convertie en une valeur BigInt de 42943797454801331377966796057547478208888578253058197330928948081739249096287n. Si la valeur de hachage comporte plus de 128 bits, vous pouvez la tronquer pour vous assurer qu'elle ne dépasse pas la valeur maximale autorisée de 2^128−1 dans le bucket.

Dans un worklet de stockage partagé, vous pouvez accéder aux modules crypto et TextEncoder qui peuvent vous aider à générer un hachage. Pour en savoir plus sur la génération d'un hachage, consultez la page SubtleCrypto.digest() sur le MN.

L'exemple suivant explique comment générer une clé de bucket à partir d'une valeur hachée:

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

Valeur agrégable

Les valeurs agrégables sont additionnées par clé pour de nombreux utilisateurs afin de générer des insights agrégés sous la forme de valeurs récapitulatives dans les rapports récapitulatifs.

Revenons à l'exemple de question posé précédemment: "Combien d'utilisateurs ayant vu mon widget viennent de France ?". La réponse à cette question ressemblera à quelque chose comme : "Environ 4 881 utilisateurs qui ont vu mon ID de widget 3276 sont originaires de France". La valeur agrégable est 1 pour chaque utilisateur, et "4 881 utilisateurs" est la valeur agrégée, c'est-à-dire la somme de toutes les valeurs agrégables pour cette clé d'agrégation.

Clé d'agrégation Valeur agrégable
ID du widget ID du pays Nombre de vues
3276 061 1

Dans cet exemple, nous incrémentons la valeur de 1 pour chaque utilisateur qui voit le widget. En pratique, la valeur agrégable peut être ajustée pour améliorer le ratio signal sur bruit.

Budget de contribution

Chaque appel à l'API Private Aggregation est appelé une contribution. Pour protéger la confidentialité des utilisateurs, le nombre de contributions pouvant être collectées auprès d'un individu est limité.

Lorsque vous additionnez toutes les valeurs agrégables de toutes les clés d'agrégation, la somme doit être inférieure au budget de contribution. Le budget est défini par origine et par jour de Worklet. Il est distinct pour l'API Protected Audience et les Worklets de stockage partagé. Une période glissante d'environ 24 heures est utilisée pour la journée. Si un nouveau rapport agrégable entraîne le dépassement du budget, le rapport n'est pas créé.

Le budget de contribution est représenté par le paramètre L1 et est défini sur 216 (65 536) par 10 minutes et par jour, avec un backstop de 220.

1 048 576. Pour en savoir plus sur ces paramètres, consultez l'explication.

La valeur du budget de contribution est arbitraire, mais le bruit est ajusté en conséquence. Vous pouvez utiliser ce budget pour maximiser le rapport signal sur bruit sur les valeurs récapitulatives (décrites plus en détail dans la section Bruit et mise à l'échelle).

Pour en savoir plus sur les budgets de contribution, consultez l'explication. Pour en savoir plus, consultez également Budget de contribution.

Rapports agrégables

Une fois que l'utilisateur a appelé l'API Private Aggregation, le navigateur génère des rapports agrégables qui seront traités ultérieurement par le service d'agrégation pour générer des rapports récapitulatifs. Un rapport agrégable est au format JSON et contient une liste chiffrée de contributions, chacune correspondant à une paire {aggregation key, aggregatable value}. Les rapports agrégables sont envoyés avec un délai aléatoire pouvant atteindre une heure.

Les contributions sont chiffrées et il est difficile de les lire en dehors du service d'agrégation. Le service d'agrégation déchiffre les rapports et génère un rapport récapitulatif. La clé de chiffrement pour le navigateur et la clé de déchiffrement pour le service d'agrégation sont émises par le coordinateur, qui agit en tant que service de gestion des clés. Le coordinateur conserve une liste de hachages binaires de l'image du service pour vérifier que l'appelant est autorisé à recevoir la clé de déchiffrement.

Exemple de rapport agrégable avec le mode débogage activé:

  "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\"}"

Les rapports agrégables peuvent être inspectés à partir de la page chrome://private-aggregation-internals:

Capture d'écran de la page "Informations internes" de l'API Private Aggregation

À des fins de test, vous pouvez utiliser le bouton "Envoyer les rapports sélectionnés" pour envoyer immédiatement le rapport au serveur.

Collecter et regrouper les rapports agrégables

Le navigateur envoie les rapports agrégables à l'origine du worklet contenant l'appel à l'API Private Aggregation, en utilisant le chemin d'accès connu listé:

  • Pour le stockage partagé: /.well-known/private-aggregation/report-shared-storage
  • Pour Protected Audience : /.well-known/private-aggregation/report-protected-audience

Sur ces points de terminaison, vous devez exploiter un serveur (agissant en tant que collecteur) qui reçoit les rapports agrégables envoyés par les clients.

Le serveur doit ensuite traiter les rapports par lot et les envoyer au service d'agrégation. Créez des lots en fonction des informations disponibles dans la charge utile non chiffrée du rapport agrégable, telle que le champ shared_info. Idéalement, les lots doivent contenir au moins 100 rapports par lot.

Vous pouvez décider d'effectuer un traitement par lot sur une base quotidienne ou hebdomadaire. Cette stratégie est flexible et vous permet de modifier votre stratégie de traitement par lot pour des événements spécifiques pour lesquels vous prévoyez un volume plus important (par exemple, les jours de l'année où le nombre d'impressions est attendu). Les lots doivent inclure des rapports issus de la même version d'API, de la même origine de création et de la même heure de planification des rapports.

Service d'agrégation

Le service s'exécute dans un TEE, déchiffre les rapports agrégables et ajoute du bruit pour créer le rapport récapitulatif final.

Le service d'agrégation reçoit des rapports agrégables chiffrés de la part du collecteur et génère des rapports récapitulatifs.

Pour déchiffrer la charge utile du rapport, le service d'agrégation récupère une clé de déchiffrement auprès du coordinateur. Le service s'exécute dans un environnement d'exécution sécurisé (TEE), qui fournit un niveau d'assurance de l'intégrité, de la confidentialité et du code des données. Bien que vous soyez le propriétaire et l'exploitant du service, vous n'avez aucune visibilité sur les données en cours de traitement dans le TEE.

Rapports de synthèse

Les rapports récapitulatifs vous permettent de consulter les données que vous avez collectées en ajoutant du bruit. Vous pouvez demander des rapports récapitulatifs pour un ensemble donné de clés.

Un rapport récapitulatif contient un ensemble de paires clé/valeur de style dictionnaire JSON. Chaque paire contient:

  • bucket: clé d'agrégation sous forme de chaîne numérique binaire. Si la clé d'agrégation utilisée est "123", le bucket correspond à "1111011".
  • value: valeur récapitulative pour un objectif de mesure donné, calculée à partir de tous les rapports agrégables disponibles avec le bruit ajouté.

Exemple :

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

Bruit et scaling

Pour préserver la confidentialité des utilisateurs, le service d'agrégation ajoute du bruit une fois à chaque valeur récapitulative chaque fois qu'un rapport récapitulatif est demandé. Les valeurs de bruit sont tirées de manière aléatoire à partir d'une distribution de probabilité de Laplace. Bien que vous ne puissiez pas contrôler directement la manière dont le bruit est ajouté, vous pouvez influer sur son impact sur ses données de mesure.

La distribution du bruit est la même, quelle que soit la somme de toutes les valeurs agrégables. Par conséquent, plus les valeurs agrégables sont élevées, moins l'impact du bruit est susceptible d'avoir.

Par exemple, supposons que la distribution du bruit ait un écart type de 100 et qu'elle soit centrée sur zéro. Si la valeur du rapport agrégable collecté (ou "valeur agrégable") n'est que de 200, l'écart type du bruit sera égal à 50% de la valeur agrégée. Toutefois, si la valeur agrégable est de 20 000,l'écart type du bruit n'est que de 0, 5% de la valeur agrégée. La valeur agrégable de 20 000 présenterait donc un rapport signal sur bruit beaucoup plus élevé.

Par conséquent, la multiplication de votre valeur agrégable par un facteur de scaling peut aider à réduire le bruit. Le facteur de scaling représente le scaling que vous souhaitez appliquer à une valeur agrégable donnée.

Le bruit est constant, quelle que soit la valeur agrégée.

La mise à l'échelle des valeurs en choisissant un facteur de scaling plus élevé réduit le bruit relatif. Toutefois, cela permet également à la somme de toutes les contributions de tous les buckets d'atteindre plus rapidement la limite du budget de contribution. Réduire les valeurs en choisissant une constante de facteur de scaling plus faible augmente le bruit relatif, mais réduit le risque d'atteindre la limite budgétaire.

Adaptez la valeur agrégable au budget de contribution.

Pour calculer un facteur de scaling approprié, divisez le budget de contribution par la somme maximale des valeurs agrégables pour toutes les clés.

Pour en savoir plus, consultez la documentation sur le budget de contribution.

Interagir et donner votre avis

L'API Private Aggregation est en cours de discussion et est susceptible d'être modifiée à l'avenir. Si vous essayez cette API et que vous avez des commentaires, n'hésitez pas à nous en faire part.