Receber e armazenar relatórios agregáveis

Quando as adtechs acionam APIs de medição (API Attribution Reporting ou API Private Aggregation), os relatórios criptografados são enviados do lado do cliente / navegador Chrome para o endpoint de relatórios da adtech, que é um URL .well-known com a origem de relatórios da adtech. O endpoint de relatórios é hospedado pela adtech para coletar os relatórios criptografados.

Diagrama do relatório da AgS.

Confira os endpoints por API:

  • Agregação particular

    • Depurar [reporting-origin]/.well-known/private-aggregation/debug/report-shared-storage
    • [reporting-origin]/.well-known/private-aggregation/report-shared-storage ou /.well-known/private-aggregation/report-protected-audience
  • Relatórios de atribuição

    • Depurar [reporting-origin]/.well-known/attribution-reporting/debug/report-aggregate-attribution
    • Ao vivo [reporting-origin]/.well-known/attribution-reporting/report-aggregate-attribution

As adtechs vão receber os relatórios no formato JSON por uma chamada POST. As adtechs vão coletar esses relatórios JSON e depois convertê-los no formato AVRO, que é usado no serviço de agregação. Depois da conversão, os relatórios AVRO são armazenados no armazenamento em nuvem da adtech para processamento em lote posterior.

Quando a adtech estiver pronta para gerar lotes, ela vai acionar uma solicitação de job de agregação pelo serviço de agregação, em que os relatórios são recuperados do armazenamento em nuvem da adtech. O serviço de agregação é hospedado no armazenamento em nuvem da adtech e precisa ter uma imagem na lista de permissões.

Os relatórios recebidos são semelhantes a este:

API Private Aggregation

  {
    "aggregation_coordinator_origin": "https://publickeyservice.msmt.aws.privacysandboxservices.com",
    "aggregation_service_payloads": [ {
        "key_id": "1a2baa3f-5d48-46cf-91f0-772633c12640",
        "payload": "8Cjr1s3FVkCYkjzBvyzJn14yardVjd5N4vLCA69LQAPbIkJ0B58hAqUGBCNXpvTjW9ZpIoZbCSiUOsUDuoA/S+tqVolLMkame6sWC07cfUmZcVsbU+La3pzTMtCgdtNc8MIWgD3C63CMw7rWroRlechewVUajvAYVK/0HJq0YyGrTiFZZm36zi0jjyHLAXKV8p1Lvy1d0o/wnBxC5oVo5BV6LPkxqQEcoYS2GyixUuht6wD0RzuH+BxxuH6vY/ynp2xDrnwftjvqwDUAxUWLFTunthM6BXZVxlrvOBim1h2dvPqWSyKZ5gafo+MgW9EM4SraavNM3XzZSCjdtAfSMJMrynSu2j0opyAq+9e1jq1xeYN00yZrJ0Y/GTI45IGjgCnVmvmuoI9ucW2SnXP31CQBwHqk4gtUgMsYGFSUYfhtnAQ/8TSbaXyS2LX+cQW87LqkvIraWw6o37O24VFBreFoFFXpu3IUeCZfji+Sr4/ykfZuHeMzQbBavyNnHKzPZlbLSXMiucx4/vWzYyOzHeIlbtupXVvbi40V2PieDShaSbjI266kGgFkeCk6z51AaAGebDPtRT1lhBpcoQ6JdF0Yp5VWSnyFARKFtCZ1aEBrlUlrEHLUQY/pFtmDxJQiicRz1YPjR8jRr3C7hlRhWwov0dMocqnMz5209hHGVZWSsaGc9kWjtxREW2ULXfoIwOGbX+WZsyFW2RhXksQPJ5fhyNc4ROkAzUthLb68gC5e0yZHvmLIAU4hcWe0UanJv+jRljn8PAPaJHKFUxQNJyBA7mTbn5mkpycxGrX6T3ZYdPHqvckqt9llJZWjr8NneizzZFRuJk423BDs38fXkvcTAsAckd2Zu0u2KC45WR93sN2/CWrqB7/QU9BsgNdonl/ehAWhU1LbcRRvBTcR9+0wL7vRL7cv5LG3+gRYRKsWI6U2nDSWp0cNpo9+HU0JNiifa5X0cguihqU2bSk6ABozgRtCZ7m+7eqWXMLSzBdmc1CPUoQppo6Wmf6ujdNqI6v2S6pDH781lph8Z2v7ZpxGdhVVPEL51cVn"
    } ],
    "debug_key": "1234",
    "shared_info": "{\"api\":\"shared-storage\",\"report_id\":\"05e3b948-cb8d-4404-be29-bfeac7ad9710\",\"reporting_origin\":\"https://privacy-sandbox-demos-dsp.dev\",\"scheduled_report_time\":\"1707784729\",\"version\":\"0.1\"}"
  }

API Attribution Reporting

  {
    "aggregation_coordinator_origin": "https://publickeyservice.msmt.aws.privacysandboxservices.com",
    "aggregation_service_payloads": [ {
        "key_id": "2dee0f3f-2aee-4a4a-8238-9154ed3d6f72",
        "payload": "pHvTHhcxvNKaCmnLpvYQsXlJpiNRuFO5Zj1QqUlqgWPOfuoHLfiXiFjmpvY8a53/OYnS4bKwHwJReFcofldsu8E9BzTTJ3CEk+B7vbEjnDPaljhpIBMTuQXy3QHGK4slWR/yNZVm2uXRWR/DVVzXziBoTDjN7qaPstRoLKUUMdfY2u8oq4tnLY00Y+NDZttZ4wJvC7hPmvY3lqHjdl14JPD2ytZZ4NViYzno3WKdH/oZc0jhGK4zI38lAM0qpahF/B9yb4zOu7IRIjQpNx73P8naDyddxLldoVlW/qHpO04FguWymscvI/8i6NwUR6Kj8seRlWS0iIUhETt/ai3lilKUHUb+uz0YG2kxjoXq7Ldk+MP56nNl67ZRNi2YZ7bOGI/okYWoT/wt2uWPe/5xAEMmadxl0hQQrG7YXHRSD8rDnaVPXo+AKIxdg727yJeB1ZENZvovl/kIevdRAmdBe2h1U3J6Uz6psly/46fvjgkj5QD+kO2uaYirzvmwS19luJsN/Qvh/R3ZO4qlJIQI0nDJPWwUJ4ODpyVmj4a0xQp3t2ESEnf4EmY7+khn3xpF5+MwEWKES2ZeDf7SHalR99pvZA8G3Fr8M0PWFmT00cmKCBwpQgZyd3Eay70UlqdkbFEedxiCVWKNNOUz41m5KG/7K3aR+dYx57l57Wct4gOFQg3jiUEBJWrFIVCXf12BT5iz5rBQh1N1CUt2oCOhYL/sPuBl6OV5GWHSIj8FUdpoDolqKXWINXfE88MUijE2ghNRpJN25BXIErUQtO9wFQv7zotC6d2BIaF0x8AkKg/7yzBQRySX/FZP3H3lMkpOz9rQMV8DjZ2lz7nV4k6CFo8qhT6cpYJD7GpYl81xJbglNqcJt5Pe5YUHrdBMyAFsTh3yoJvYnhQib/0xVN/a93lbYccxsd0yi375n4Xz0i1HUoe2ps+WlU8XysAUA1agG936eshaY1anTtbJbrcoaH+BNSacKiq4saprgUGl4eDjaR/uBhvUnO52WkmAGon8De3EFMZ/kwpPBNSXi7/MIAMjotsSKBc19bfg"
    } ],
    "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://privacy-sandbox-demos-shop.dev\",\"report_id\":\"5b052748-f5fb-4f14-b291-de03484ed59e\",\"reporting_origin\":\"https://privacy-sandbox-demos-dsp.dev\",\"scheduled_report_time\":\"1707786751\",\"source_registration_time\":\"0\",\"version\":\"0.1\"}",
    "source_debug_key": "123456789",
    "trigger_debug_key": "123456789"
  }

Converter relatórios JSON em AVRO

Ao agrupar, os relatórios agregáveis precisam estar no formato AVRO. Para criar um relatório AVRO, você vai precisar do esquema AVRO do relatório (AVSC).

Um exemplo de código JavaScript está disponível no repositório do GitHub do serviço de agregação.

Confira abaixo o esquema AVRO para relatórios agregáveis. Os campos diferentes dos relatórios são payload, key_id e shared_info.

  {
    "type": "record",
    "name": "AggregatableReport",
    "fields": [
      {
        "name": "payload",
        "type": "bytes"
      },
      {
        "name": "key_id",
        "type": "string"
      },
      {
        "name": "shared_info",
        "type": "string"
      }
    ]
  }
Parâmetro Tipo Descrição
payload Bytes O payload precisa ser decodificado em base64 e convertido em uma matriz de bytes de payload para relatórios em tempo real / produção.
debug_cleartext_payload Bytes O payload precisa ser decodificado em base64 e convertido em uma matriz de bytes de debug_cleartext_payload para relatórios de depuração.
key_id String Essa é a string "key_id" encontrada no relatório. O key_id será um identificador universalmente exclusivo semelhante de 128 bits.
shared_info String Essa será a string não adulterada encontrada no campo shared_info do relatório.

Este é um exemplo de JSON de relatório:

{ 
   "aggregation_coordinator_identifier": "aws-cloud",      
   "aggregation_service_payloads": [{ 
      "debug_cleartext_payload": "omRkYXhgaJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAFWW1vcGVyYX", 
      "key_id": "3c6e2850-edf6-4886-eb70-eb3f2a7a7596",
      "payload": "oapYz92Mb1yam9YQ2AnK8dduTt2RwFUSApGcKqXnG1q+aGXfJ5DGpSxMj0NxdZgp7Cq" 
   }],
   "debug_key": "1234", 
   "shared_info":
"{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"b029b922-93e9-4d66-a8c6-8cdeec762aed\",\"reporting_origin\":\"https://privacy-sandbox-demos-dsp.dev\",\"scheduled_report_time\":\"1719251997\",\"version\":\"0.1\"}"
}

AVRO do domínio de saída

Para gerar relatórios de resumo usando o serviço de agregação, a adtech exige os relatórios agregáveis e o arquivo de domínio. Os relatórios JSON recebidos na origem de relatórios e convertidos para o formato AVRO serão agregados. Os domínios de saída vão conter as chaves predeclaradas que serão coletadas dos relatórios agregáveis e serão gravadas nos relatórios de resumo. Saiba mais sobre essas chaves nos Relatórios de atribuição e chaves na agregação privada. O domínio de saída vai conter o bucket de campo, e o valor do bucket será a chave dele.

O arquivo de domínio também precisa estar no formato AVRO usando o seguinte esquema:

  {
    "type": "record",
    "name": "AggregationBucket",
    "fields": [
      {
        "name": "bucket",
        "type": "bytes",
        "doc": "A single bucket that appears in the aggregation service output. 128-bit integer encoded as a 16-byte big-endian bytestring."
      }
    ]
  }

Chave do bucket

A chave do bucket precisa ser uma string de byte hexadecimal da chave do bucket. Um exemplo disso é ter uma chave de 1369 em decimal. Quando convertido em hexadecimal, será 559. Em seguida, você precisa converter 559 em uma string de bytes para ser adicionada ao domínio de saída AVRO.

Diagrama da chave do bucket AgS.

Relatórios em lote

Para entender mais sobre os orçamentos de privacidade e o agrupamento, acesse o documento estratégias de agrupamento. Além disso, lembre-se de que um relatório agregável só pode ser agrupado em um determinado período. Um relatório não pode exceder o MAX_REPORT_AGE entre a scheduled_report_time e a data de execução do lote (atualmente 90 dias).

Relatórios de resumo

Depois do agrupamento, o serviço de agregação cria o relatório de resumo no formato AVRO. O relatório de resumo usa o esquema results.avsc.

O relatório de resumo vai estar localizado no output_data_blob_prefix no bucket output_data_bucket_name indicado na solicitação createJob.

Para lotes do serviço de agregação em que o debug_run está ativado, dois relatórios são criados. O relatório de resumo e o relatório de resumo de depuração. O relatório de resumo de depuração vai estar localizado na pasta output_data_blob_prefix/debug.

O relatório de depuração gerado usa o esquema debug_results.avsc.

O resumo e o relatório de depuração vão ser nomeados como [output_data_blob_prefix]-1-of-1.avro. Se o output_data_blob_prefix for summary/summary.avro, o relatório vai estar na pasta de resumo com o nome summary-1-of-1.avro.

results.avsc

{
  "type": "record",
  "name": "AggregatedFact",
  "fields": [
    {
      "name": "bucket",
      "type": "bytes",
      "doc": "Histogram bucket used in aggregation. 128-bit integer encoded as a 16-byte big-endian bytestring. Leading 0-bits will be left out."
    },
    {
      "name": "metric",
      "type": "long",
      "doc": "Metric associated with the bucket"
    }
  ]
}

debug_results.avsc

  {
  "type": "record",
  "name": "DebugAggregatedFact",
  "fields": [
      {
        "name": "bucket",
        "type": "bytes",
        "doc": "Histogram bucket used in aggregation. 128-bit integer encoded as a 16-byte big-endian bytestring. Leading 0-bits will be left out."
      },
      {
        "name": "unnoised_metric",
        "type": "long",
        "doc": "Unnoised metric associated with the bucket."
      },
      {
        "name": "noise",
        "type": "long",
        "doc": "The noise applied to the metric in the regular result."
      }
      {
        "name":"annotations",
        "type": {
          "type": "array",
          "items": {
            "type":"enum",
            "name":"bucket_tags",
            "symbols":["in_domain","in_reports"]
          }
       }
    ]
  }

Depois da conversão, o relatório de resumo vai ficar parecido com o exemplo results.json. Quando o debug_run está ativado, o relatório de resumo de depuração retorna algo semelhante ao exemplo debug_results.json.

results.json (exemplo)

Os relatórios AVRO provenientes do serviço de agregação podem ser semelhantes, com a chave do bucket e o valor de resumo / agregado com ruído adicionado dos valores do bucket.

  {
    "bucket": "\u0005Y",
    "metric": 26308
  }

debug_results.json (exemplo)

Os relatórios de depuração do AVRO provenientes do serviço de agregação devem ser semelhantes ao seguinte, em que você recebe as chaves do bucket, unnoised_metric (resumo das chaves do bucket sem ruído) e o ruído adicionado à unnoised_metric.

  {
    "bucket": "\u0005Y",
    "unnoised_metric": 128,
    "noise": -17948,
    "annotations": [
      "in_reports",
      "in_domain"
    ]
  }

As anotações também vão conter in_reports e / ou in_domain, o que significa:

  • in_reports: a chave do bucket está disponível nos relatórios agregáveis
  • in_domain: a chave do bucket está disponível no arquivo AVRO output_domain