Otimização e integração de serviços de lances e leilões

A proposta de design Serviços de lances e leilões para Android detalha a execução e o fluxo de dados dos leilões em execução no Android usando o servidor de lances e leilões confiáveis. Para garantir que os dados em trânsito sejam processados apenas por APIs que preservam a privacidade e por servidores confiáveis, eles são criptografados entre o cliente e o servidor usando a criptografia de chave pública híbrida bidirecional.

Ilustração do fluxo da Protected Audience. Três colunas representam como os dados são transferidos entre os dispositivos, serviços de vendedores não confiáveis e um ambiente de execução confiável.
O fluxo de leilão da Protected Audience.

Para gerar o leilão conforme detalhado anteriormente, as adtechs do vendedor no dispositivo precisam realizar as seguintes etapas:

  1. Coletar e criptografar dados para leilão de servidor
  2. Enviar uma solicitação para um serviço de vendedor não confiável
  3. Receber uma resposta de um serviço de vendedor não confiável
  4. Descriptografar a resposta do leilão da Protected Audience e conferir o resultado

A Protected Audience está introduzindo duas novas APIs para dar suporte aos leilões de servidor em execução:

  1. A API getAdSelectionData coleta dados para o leilão do servidor e gera um payload criptografado com esses dados. O servidor de lances e leilões usa esse payload para executar um leilão, gerar o resultado e retorná-lo.
  2. Os clientes de adtechs no dispositivo podem chamar a API persistAdSelectionResult para descriptografar o resultado gerado pelo leilão do servidor e receber o URL de renderização do anúncio vencedor.

As adtechs do vendedor no dispositivo precisam integrar e criar o seguinte para gerar um leilão:

  1. Coletar e criptografar dados do vendedor do leilão do servidor: as adtechs precisam chamar a API getAdSelectionData para conseguir o payload criptografado.
  2. Enviar solicitação para envio de serviço de vendedor não confiável: uma solicitação HTTP POST ou PUT que contém o payload criptografado gerado pela API getAdSelectionData para o serviço e dados de vendedor não confiável exigido pelo serviço do vendedor não confiável para gerar resultados contextuais.
  3. Receber resposta do serviço de vendedor não confiável: a resposta do serviço de vendedor não confiável conteria o resultado do leilão de público-alvo protegido criptografado e o resultado do leilão contextual.
  4. Descriptografar a resposta do leilão de público protegido e receber o resultado:para descriptografar o resultado, as adtechs do vendedor precisam chamar a API persistAdSelectionResult. O resultado gerado pelo persistAdSelectionResult vai ajudar as adtechs a determinar se o anúncio contextual ou o anúncio de público-alvo protegido venceu o leilão e o URI do anúncio público-alvo protegido vencedor, se aplicável.

Recursos com suporte para leilão do servidor

Nosso objetivo é oferecer suporte a todos os recursos atualmente disponíveis para o leilão no dispositivo. O cronograma para oferecer suporte a esses recursos no leilão do servidor é o seguinte:

Leilão no dispositivo

Leilão do servidor

Prévia para desenvolvedores

Beta

Prévia para desenvolvedores

Beta

Relatórios de vitórias no nível do evento

1º trimestre de 2023

3º trimestre de 2023

N/A

4º trimestre de 2023

Mediação em hierarquia

1º trimestre de 2023

4º trimestre de 2023

N/A

1º trimestre de 2024

Filtragem do limite de frequência

2º trimestre de 2023

3º trimestre de 2023

N/A

4º trimestre de 2023

Transmitir anúncios contextuais ao fluxo de trabalho de seleção de anúncios para filtragem

2º trimestre de 2023

1º trimestre de 2024

N/A

N/A

Relatórios de interação

2º trimestre de 2023

3º trimestre de 2023

N/A

4º trimestre de 2023

Participar da delegação de público-alvo personalizado

3º trimestre de 2023

4º trimestre de 2023

N/A

4º trimestre de 2023

Faturamento sem CPM

3º trimestre de 2023

4º trimestre de 2023

Relatórios de
depuração

3º trimestre de 2023

4º trimestre de 2023

3º trimestre de 2023

4º trimestre de 2023

Mediação do Open Bidding

N/A

N/A

N/A

1º trimestre de 2024

Filtragem de anúncios de instalação de apps

2º trimestre de 2023

1º trimestre de 2024

N/A

1º trimestre de 2024

Gerenciamento de moedas

N/A

N/A

N/A

1º trimestre de 2024

Integração com k-anonimato

N/A

1º trimestre de 2024

N/A

1º trimestre de 2024

Integração da agregação particular

N/A

N/A

N/A

3º trimestre de 2024

Gerar leilões de servidor usando APIs Protected Audience

Na faixa de prévia para desenvolvedores, o AdSelectionManager expõe duas novas APIs: getAdSelectionData e persistAdSelectionResult. Essas APIs permitem que os SDKs de adtechs se integrem aos servidores de lances e leilões.

Coletar e criptografar dados para um leilão de servidor

A API getAdSelectionData gera a entrada necessária para componentes de lances e leilões, como BuyerInput e ProtectedAudienceInput, e criptografa os dados antes de disponibilizar o resultado para o autor da chamada. Para evitar o vazamento de dados entre apps, esses dados contêm informações de todos os compradores presentes no dispositivo. Leia mais sobre essa decisão na seção de considerações de privacidade e nas estratégias para otimizá-la na seção de considerações de tamanho.

Para acessar a API, o acesso à API Protected Audience precisa estar ativado e a permissão ACCESS_ADSERVICES_CUSTOM_AUDIENCE precisa estar definida no manifesto do autor da chamada.

public class AdSelectionManager {
    public void getAdSelectionData(
            GetAdSelectionDataRequest getAdSelectionDataRequest,
            Executor executor,
            OutcomeReceiver<GetAdSelectionDataOutcome, Exception> receiver) {}
}

GetAdSelectionDataRequest

O autor da chamada precisa definir o campo seller na solicitação, já que ele é usado para executar verificações de registro antes de atender à solicitação.

public class GetAdSelectionDataRequest {
  Public setSeller(AdTechIdentifier seller);
}

Depois que a solicitação é validada, os dados do comprador no dispositivo são compostos em BuyerInput e ProtectedAudienceInput. O objeto do payload final é criptografado com criptografia de chave pública híbrida bidirecional.

GetAdSelectionDataOutcome

GetAdSelectionDataOutcome é gerado como resultado da API getAdSelectionData. O conteúdo é o seguinte:

  1. adSelectionId: um número inteiro opaco para identificar essa invocação de getAdSelectionData. O cliente de adtechs precisa manter esse valor de adSelectionId, porque ele atua como o ponteiro da chamada getAdSelectionData. Esse identificador é exigido pela API persistAdSelectionResult para descriptografar o resultado do leilão do servidor de lances e leilões, além das APIs reportImpression e reportEvent.
  2. adSelectionData: são os dados de leilão criptografados exigidos pelo servidor de lances e leilões para realizar leilões. Esse método contém:
    1. Dados de público-alvo personalizados filtrados com base no limite de frequência, nos filtros de instalação de apps e nos requisitos de leilão do servidor para públicos-alvo personalizados.
    2. Em uma versão futura, ele conterá dados de instalação do app.
public class GetAdSelectionDataOutcome {
  Public getAdSelectionId(long adSelectionId);
  public byte[] getAdSelectionData();
}

Erros, exceções e tratamento de falhas

Se a geração dos dados de seleção de anúncios não for concluída por motivos como argumentos inválidos, tempos limite ou consumo excessivo de recursos, o callback OutcomeReceiver.onError() vai fornecer um AdServicesException com os comportamentos a seguir:

  1. Se getAdSelectionData for iniciado com argumentos inválidos, o AdServicesException vai indicar uma IllegalArgumentException como a causa.
  2. Todos os outros erros vão receber uma AdServicesException com uma IllegalStateException como causa.

Enviar uma solicitação para um serviço de vendedor não confiável

Usando AdSelectionData, o SDK no dispositivo pode enviar uma solicitação ao serviço de anúncio do vendedor incluindo os dados em uma solicitação POST ou PUT:

fetch('https://www.example-ssp.com/auction', {
  method: "PUT",
  body: data,
...
})

O SDK no dispositivo é responsável por codificar esses dados. É recomendável usar uma solução eficiente em termos de espaço, como enviar a solicitação ao serviço de anúncios do vendedor como dados de várias partes/de formulário.

Receber uma resposta de um serviço de vendedor não confiável

Conforme detalhado na explicação sobre o servidor de lances e leilões, quando o serviço de vendedor não confiável recebe a solicitação, ele faz chamadas de anúncios contextuais para compradores do parceiro.

O serviço de vendedor não confiável encaminha o adSelectionData e o AuctionConfig criptografados para o serviço SellerFrontEnd do servidor de lances e leilões em execução em um TEE.

Quando o leilão da Protected Audience é concluído, o serviço SellerFrontEnd criptografa o resultado do leilão e o retorna como uma resposta ao serviço de vendedor não confiável.

O serviço de vendedor não confiável envia uma resposta para o dispositivo com o anúncio contextual e/ou resultado criptografado do leilão do público-alvo protegido.

Ao receber a resposta, o código de adtech do vendedor no dispositivo pode escolher usar apenas o anúncio contextual na resposta ou, se ele considerar que há um valor incremental para alcançar o resultado de público protegido, descriptografar esse resultado chamando a API PersistAdSelectionResult.

API PersistAdSelectionResult

Para descriptografar o resultado, a adtech do vendedor pode chamar a segunda API Protected Audience persistAdSelectionResult. A API descriptografa o resultado e retorna um AdSelectionOutcome, o mesmo objeto retornado de um leilão no dispositivo.

Para acessar a API, o autor da chamada precisa ativar o acesso à API Protected Audience e definir a permissão ACCESS_ADSERVICES_CUSTOM_AUDIENCE no manifesto.

    public void persistAdSelectionResult(
            PersistAdSelectionResultRequest persistAdSelectionResultRequest,
            Executor executor,
            OutcomeReceiver<AdSelectionOutcome, Exception> receiver) {}

PersistAdSelectionResultRequest

O autor da chamada precisa definir o seguinte na solicitação:

public final class PersistAdSelectionResultRequest {
  Public setAdSelectionId(long adSelectionId);
  public setSeller(AdTechIdentifier seller);
  public setAdSelectionResult(byte[] adSelectionResult);
}
  1. adSelectionId: o identificador opaco gerado pela chamada getAdSelectionData com o resultado que o autor da chamada quer descriptografar.
  2. seller: o identificador de adtech do vendedor precisa ser definido na solicitação para executar verificações de registro antes de atendê-la.
  3. adSelectionResult: o resultado criptografado do leilão gerado pelo servidor de lances e leilões que o autor da chamada quer descriptografar.

Resposta AdSelectionOutcome

Se houver um vencedor de público protegido, AdSelectionOutcome vai retornar o URI de renderização do anúncio vencedor. Depois que o adSelectionResult for descriptografado, os dados do relatório serão mantidos internamente. O callback OutcomeReceiver.onResult() retorna um AdSelectionOutcome que contém:

  • URI: se houver um anúncio de público-alvo protegido vencedor, o URL de renderização do anúncio vencedor será retornado. Se não houver um vencedor de público protegido, "Uri.EMPTY" será retornado.
  • adSelectionId: o adSelectionId associado a esse leilão de servidor.

Erros, exceções e tratamento de falhas

Se a geração dos dados de seleção de anúncios não for concluída por motivos como argumentos inválidos, tempos limite ou consumo excessivo de recursos, o callback OutcomeReceiver.onError() vai fornecer um AdServicesException com os comportamentos a seguir:

  1. Se getAdSelectionData for iniciado com argumentos inválidos, o AdServicesException vai indicar um IllegalArgumentException como a causa.
  2. Todos os outros erros vão receber uma AdServicesException com uma IllegalStateException como causa.

Considerações sobre privacidade

adSelectionData é criptografado para garantir que os dados em trânsito sejam acessíveis apenas pela PPAPI e pelos servidores confiáveis.

Apesar da criptografia, o vazamento de dados pode ocorrer devido ao tamanho de adSelectionData. O tamanho de adSelectionData pode variar devido a:

  1. Mudanças nos dados do CustomAudience presentes no dispositivo.
  2. Mudanças na lógica de filtragem do CustomAudience.
  3. Mudanças na entrada para a chamada de getAdSelectionData.

A mudança de tamanho de adSelectionData pode ser usada para gerar um identificador entre apps, conforme mencionado na discussão de vazamento de 1 bit (em inglês). Muitas mitigações aplicáveis ao vazamento de 1 bit também são aplicáveis aqui.

Para gerenciar esses vazamentos, planejamos gerar o mesmo adSelectionData para todas as chamadas para a API getAdSelectionData. Nas versões iniciais, todos os CustomAudiences no dispositivo são usados para criar adSelectionData, e o payload criptografado será preenchido para mascarar variações de tamanho. Também restringiremos a influência dos parâmetros de entrada de GetAdSelectionData nos adSelectionData gerados.

No entanto, gerar o mesmo adSelectionData para todas as adtechs que usam todos os dados de leilão no dispositivo cria um payload grande que agora precisa ser transferido em todas as chamadas para o servidor da adtech. O uso de todos os públicos-alvo personalizados no dispositivo para gerar payload de leilão também abre o ecossistema para abuso de entidades maliciosas. Abordamos essas questões nas seções Otimizações de tamanho e Mitigações de abuso abaixo.

Otimizações de tamanho

Espera-se que o SDK do cliente de adtechs empacote os bytes criptografados de adSelectionData na chamada contextual HTTP PUT/POST feita para o servidor de adtechs. Para reduzir a latência e o custo do tempo de ida e volta, é necessário reduzir o tamanho de adSelectionData o máximo possível sem afetar o utilitário.

Planejamos descobrir e potencialmente introduzir as seguintes otimizações nas próximas versões para reduzir o tamanho de adSelectionData:

  1. Payload gerado em um conjunto fixo de tamanhos de bucket com padding: para minimizar o vazamento de variações de tamanho e ainda permitir payloads menores, sugerimos o uso de bucket de tamanho fixo para o payload gerado. Manter o número de buckets pequeno, por exemplo, 7 vai resultar em menos de 3 bits de entropia vazada por chamada para getAdSelectionData.

    Se os dados no dispositivo excederem o tamanho máximo do bucket, as estratégias mencionadas abaixo, como valores de prioridade, serão usadas para decidir quais dados serão descartados.

  2. Configuração do comprador: estamos avaliando a viabilidade de permitir que os compradores definam uma configuração de payload por comprador. Essa configuração seria útil para identificar em quais leilões um comprador teria interesse em participar. Se possível, durante a inscrição, as adtechs do comprador podem registrar um endpoint em que o público-alvo protegido vai buscar a configuração de payload em uma frequência regular diária. Como alternativa, as APIs que preservam a privacidade exporiam uma API para permitir que as adtechs do comprador registrem esse endpoint.

    Essa configuração seria usada para avaliar a contribuição de um comprador para adSelectionData gerado para cada solicitação de getAdSelectionData.

    A configuração de payload do comprador permite que os compradores especifiquem o seguinte:

    1. Lista de vendedores permitidos: os CustomAudiences do comprador só serão adicionados ao payload se a chamada getAdSelectionData for iniciada por um vendedor na lista de permissões. Buscamos a configuração do payload em uma cadência diária para manter a lista de permissões atualizada.
    2. Limite de tamanho por vendedor: o comprador pode especificar um limite de tamanho por vendedor para determinar o tamanho dos dados que serão enviados no payload quando um leilão for iniciado por um determinado vendedor. Isso será útil se um comprador quiser dedicar mais recursos ao processamento de dados de leilão de determinados vendedores. O SellerFrontendService encaminha apenas dados específicos do comprador para cada BuyerFrontendService. Assim, ao definir um limite de tamanho por vendedor, um comprador poderia controlar explicitamente a quantidade de dados ingeridos e processados pelo BuyerFrontendService do servidor de lances e leilões dele para leilões realizados por um vendedor.
  3. Configuração do vendedor: estamos avaliando a viabilidade de uma configuração de leilão por vendedor que permitiria aos vendedores definir parâmetros de leilão para controlar o tamanho do payload e os participantes do leilão. Se possível, durante a inscrição, as adtechs do vendedor poderão especificar o endpoint em que o público-alvo protegido pode buscar a configuração de leilão por vendedor em cadência regular. Essa configuração seria usada para determinar a composição e os limites de adSelectionData gerados para cada solicitação getAdSelectionData.

    Semelhante à configuração do comprador, uma configuração por vendedor permite que os vendedores especifiquem qual conjunto de compradores esperam encontrar em um leilão e especifiquem limites de contribuição por comprador para o tamanho do payload.

    A configuração do leilão do vendedor permitiria que os vendedores especificassem o seguinte:

    1. Lista de compradores permitidos: nos leilões iniciados pelo vendedor, apenas os compradores na lista de permissões poderiam contribuir com os CustomAudiences para o leilão. A configuração do leilão precisaria ser atualizada diariamente para manter a lista de permissões atualizada com a lista de compradores do lado do servidor.
    2. Limite de tamanho por comprador: os vendedores podem especificar um limite por comprador para regular o tamanho dos dados enviados por comprador para o payload que está sendo enviado ao SellerFrontendService. Se o comprador exceder o limite de tamanho por comprador, a prioridade CustomAudience definida na configuração de payload será usada para conseguir os dados nos limites esperados.
    3. Prioridade por comprador: permita que os vendedores definam a prioridade por comprador. A prioridade do comprador será usada para identificar quais dados precisam ser mantidos no payload se o tamanho deles exceder o limite.
    4. Limite de tamanho máximo para o payload: vendedores diferentes podem ter alocação de recursos diferente e podem definir um limite de tamanho máximo para o payload de leilão por solicitação. O limite de tamanho máximo respeitaria os buckets de tamanho fixo definidos pela API Protected Audience.
  4. Mudanças no público-alvo personalizado

    1. Especificar a prioridade do público-alvo personalizado: permita que os compradores especifiquem um valor de prioridade em um público-alvo personalizado. O campo priority seria usado para identificar públicos-alvo personalizados que precisam ser incluídos em um leilão se o conjunto de públicos-alvo personalizados do comprador exceder os limites de tamanho por vendedor ou por comprador. Um valor de prioridade não especificado em um público-alvo personalizado seria padronizado como 0.0.
  5. Mudanças nos dados de payload

    1. Reduzir os dados enviados no payload: conforme detalhado na Otimização de payload dos serviços de lances e leilões, o payload maior é impulsionado por dados ads de público-alvo personalizado, indicadores de lances do usuário e indicadores do Android. Os payloads mais altos podem ser reduzidos por:
      1. Fazer com que o cliente envie IDs de renderização de anúncios (em vez de objetos de anúncios) no payload.
      2. Fazer com que o cliente não envie dados de anúncios no payload.
      3. Não enviar indicadores de lances do usuário no payload do cliente.

Embora as estratégias mencionadas acima permitam que as adtechs definam configurações para gerenciar a composição e os limites do payload do adSelectionData, elas também podem ser fatores que modificam o tamanho do adSelectionData mudando os parâmetros de configuração. Para evitar isso, a configuração seria buscada diariamente pelo público-alvo protegido no endpoint configurado.

Otimização da latência

Para que os leilões de servidor tenham um nível de utilidade desejável, precisamos garantir que as APIs getAdSelectionData e persistAdSelectionResult tenham baixa latência por chamada. Nosso objetivo é oferecer suporte a recursos para APIs em 2023, mas a próxima versão vai se concentrar nos comparativos de mercado e nas otimizações de latência das APIs.

Estamos analisando as seguintes estratégias para manter a latência dentro dos limites aceitáveis:

  1. Pré-geração de dados do público-alvo protegido por vendedor: como a configuração do leilão do vendedor e a configuração do payload do comprador serão estáveis por um período considerável (diariamente), a plataforma poderá pré-calcular e armazenar os dados do público-alvo protegido qualificado.

    Isso exigiria que a plataforma criasse um mecanismo para monitorar as atualizações de público-alvo personalizado e modificar os dados pré-gerados do público protegido com base nas atualizações. A plataforma também precisa declarar SLOs na adtech de atraso de corrida entre as atualizações de público-alvo personalizado e a mudança no adSelectionData gerado para o leilão do servidor.

    Como um dispositivo fornece um modelo de computação de recursos limitado com prioridades de processo variadas, sabemos que o fornecimento dessa instalação de pré-geração precisa vir com alta confiabilidade e garantias de SLOs.

    A pré-geração dos dados de público protegido seria então baseada:

    1. na ativação pelo vendedor da pré-geração de dados do público-alvo protegido;
    2. nos compradores qualificados para participar de um leilão iniciado por um vendedor específico;
    3. na identificação de públicos-alvo personalizados por comprador que farão parte do payload com base em:
      1. limites de tamanho por comprador, prioridade por comprador e limites de tamanho máximo definidos na configuração do vendedor;
      2. limite de tamanho por vendedor, prioridade de público-alvo personalizada definida na configuração do comprador.
  2. Aplicação antecipada da filtragem negativa: se preferencial por um vendedor, a plataforma pode pré-calcular o adSelectionData pré-gerando dados do público-alvo protegido e aplicando a filtragem negativa da chamada getAdSelectionData crítica. Isso permite que os vendedores equilibrem a redução de latência e aceitem a inatividade na filtragem negativa.

    A plataforma pode oferecer esse suporte fornecendo uma opção padrão na configuração do vendedor com um limite de inatividade e uma opção de modificação em getAdSelectionData para permitir o cálculo mais recente, se necessário. Como alternativa, a plataforma pode fornecer uma API de inicialização adicional que será chamada antes de getAdSelectionData para aquecer o leilão.

  3. Computação de payload para vários leilões: em determinados cenários, pode ser preferível ter uma API com desempenho de latência em detrimento do aumento da inatividade dos dados. Para isso, a plataforma pode introduzir uma API de inicialização para calcular todo o payload e fornecer uma referência ao payload calculado ao autor da chamada.

    Para chamadas subsequentes para getAdSelectionData, o autor da chamada pode fornecer referência ao payload pré-computado a ser usado para a geração adSelectionData.

Todas as três estratégias mencionadas acima estão no estágio de exploração inicial e descrevem a direção que a plataforma pode tomar para otimizar a latência. À medida que exploramos perfis de latência mais detalhados dos requisitos de API e adtechs, continuaremos propondo outras estratégias.

Mitigação e identificação de abusos

Como mencionado nas considerações sobre privacidade, adSelectionData é gerado usando todos os dados do comprador no dispositivo.

No entanto, se todos os dados do comprador no dispositivo forem usados para gerar a saída adSelectionData, uma entidade mal-intencionada poderá se passar por um comprador e criar dados fraudulentos do comprador para prejudicar a performance do Android, sobrecarregar o payload para aumentar o custo de uma adtech para realizar leilões ou lances e assim por diante.

Mitigação

Algumas medidas mencionadas na seção de considerações de tamanho, como a configuração do payload do comprador que contém vendedores na lista de permissões e a configuração do leilão do vendedor que contém compradores na lista de permissões, ajudam a excluir dados inesperados no payload.

Outras medidas de consideração de tamanho, como permitir que as SSPs especifiquem a prioridade do comprador, colocar a cota por comprador no payload gerado e definir um tamanho máximo por payload de leilão também podem ajudar a reduzir o impacto da expansão de payload malicioso. Essas medidas são destinadas a permitir que as adtechs definam com que outras adtechs vão colaborar e os limites aceitáveis no payload que precisa ser processado.

Como mencionado anteriormente, todas as mitigações introduzidas para restrições contra abuso e tamanho precisam obedecer às considerações sobre privacidade.

Identificação de entidades maliciosas

Embora as mitigações mencionadas acima protejam a geração de adSelectionData para leilão de servidores, elas não ajudam a identificar entidades maliciosas nem a proteger a plataforma contra abuso, como a criação de um número sem precedentes de públicos-alvo personalizados de um comprador.

Para garantir a estabilidade e a integridade da plataforma, precisamos encontrar um mecanismo para identificar entidades maliciosas, vetores de abuso e motivação para os ataques específicos. Nas próximas versões, apresentaremos explicações sobre os possíveis vetores de abuso e proteções em vigor para evitá-los.