Основы API частной агрегации

Ключевые понятия API частного агрегирования

Для кого предназначен этот документ?

API частного агрегирования позволяет собирать агрегированные данные из рабочих модулей с доступом к межсайтовым данным. Представленные здесь концепции важны для разработчиков, создающих функции отчетности в рамках Shared Storage и Protected Audience API.

  • Если вы разработчик, создающий систему отчетности для межсайтового измерения.
  • Если вы маркетолог , специалист по данным или другой потребитель сводных отчетов , понимание этих механизмов поможет вам принять проектные решения для получения оптимизированного сводного отчета.

Ключевые термины

Прежде чем читать этот документ, будет полезно ознакомиться с ключевыми терминами и понятиями. Каждый из этих терминов будет описан здесь подробно.

  • Ключ агрегирования (также известный как сегмент) — это заранее определенный набор точек данных. Например, вы можете захотеть собрать набор данных о местоположении, в котором браузер сообщает название страны. Ключ агрегирования может содержать более одного измерения (например, страну и идентификатор вашего виджета контента).
  • Агрегируемое значение — это отдельная точка данных, собранная в ключ агрегации. Если вы хотите измерить, сколько пользователей из Франции просмотрели ваш контент, то France — это измерение в ключе агрегирования, а значение viewCount равное 1 — это агрегируемое значение.
  • Агрегированные отчеты генерируются и шифруются в браузере. Для API частного агрегирования он содержит данные об одном событии.
  • Служба агрегации обрабатывает данные из агрегированных отчетов для создания сводного отчета.
  • Сводный отчет — это окончательный результат работы службы агрегирования. Он содержит зашумленные агрегированные пользовательские данные и подробные данные о конверсиях.
  • Worklet — это часть инфраструктуры, которая позволяет запускать определенные функции JavaScript и возвращать информацию отправителю запроса. Внутри ворлета вы можете выполнять JavaScript, но не можете взаимодействовать или общаться с внешней страницей.

Рабочий процесс частного агрегирования

Когда вы вызываете Private Aggregation API с ключом агрегации и агрегируемым значением, браузер генерирует агрегируемый отчет. Отчеты отправляются на ваш сервер, который группирует отчеты. Пакетные отчеты позже обрабатываются службой агрегирования, и создается сводный отчет.

Данные передаются от клиента к сборщику, а затем к агрегатору.     Сервис для формирования сводного отчета.
  1. Когда вы вызываете API частного агрегирования, клиент (браузер) генерирует и отправляет агрегированный отчет на ваш сервер для сбора.
  2. Ваш сервер собирает отчеты от клиентов и группирует их для отправки в службу агрегации.
  3. Собрав достаточное количество отчетов, вы группируете их и отправляете в службу агрегации, работающую в доверенной среде выполнения, для создания сводного отчета.

Рабочий процесс, описанный в этом разделе, аналогичен API отчетов по атрибуции . Однако отчеты по атрибуции связывают данные, собранные в результате показа и события-конверсии, которые происходят в разное время. Частное агрегирование измеряет одно межсайтовое событие.

Ключ агрегирования

Ключ агрегирования (сокращенно «ключ») представляет собой сегмент, в котором будут накапливаться агрегируемые значения. В ключе могут быть закодированы одно или несколько измерений. Измерение представляет собой некоторый аспект, о котором вы хотите получить более подробную информацию, например возрастную группу пользователей или количество показов рекламной кампании.

Например, у вас может быть виджет, встроенный в несколько сайтов, и вы хотите проанализировать страну пользователей, которые видели ваш виджет. Вы хотите ответить на такие вопросы, как «Сколько пользователей, которые видели мой виджет, были из страны X?» Чтобы сообщить об этом вопросе, вы можете настроить ключ агрегирования, который кодирует два измерения: идентификатор виджета и идентификатор страны.

Ключ, предоставляемый API частного агрегирования, — это BigInt , который состоит из нескольких измерений. В этом примере измерениями являются идентификатор виджета и идентификатор страны. Предположим, что идентификатор виджета может иметь длину до 4 цифр, например 1234 , и каждая страна сопоставлена ​​с номером в алфавитном порядке, например, Афганистан — 1 , Франция — 61 , а Зимбабве — 195 . Таким образом, совокупный ключ будет состоять из 7 цифр, где первые 4 символа зарезервированы для WidgetID , а последние 3 символа зарезервированы для CountryID .

Допустим, ключ представляет собой количество пользователей из Франции (идентификатор страны 061 ), которые видели виджет с идентификатором 3276 Ключ агрегирования — 3276061 .

Ключ агрегирования
Идентификатор виджета Идентификатор страны
3276 061

Ключ агрегации также может быть сгенерирован с помощью механизма хеширования, например SHA-256 . Например, строку {"WidgetId":3276,"CountryID":67} можно хешировать, а затем преобразовать в значение BigInt 42943797454801331377966796057547478208888578253058197330928948081739249096287n . Если хеш-значение имеет длину более 128 бит, вы можете усечь его, чтобы гарантировать, что оно не превысит максимально допустимое значение сегмента 2^128−1 .

В рамках ворлета Shared Storage вы можете получить доступ к модулям crypto и TextEncoder , которые помогут вам сгенерировать хэш. Чтобы узнать больше о создании хеша, ознакомьтесь с SubtleCrypto.digest() на MDN .

В следующем примере показано, как сгенерировать ключ сегмента из хешированного значения:

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

Агрегированная стоимость

Агрегированные значения суммируются по ключам для многих пользователей для получения агрегированной информации в форме сводных значений в сводных отчетах.

Теперь вернемся к примеру вопроса, заданному ранее: «Сколько пользователей, увидевших мой виджет, из Франции?» Ответ на этот вопрос будет выглядеть примерно так: «Приблизительно 4881 пользователь, который видел мой виджет с идентификатором 3276, из Франции». Агрегируемое значение равно 1 для каждого пользователя, а «4881 пользователь» — это агрегированное значение , представляющее собой сумму всех агрегируемых значений для этого ключа агрегирования .

Ключ агрегирования Агрегированная стоимость
Идентификатор виджета Идентификатор страны Количество просмотров
3276 061 1

В этом примере мы увеличиваем значение на 1 для каждого пользователя, который видит виджет. На практике агрегируемое значение можно масштабировать для улучшения отношения сигнал/шум .

Бюджет взносов

Каждый вызов API частного агрегирования называется вкладом . Для защиты конфиденциальности пользователей количество пожертвований, которые могут быть получены от отдельных лиц, ограничено.

При суммировании всех агрегируемых значений по всем ключам агрегирования сумма должна быть меньше бюджета вклада. Бюджет определяется для каждого источника ворлета в день и является отдельным для ворлетов Protected Audience API и Shared Storage. В течение дня используется скользящее окно примерно за последние 24 часа. Если новый агрегированный отчет приведет к превышению бюджета, отчет не создается.

Бюджет вклада представлен параметром L 1 и установлен на уровне 2 16 (65 536) за десять минут в день с ограничением обратного хода 2 20 (1 048 576). Дополнительную информацию об этих параметрах см. в пояснении .

Значение бюджета вклада произвольно, но к нему масштабируется шум. Вы можете использовать этот бюджет для максимизации отношения сигнал/шум в сводных значениях (подробнее обсуждается в разделе «Шум и масштабирование »).

Дополнительную информацию о бюджетах взносов см. в пояснении . Кроме того, дополнительные рекомендации см. в разделе «Бюджет взносов» .

Лимит вклада на отчет

В зависимости от звонящего лимит взноса может отличаться. В настоящее время отчеты, созданные для вызывающих API Shared Storage API, ограничены 20 вкладами на отчет. С другой стороны, пользователи, вызывающие API Protected Audience, ограничены 100 вкладами на отчет. Эти ограничения были выбраны, чтобы сбалансировать количество вкладов, которые можно внедрить, в зависимости от размера полезной нагрузки.

Для общего хранилища данные, внесенные в рамках одной операции run() или selectURL() объединяются в один отчет. Для Защищенной аудитории вклады, внесенные одним источником в рамках аукциона, объединяются вместе.

Вклады с дополнением

Вклады дополнительно изменяются с помощью функции заполнения. Заполнение полезных данных защищает информацию об истинном количестве вкладов, включенную в сводный отчет. Заполнение дополняет полезную нагрузку null вкладами (т. е. значением 0) для достижения фиксированной длины.

Агрегированные отчеты

Как только пользователь вызывает API частного агрегирования, браузер генерирует агрегированные отчеты, которые позднее обрабатываются службой агрегации для создания сводных отчетов . Агрегируемый отчет имеет формат JSON и содержит зашифрованный список вкладов, каждый из которых представляет собой пару {aggregation key, aggregatable value} . Агрегированные отчеты отправляются со случайной задержкой до одного часа.

Вклады зашифрованы и не могут быть прочитаны за пределами Службы агрегирования. Служба агрегации расшифровывает отчеты и формирует сводный отчет. Ключ шифрования для браузера и ключ дешифрования для службы агрегации выдаются координатором, который действует как служба управления ключами. Координатор хранит список двоичных хешей образа службы, чтобы убедиться, что вызывающему абоненту разрешено получить ключ дешифрования.

Пример агрегированного отчета с включенным режимом отладки :

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

Агрегированные отчеты можно просмотреть на странице chrome://private-aggregation-internals :

снимок экрана страницы внутренних компонентов API частного агрегирования

В целях тестирования можно использовать кнопку «Отправить выбранные отчеты», чтобы немедленно отправить отчет на сервер.

Собирайте и группируйте агрегированные отчеты

Браузер отправляет агрегированные отчеты в источник ворлета, содержащего вызов API частного агрегирования, используя указанный общеизвестный путь:

  • Для общего хранилища: /.well-known/private-aggregation/report-shared-storage
  • Для защищенной аудитории: /.well-known/private-aggregation/report-protected-audience

На этих конечных точках вам потребуется использовать сервер, действующий как сборщик, который получает агрегированные отчеты, отправленные от клиентов.

Затем сервер должен пакетировать отчеты и отправлять их в службу агрегации. Создавайте пакеты на основе информации, доступной в незашифрованных полезных данных агрегируемого отчета, например shared_info . В идеале пакеты должны содержать 100 или более отчетов в каждом пакете.

Вы можете выбрать ежедневную или еженедельную дозировку. Эта стратегия является гибкой, и вы можете изменить стратегию пакетной обработки для конкретных событий, от которых вы ожидаете большего объема, например дней в году, когда ожидается больше показов. Пакеты должны включать отчеты из одной и той же версии API, источника отчетов и расписания отчетов.

Фильтрация идентификаторов

Частный API-интерфейс агрегации и служба агрегации позволяют использовать идентификаторы фильтрации для обработки измерений на более детальном уровне, например для каждой рекламной кампании, вместо обработки результатов в более крупных запросах.

Схема ПАА СС

Чтобы начать использовать это сегодня, выполните несколько приблизительных шагов, которые можно применить к вашей текущей реализации.

Действия с общим хранилищем

Если вы используете API общего хранилища в своем потоке:

  1. Определите, где вы будете объявлять и запускать новый модуль общего хранилища. В следующем примере мы назвали файл модуля filtering-worklet.js , зарегистрированный в filtering-example .

    (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 можно настроить для каждого отчета и, если он не установлен, по умолчанию используется значение 1. Это значение по умолчанию предназначено для предотвращения ненужного увеличения размера полезных данных и, следовательно, затрат на хранение и обработку. Подробнее читайте в пояснении к гибкому вкладу .

  2. В файле, который вы использовали выше, в данном случае filtering-worklet.js , когда вы передаете вклад в privateAggregation.contributeToHistogram(...) в Worklet Shared Storage, вы можете указать идентификатор фильтрации.

    // 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. Агрегированные отчеты будут отправляться туда, где вы определили конечную точку /.well-known/private-aggregation/report-shared-storage . Перейдите к руководству по идентификаторам фильтрации, чтобы узнать об изменениях, необходимых в параметрах задания службы агрегации.

После завершения пакетной обработки и отправки в развернутую службу агрегации отфильтрованные результаты должны быть отражены в итоговом сводном отчете.

Действия с защищенной аудиторией

Если вы используете API защищенной аудитории в своем потоке:

  1. В вашей нынешней реализации Protected Audience вы можете настроить следующее для подключения к Private Aggregation. В отличие от общего хранилища, пока невозможно настроить максимальный размер идентификатора фильтрации. По умолчанию максимальный размер идентификатора фильтрации составляет 1 байт и ему присваивается значение 0n . Имейте в виду, что они будут установлены в функциях отчетности по Защищенной аудитории (например, reportResult() generateBid() ).

    const contribution = {
        ...
        filteringId: 0n
    };
    
    privateAggregation.contributeToHistogram(contribution);
    
  2. Агрегированные отчеты будут отправляться туда, где вы определили конечную точку /.well-known/private-aggregation/report-protected-audience . После завершения пакетной обработки и отправки в развернутую службу агрегации отфильтрованные результаты должны быть отражены в итоговом сводном отчете. Доступны следующие пояснения к API отчетов по атрибуции и API частного агрегирования, а также первоначальное предложение.

Продолжайте читать наше руководство по идентификаторам фильтрации в Службе агрегирования или перейдите к разделам API отчетов об атрибуции, чтобы получить более подробную информацию об учетной записи.

Служба агрегации

Служба работает в TEE, расшифровывает агрегированные отчеты и добавляет шум для создания окончательного сводного отчета.

Служба агрегации получает от сборщика зашифрованные агрегированные отчеты и формирует сводные отчеты. Дополнительные стратегии по пакетному агрегированию отчетов в вашем сборщике см. в нашем руководстве по пакетной обработке .

Служба работает в доверенной среде выполнения (TEE), которая обеспечивает уровень гарантии целостности данных, конфиденциальности данных и целостности кода. Если вы хотите поближе познакомиться с тем, как координаторы используются вместе с TEE, узнайте больше об их роли и назначении .

Сводные отчеты

Сводные отчеты позволяют вам увидеть собранные вами данные с добавленным шумом. Вы можете запросить сводные отчеты по заданному набору ключей.

Сводный отчет содержит набор пар ключ-значение в стиле словаря JSON. Каждая пара содержит:

  • bucket : ключ агрегирования в виде строки двоичных чисел. Если используемый ключ агрегирования — «123», то сегмент — «1111011».
  • value : суммарное значение для заданной цели измерения, суммированное из всех доступных агрегированных отчетов с добавлением шума.

Например:

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

Шум и масштабирование

Чтобы сохранить конфиденциальность пользователей, служба агрегации добавляет шум один раз к каждому сводному значению каждый раз, когда запрашивается сводный отчет. Значения шума случайным образом извлекаются из распределения вероятностей Лапласа . Хотя вы не можете напрямую контролировать способы добавления шума, вы можете влиять на влияние шума на данные измерений.

Распределение шума одинаково независимо от суммы всех агрегируемых значений. Следовательно, чем выше агрегированные значения, тем меньшее влияние может оказать шум.

Например, предположим, что распределение шума имеет стандартное отклонение 100 и центрировано на нуле. Если собранное агрегированное значение отчета (или «агрегируемое значение») составляет всего 200, то стандартное отклонение шума будет составлять 50 % от агрегированного значения. Но если агрегируемое значение равно 20 000, то стандартное отклонение шума составит всего 0,5% от агрегированного значения. Таким образом, совокупное значение 20 000 будет иметь гораздо более высокое соотношение сигнал/шум.

Таким образом, умножение совокупного значения на коэффициент масштабирования может помочь уменьшить шум. Коэффициент масштабирования показывает, насколько вы хотите масштабировать данное агрегируемое значение.

Шум является постоянным независимо от совокупного значения.

Увеличение значений путем выбора большего коэффициента масштабирования снижает относительный шум. Однако это также приводит к тому, что сумма всех взносов во всех сегментах быстрее достигает предела бюджета вкладов. Уменьшение значений путем выбора меньшего коэффициента масштабирования увеличивает относительный шум, но снижает риск достижения предела бюджета.

Масштабируйте совокупную стоимость в бюджет вклада.

Чтобы вычислить соответствующий коэффициент масштабирования, разделите бюджет вклада на максимальную сумму агрегируемых значений по всем ключам.

Дополнительную информацию см. в документации по бюджету взносов .

Привлекайте и делитесь отзывами

API частного агрегирования находится в стадии активного обсуждения и может быть изменен в будущем. Если вы попробуете этот API и у вас есть отзывы, мы будем рады их услышать.