Private Aggregation API 基礎知識

Private Aggregation API 的重要概念

這份文件的目標讀者是誰?

Private Aggregation API 可從有權存取跨網站資料的 Worklet 收集匯總資料。本文分享的概念對於開發人員在 Shared Storage 和 Protected Audience API 中建構報表功能至關重要。

  • 如果您是開發人員,要為跨網站評估建立報表系統。
  • 如果您是行銷人資料科學家或其他摘要報表消費者,瞭解這些機制有助於做出設計決策,以擷取最佳化摘要報表。

重要詞彙

閱讀本文前,建議先熟悉重要術語和概念。我們將在此深入說明各項條款。

  • 匯總鍵 (也稱為 bucket) 是預先決定的資料點集合。舉例來說,您可能想收集瀏覽器回報國家/地區名稱的位置資料。匯總鍵可能包含多個維度 (例如國家/地區和內容小工具的 ID)。
  • 可匯總值是收集到匯總鍵中的個別資料點。如要評估有多少法國使用者看過您的內容,則 France 是匯總鍵中的維度,而 viewCount 是可匯總的值。1
  • 可匯總報表會在瀏覽器中產生並加密,如果是 Private Aggregation API,這會包含單一事件的資料。
  • 匯總服務會處理可匯總報表的資料,並建立摘要報表。
  • 摘要報表是 Aggregation Service 的最終輸出內容,內含經過加噪處理的匯總使用者資料和詳細轉換資料。
  • 工作單是基礎架構的一部分,可讓您執行特定 JavaScript 函式,並將資訊傳回給要求者。在工作單元中,您可以執行 JavaScript,但無法與外部網頁互動或通訊。

私密匯總工作流程

使用匯總鍵和可匯總值呼叫 Private Aggregation API 時,瀏覽器會產生可匯總報表。報表會傳送至伺服器,並由伺服器批次處理。匯總服務稍後會處理批次報表,並產生摘要報表。

資料會從用戶端流向收集器,然後流向匯總服務,產生摘要報表。
從用戶端到收集器的資料流。
  1. 呼叫 Private Aggregation API 時,用戶端 (瀏覽器) 會產生可匯總報表,並傳送至伺服器以供收集。
  2. 伺服器會從用戶端收集報表,並將報表分批傳送至匯總服務。
  3. 收集到足夠的報表後,您會將報表分批傳送至可信執行環境中執行的匯總服務,以產生摘要報表。

本節所述的工作流程與 Attribution Reporting API 類似。不過,歸因報表會將曝光事件和轉換事件 (發生時間不同) 收集到的資料建立關聯。私密匯總會評估單一跨網站事件。

匯總鍵

匯總鍵 (簡稱「鍵」) 代表可匯總值累積的 bucket。您可以將一或多個維度編碼到金鑰中。維度代表您想深入瞭解的某個層面,例如使用者年齡層或廣告活動的曝光次數。

舉例來說,您可能在多個網站中嵌入小工具,並想分析看過小工具的使用者所在國家/地區。您想解答的問題包括「看過我小工具的使用者中,有多少來自 X 國家/地區?」如要針對這個問題產生報表,您可以設定匯總鍵,其中會編碼兩個維度:小工具 ID 和國家/地區 ID。

提供給 Private Aggregation API 的金鑰是 BigInt,由多個維度組成。在本例中,維度是小工具 ID 和國家/地區 ID。假設小工具 ID 最多可達 4 位數,例如 1234,且每個國家/地區都依字母順序對應到一個數字,例如阿富汗是 1、法國是 61,辛巴威是 195。因此,可匯總的索引鍵長度為 7 位數,前 4 個字元保留給 WidgetID,後 3 個字元保留給 CountryID

假設鍵代表來自法國 (國家/地區 ID 061) 的使用者看到小工具 ID 3276 的次數,則匯總鍵為 3276061

匯總鍵
小工具 ID 國家/地區 ID
3276 061

您也可以使用雜湊機制 (例如 SHA-256) 產生匯總鍵。舉例來說,字串「{"WidgetId":3276,"CountryID":67}」可以經過雜湊處理,然後轉換為「BigInt」值「42943797454801331377966796057547478208888578253058197330928948081739249096287n」。如果雜湊值超過 128 位元,可以截斷雜湊值,確保不會超過允許的儲存區值上限 2^128−1

在 Shared Storage 工作單中,您可以存取 cryptoTextEncoder 模組,協助您產生雜湊值。如要進一步瞭解如何產生雜湊,請參閱 SubtleCrypto.digest() MDN 頁面。

以下範例說明如何從雜湊值產生 bucket 鍵:

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

可匯總的值

系統會將多位使用者各個鍵的可匯總值加總,在摘要報表中以摘要值的形式,產生匯總洞察資料。

現在,請回到先前提出的範例問題:「看過我小工具的使用者中,有多少人來自法國?」這個問題的答案會類似「看過 Widget ID 3276 的使用者中,約有 4881 人來自法國」。每位使用者的可匯總值為 1,「4881 位使用者」則是匯總值,也就是該匯總鍵的所有可匯總值總和。

匯總鍵 可匯總的值
小工具 ID 國家/地區 ID 觀看次數
3276 061 1

在這個範例中,每位看到小工具的使用者都會讓值增加 1。 在實務上,可匯總的值可以擴大,以提升訊號雜訊比

捐款預算

每次呼叫 Private Aggregation API 都稱為「貢獻」。為保護使用者隱私,系統會限制可從個人收集的貢獻內容數量。

加總所有匯總鍵的可匯總值時,總和必須小於貢獻預算。預算範圍為每個工作單元來源,以天為單位,且 Protected Audience API 和 Shared Storage 工作單元的預算各自獨立。系統會使用大約過去 24 小時的滾動時間範圍來計算當日用量。如果建立新的可匯總報表會導致超出預算,系統就不會建立該報表。

貢獻預算以參數 L1 表示,且設為每天每十分鐘 216 (65,536),並以 220 (1,048,576) 做為後備機制。如要進一步瞭解這些參數,請參閱說明

貢獻預算的值是任意值,但雜訊會根據該值調整。 您可以使用這項預算,盡量提高摘要值的訊號雜訊比 (詳情請參閱「雜訊和縮放」一節)。

如要進一步瞭解貢獻預算,請參閱說明。 如需更多指引,請參閱「貢獻預算」。

每份報表的貢獻數量上限

視來電者而定,貢獻上限可能有所不同。如果是共用儲存空間,這些上限是預設值,可以覆寫。目前,為 Shared Storage API 呼叫端產生的報表,每份報表最多只能有 20 項貢獻。另一方面,Protected Audience API 呼叫者每份報表的貢獻上限為 100 次。我們設定這些限制,是為了在可嵌入的貢獻內容數量與酬載大小之間取得平衡。

如果是共用儲存空間,單一 run()selectURL() 作業中的貢獻內容會批次處理,並匯入一份報表。如果是 Protected Audience,競價中單一來源的貢獻內容會批次處理。

含邊框間距的 Contributions

並透過邊框間距功能進一步修改。填補酬載可保護內嵌在可匯總報表中的實際貢獻數量相關資訊。填充內容會增加酬載的null貢獻 (即值為 0),達到固定長度。

可匯總報表

使用者叫用 Private Aggregation 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頁面檢查可匯總報表:

Private Aggregation API 內部頁面
Private Aggregation API 內部頁面

如要進行測試,可以使用「傳送所選報表」按鈕,立即將報表傳送至伺服器。

收集並批次處理可匯總報表

瀏覽器會使用下列列出的知名路徑,將可匯總報表傳送至含有 Private Aggregation API 呼叫的 Worklet 來源:

  • 共用儲存空間:/.well-known/private-aggregation/report-shared-storage
  • 適用於受保護的目標對象: /.well-known/private-aggregation/report-protected-audience

在這些端點,您需要運作伺服器 (做為收集器),接收用戶端傳送的可匯總報表。

接著,伺服器應將報表分批傳送至匯總服務。根據可匯總報表未加密的酬載中提供的資訊 (例如 shared_info 欄位) 建立批次。在理想情況下,每個批次應包含 100 份以上的報表。

您可以選擇每天或每週批次處理。這項策略十分彈性,您可以針對預期有較多量的特定事件變更批次處理策略,例如預期有較多曝光次數的日期。批次應包含來自相同 API 版本、報表來源和排定報表時間的報表。

篩選 ID

Private Aggregation API 和 Aggregation Service 允許使用篩選 ID,以更精細的層級處理評估結果,例如以每個廣告活動為單位,而非處理較大查詢中的結果。

私密匯總和匯總服務篩選 ID。
私密匯總和匯總服務篩選 ID。

如要立即開始使用,請參考下列大致步驟,將這項功能套用至目前的實作項目。

共用儲存空間步驟

如果您在流程中使用 Shared Storage API

  1. 定義要宣告及執行新 Shared Storage 模組的位置。 在下列範例中,我們將模組檔案命名為 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中,將貢獻傳遞至共用儲存空間 Worklet 內的 privateAggregation.contributeToHistogram(...) 時,您可以指定篩選 ID。

    // 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。請繼續參閱篩選 ID 指南,瞭解匯總服務工作參數需要進行哪些變更。

批次處理完成並傳送至已部署的匯總服務後,最終摘要報告中就會顯示篩選後的結果。

Protected Audience 步驟

如果您在流程中使用 Protected Audience API

  1. 在目前導入的 Protected Audience 中,您可以設定下列項目,連結至 Private Aggregation。與共用儲存空間不同,目前還無法設定篩選 ID 的大小上限。根據預設,篩選 ID 的大小上限為 1 個位元組,且會設為 0n。請注意,這些值會在受保護的目標對象報表函式 (例如 reportResult()generateBid()) 中設定。

    const contribution = {
      ...
      filteringId: 0n
    };
    
    privateAggregation.contributeToHistogram(contribution);
    
  2. 可匯總報表會傳送至您定義的端點 /.well-known/private-aggregation/report-protected-audience。批次處理完成並傳送至已部署的匯總服務後,最終摘要報表應會顯示經過篩選的結果。以下是 Attribution Reporting API 和 Private Aggregation API 的說明,以及初步提案。

請繼續參閱「在匯總服務中篩選 ID 指南」,或前往「Attribution Reporting API」章節,瞭解更詳細的說明。

匯總服務

這項服務會在 TEE 中執行,解密可匯總報表並加入雜訊,以建立最終摘要報表。
這項服務會在 TEE 中執行,解密可匯總報表並加入雜訊,建立最終摘要報表。

匯總服務會接收收集器傳送的加密可匯總報表,並產生摘要報表。如需在收集器中批次處理可匯總報表的進一步策略,請參閱批次處理指南

這項服務會在受信任的執行環境 (TEE) 中執行,確保資料完整性、資料機密性和程式碼完整性。如要進一步瞭解如何搭配使用協調器和 TEE,請參閱角色和用途

摘要報表

摘要報表 可顯示您收集的資料,並加入噪音。您可以針對特定金鑰組合要求摘要報表。

摘要報表包含 JSON 字典樣式的鍵/值組合。每組都包含:

  • bucket:以二進位數字字串表示的匯總鍵。如果使用的彙整鍵是「123」,則 bucket 為「1111011」。
  • value:特定評估目標的摘要值,由所有可匯總的報表加總而來,並加入雜訊。

例如:

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

雜訊和縮放

為保護使用者隱私,每次要求摘要報表時,匯總服務都會為每個摘要值加入一次雜訊。系統會從 Laplace 概率分布中隨機抽取雜訊值。雖然您無法直接控制加入雜訊的方式,但可以影響雜訊對評估資料的影響。

無論所有可匯總值的總和為何,雜訊分布情形都相同。因此,可匯總的值越高,雜訊的影響就越小。

舉例來說,假設雜訊分布的標準差為 100,且以零為中心。如果收集到的可匯總報表值 (或「可匯總值」) 只有 200,則雜訊的標準差會是匯總值的 50%。但如果可彙整的值為 20,000,則雜訊的標準差只會是彙整值的 0.5%。因此,20,000 的可匯總值訊號雜訊比會高出許多。

因此,將可匯總的值乘以調整係數,有助於減少雜訊。比例因數代表您要將特定可彙整值縮放多少。

無論匯總值為何,雜訊都是常數。
無論匯總值為何,一律為雜訊常數。

選擇較大的縮放比例,放大值可減少相對雜訊。不過,這也會導致所有儲存區的貢獻總和更快達到貢獻預算上限。選擇較小的縮放比例常數來縮減值,會增加相對雜訊,但可降低達到預算上限的風險。

將可匯總的值縮放至貢獻預算。
將可匯總的值縮放至貢獻預算。

如要計算適當的縮放比例因子,請將貢獻預算除以所有鍵的最大可彙整值總和。

詳情請參閱貢獻預算說明文件

參與討論及分享意見

Private Aggregation API 目前仍在積極討論中,未來可能會有所變動。如果您試用過這項 API,歡迎提供意見。