Entwicklerleitfaden für Protected App-Signale

Damit Entwickler mit der Protected App Signals API experimentieren können, werden in diesem Dokument alle APIs in der API-Oberfläche, die Einrichtung einer Testumgebung sowie Beispiele für die Konfiguration und die Skripts beschrieben.

Versionsverlauf

Januar 2024

Erste Version des Entwicklerhandbuchs zur Unterstützung der PAS-MVP-Version

March 2024

Änderungen an der API zur Unterstützung des Release M-2024-05 der Android API und des Release April 2024 der serverseitigen Komponenten. Die wichtigsten Änderungen:

  • Details zu den erforderlichen Berechtigungen für die API auf dem Gerät hinzugefügt
  • Es wurden Details zur Kontingentverwaltung für On-Device-Signale hinzugefügt
  • Die generateBid-Signatur wurde mit Änderungen im Zusammenhang mit dem kontextbezogenen Anzeigenabruf und der Unterstützung für ausgehenden Traffic aktualisiert.
  • Die reportWin-Dokumentation, einschließlich Unterstützung für ausgehenden Traffic, wurde aktualisiert
  • Dokumentation zur Ad Retrieval API aktualisieren, um die Unterstützung für den BYOS-Anzeigenabruf zu entfernen und die UDF für den Anzeigenabruf zu dokumentieren

API-Übersicht

Die Oberfläche der Protected Signals API enthält verschiedene API-Teilmengen auf verschiedenen Systemen:

  • Android APIs:
    • Signal Curation API, bestehend aus:
    • Signals API aktualisieren
    • Signals Encoding API
    • Protected Auktion Support API: Zur Verwendung durch SDKs zur Ausführung der geschützten Auktion auf Gebots- und Auktionsservern mit Protected App-Signalen.
  • Serverseitige APIs:
    • Protected Auktions-API: Eine Reihe von JS-Skripts, die auf den Gebots- und Auktionsservern ausgeführt werden. Mit dieser API können Verkäufer und Käufer die Logik zur Implementierung der geschützten Auktion schreiben.
    • Ad Retrieval API: Verantwortlich für die Bereitstellung einer Liste möglicher Anzeigen anhand der Kontext- und Nutzerinformationen, die dem Gebotsserver des Käufers zur Verfügung gestellt werden.

Android-Client

Auf Clientseite besteht die Oberfläche der Protected App Signals aus drei verschiedenen APIs:

  • Aktualisierungssignale: Eine Android System API zur Auswahl von Signalen auf dem Gerät.
  • Signalcodierung: Eine JavaScript API zur Vorbereitung der Signale, die während der Auktion an den Server gesendet werden sollen.
  • Unterstützung für geschützte Auktionen: Eine API zur Unterstützung der Ausführung einer geschützten Auktion auf den Gebots- und Auktionsservern. Diese API ist nicht spezifisch für Protected App-Signale und wird auch verwendet, um Auktionen für die Protected Audience API zu unterstützen.

Signals API aktualisieren

Mit der Update Signals API können Anzeigentechnologie-Anbieter nutzer- und appbezogene Signale im Namen eines Käufers registrieren. Die API arbeitet mit einem Delegationsmodell. Der Aufrufer stellt einen URI bereit, von dem das Framework die entsprechenden Signale abruft, sowie die Logik, um diese Signale für die Auktion zu codieren.

Für die API ist die Berechtigung android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS erforderlich.

Die updateSignals() API ruft ein JSON-Objekt aus dem URI ab, das beschreibt, welche Signale hinzugefügt oder entfernt werden sollen und wie diese Signale für die Auktion vorbereitet werden.

Executor executor = Executors.newCachedThreadPool();
ProtectedSignalsManager protectedSignalsManager
     =  ProtectedSignalsManager.get(context);

// Initialize a UpdateSignalsRequest
UpdateSignalsRequest updateSignalsRequest = new
  UpdateSignalsRequest.Builder(Uri.parse("https://example-adtech1.com/signals"))
      .build();

OutcomeReceiver<Object, Exception> outcomeReceiver = new OutcomeReceiver<Object, Exception>() {
  @Override
  public void onResult(Object o) {
    //Post-success actions
  }

  @Override
  public void onError(Exception error) {
    //Post-failure actions
  };

// Call updateSignals
protectedSignalsManager.updateSignals(updateSignalsRequest,
    executor,
    outcomeReceiver);

Die Plattform stellt eine HTTPS-Anfrage an den in der Anfrage angegebenen URI, um die Signalaktualisierungen abzurufen. Zusammen mit den Signalaktualisierungen kann die Antwort einen Endpunkt enthalten, der die Codierungslogik zum Konvertieren der Rohsignale in codierte Nutzlasten hostet. Die Signalaktualisierungen sollten im JSON-Format vorliegen und die folgenden Schlüssel haben:

Die Schlüssel der obersten Ebene für das JSON-Objekt müssen einem der fünf Befehle entsprechen:

key

Beschreibung

put

Fügt ein neues Signal hinzu und überschreibt alle vorhandenen Signale mit demselben Schlüssel. Der Wert

Dies ist ein JSON-Objekt, bei dem die Schlüssel Basis 64-Strings sind, die dem zu setzenden Schlüssel entsprechen, und die Werte Basis 64-Strings, die dem zu setzenden Wert entsprechen.

append

An eine Zeitreihe von Signalen wird/werden ein neues Signal bzw. Signale angehängt und das älteste entfernt

Signalen, um Platz für neue zu schaffen, falls die Reihen größer sind als das vorgegebene Maximum. Der Wert für dieses Objekt ist ein JSON-Objekt, bei dem die Schlüssel Basis 64-Strings sind, die dem Schlüssel entsprechen, an den der Schlüssel angehängt werden soll. Die Werte sind Objekte mit zwei Feldern: „values“ und „maxSignals“.

„values“: Eine Liste von Base64-Strings, die den Signalwerten entsprechen, die an die Zeitreihe angehängt werden sollen.

„maxSignals“: Die maximale Anzahl von Werten, die in dieser Zeitreihe zulässig sind. Wenn

Die aktuelle Anzahl der mit dem Schlüssel verknüpften Signale überschreitet „maxSignals“. Die ältesten Signale werden entfernt. Sie können Daten an einen Schlüssel anhängen, der durch „put“ hinzugefügt wurde. Beachten Sie, dass das Anfügen von mehr als der maximalen Anzahl von Werten zu einem Fehler führt.

put_if_not_present

Fügt nur dann ein neues Signal hinzu, wenn keine Signale mit demselben Schlüssel vorhanden sind. Der Wert für diesen Wert ist ein JSON-Objekt, bei dem die Schlüssel Basis 64-Strings sind, die dem zu setzenden Schlüssel entsprechen, und die Werte Basis 64-Strings, die dem zu übergebenden Wert entsprechen.

remove

Entfernt das Signal für einen Schlüssel. Der Wert ist eine Liste von Base64-Strings, die den zu löschenden Signalschlüsseln entsprechen.

update_encoder

Liefert eine Aktion zum Aktualisieren des Endpunkts und einen URI, der verwendet werden kann

um eine Codierungslogik abzurufen. Der Unterschlüssel zum Angeben einer Aktualisierungsaktion ist "Aktion" und der

-Werte werden derzeit nur über "REGISTER" unterstützt. Damit wird der Encoder-Endpunkt registriert, der zum ersten Mal angegeben wurde, oder er überschreibt den vorhandenen mit dem neu bereitgestellten Endpunkt. Für die Aktion "REGISTER" muss der Endpunkt angegeben werden. Der Unterschlüssel zum Angeben eines Encoder-Endpunkts ist "endpoint" und der Wert ist der URI.

String für den Endpunkt.

Eine JSON-Beispielanfrage würde so aussehen:

{
    "put": {
        "AAAAAQ==": "AAAAZQ==",
        "AAAAAg==": "AAAAZg=="
    },
    "append": {
        "AAAAAw==": {
            "values": [
                "AAAAZw=="
            ],
            "max_signals": 3
        }
    },
    "put_if_not_present": {
        "AAAABA==": "AAAAaQ==",
        "AAAABQ==": "AAAAag=="
    },
    "update_encoder": {
        "action": "REGISTER",
        "endpoint": "https://adtech1.com/Protected App Signals_encode_script.js"
    }
}

Für Signale gilt ein On-Device-Kontingent von 10 bis 15 KB. Sobald das Kontingent überschritten ist, entfernt PPAPI Signale mithilfe einer FIFO-Strategie. Durch den Bereinigungsprozess kann das Kontingent für kurze Zeiträume leicht überschritten werden, um die Häufigkeit von Bereinigungen zu reduzieren.

Signals Encoding API

Käufer müssen eine JavaScript-Funktion zur Codierung der auf dem Gerät gespeicherten Signale bereitstellen, die während der geschützten Auktion an den Server gesendet werden sollen. Käufer können dieses Script bereitstellen, indem sie die URL, von der sie abgerufen werden können, mit dem Schlüssel „update_encoder“ in einer der Antworten auf eine UpdateSignal API-Anfrage hinzufügen. Das Skript hat die folgende Signatur:

function encodeSignals(signals, maxSize) {
  let result = new Uint8Array(maxSize);
  // first entry will contain the total size
  let size = 1;
  let keys = 0;
  
  for (const [key, values] of signals.entries()) {
    keys++;
    // In this encoding we only care about the first byte
    console.log("key " + keys + " is " + key)
    result[size++] = key[0];
    result[size++] = values.length;
    for(const value of values) {
      result[size++] = value.signal_value[0];
    }
  }
  result[0] = keys;
  
  return { 'status': 0, 'results': result.subarray(0, size)};
}

Der Parameter signals ist eine Zuordnung von Schlüsseln in Form von UInt8Arrays der Größe 4 zu Listen von Protected App Signals-Objekten. Jedes Protected App Signals-Objekt hat drei Felder:

  • signal_value: Ein UInt8Array, das den Wert des Signals darstellt.
  • creation_time: Eine Zahl, die den Erstellungszeitpunkt der Signale in Epochensekunden angibt.
  • package_name: Ein String, der den Namen des Pakets darstellt, das das Signal erstellt hat.

Der Parameter maxSize ist eine Zahl, die die größte zulässige Arraygröße für die Ausgabe angibt.

Die Funktion sollte ein Objekt mit zwei Feldern ausgeben:

  • status: Sollte 0 sein, wenn das Script erfolgreich ausgeführt wurde.
  • results: Sollte ein UInt8Array mit Länge kleiner oder gleich maxSize sein. Dieses Array wird bei Auktionen an den Server gesendet und vom Skript prepareDataForAdRetrieval vorbereitet.

Die Codierung bietet AdTech-Mitarbeitern eine erste Phase des Feature Engineering, in der sie Transformationen wie die Komprimierung von Rohsignalen in verketteten Versionen basierend auf ihrer eigenen benutzerdefinierten Logik ausführen können. Während einer geschützten Auktion in den vertrauenswürdigen Ausführungsumgebungen (Trusted Execution Environments, TEE) hat die benutzerdefinierte Logik der Anzeigentechnologie Lesezugriff auf die durch die Codierung generierten Signalnutzlasten. Die als User Defined Function (UDF) bezeichnete benutzerdefinierte Logik, die im B&A TEE des Käufers ausgeführt wird, hat Lesezugriff auf die codierten Signale und andere Kontextsignale, die von der Publisher-App bereitgestellt werden, um die Anzeigenauswahl (Anzeigenabruf und Gebote) durchzuführen.

Signalcodierung

Die Signale von Käufern, die mit ihren registrierten Signalen eine Codierungslogik bereitgestellt haben, werden stündlich in einer Auktionsnutzlast codiert.Das Byte-Array für die Auktionsnutzlast wird auf dem Gerät beibehalten, verschlüsselt und von den Verkäufern als Teil der Daten zur Anzeigenauswahl erfasst, um sie in eine geschützte Auktion aufzunehmen. Zu Testzwecken können Sie diese Codierung außerhalb des stündlichen Rhythmus auslösen, indem Sie den folgenden Befehl ausführen:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Versionsverwaltung für Encoder-Logik

Wenn eine Anfrage zum Herunterladen der benutzerdefinierten AdTech-Encoder-Logik gesendet wird, kann der AdTech-Endpunkt mit einer Versionsnummer in den Antwortheadern antworten. Diese Version wird zusammen mit der Encoder-Logik auf dem Gerät beibehalten. Wenn die Rohsignale codiert sind, wird die codierte Nutzlast zusammen mit der für die Codierung verwendeten Version beibehalten. Diese Version wird auch während einer geschützten Auktion an den B&A-Server gesendet, damit Anzeigentechnologie-Anbieter ihre Gebots- und Codierungslogik auf Grundlage der Version abstimmen können.

Response header for providing encoder version : X_ENCODER_VERSION

Protected Auktion Support API

Auf Geräteseite ist eine Auktion für geschützte App-Signale mit einer Auktion für geschützte Zielgruppen identisch.

Gebots- und Auktionsdienste

Zu den serverseitigen APIs gehören:

  • Geschützte Auktions-API: Eine Reihe von JS-Funktionen oder UDFs, die Käufer und Verkäufer für ihre B&A-Komponenten bereitstellen können, um die Gebots- und Auktionslogik zu bestimmen.
  • Ad Retrieval API: Käufer können diese API implementieren, indem sie einen REST-Endpunkt implementieren, der für die Bereitstellung einer Reihe von potenziellen Anzeigen für die Protected App-Signal-Auktion verantwortlich ist.

Geschützte Auktions-API

Die Protected Auktion API besteht aus der JS API oder UDFs, mit denen Käufer und Verkäufer ihre Auktions- und Gebotslogik implementieren können.

UDFs für Anzeigentechnologie-Käufer
UDF vorbereitenDataForAdRetrieval

Bevor über geschützte App-Signale Anzeigen aus dem TEE-Abrufdienst für Anzeigen abgerufen werden können, müssen Käufer die geschützten App-Signale und andere von Verkäufern bereitgestellte Daten decodieren und vorbereiten. Die UDF-Ausgabe des Käufers prepareDataForAdRetrieval wird an den Anzeigen-Abrufdienst weitergeleitet, um die am besten k möglichen Anzeigen für Gebote abzurufen.

// Inputs
// ------
// encodedOnDeviceSignals: A Uint8Array of bytes from the device.
// encodedOnDeviceSignalsVersion: An integer representing the encoded
//   version of the signals.
// sellerAuctionSignals: Information about auction (ad format, size) derived
//                       contextually.
// contextualSignals: Additional contextual signals that could help in
//                    generating bids.
//
// Outputs
// -------
// Returns a JSON structure to be used for retrieval.
// The structure of this object is left to the adtech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
„generateBid“-UDF

Nachdem die besten k möglichen Anzeigen zurückgegeben wurden, werden diese an die Logik für benutzerdefinierte Gebote des Käufers (generateBid UDF) übergeben:

// Inputs
// ------
// ads: Data string returned by the ads retrieval service. This can include Protected App Signals
//   ads and related ads metadata.
// sellerAuctionSignals: Information about the auction (ad format, size),
//                       derived contextually
// buyerSignals: Any additional contextual information provided by the buyer
// preprocessedDataForRetrieval: This is the output of this UDF.
function generateBid(ads, sellerAuctionSignals, buyerSignals,
                    preprocessedDataForRetrieval,
                    rawSignals, rawSignalsVersion) {
    return { "ad": <ad Value Object>,
             "bid": <float>,
             "render": <render URL string>,
             'adCost': <optional float ad cost>,
             "egressPayload": <limitedEgressPayload>,
             "temporaryUnlimitedEgressPayload": <temporaryUnlimitedEgressPayload>
    };
}

Die Ausgabe dieser Funktion ist ein einzelnes Gebot für eine Anzeige, das als JSON-Äquivalent zu ProtectedAppSignalsAdWithBidMetadata dargestellt wird. Die Funktion kann auch zwei Arrays zurückgeben, die dann an reportWin übergeben werden, um das Modelltraining zu ermöglichen. Weitere Informationen zu ausgehendem Traffic und Modelltraining finden Sie im Abschnitt zur Berichterstellung in der PAS-Erklärung.

UDF für „reportWin“

Wenn eine Auktion abgeschlossen ist, generiert der Auktionsdienst Berichts-URLs für die Käufer und registriert Beacons mithilfe von reportWin. Dies ist dieselbe reportWin-Funktion, die auch für geschützte Zielgruppen verwendet wird. Diese wird vom Gerät angepingt, sobald die Anzeige vom Client gerendert wurde. Die Signatur dieser Methode ist fast mit der Protected Audience-Version identisch, mit Ausnahme der beiden zusätzlichen Parameter egressPayload und temporaryUnlimitedEgressPayload, die zum Aktivieren des Modelltrainings verwendet werden und mit den Ergebnissen von generateBid gefüllt werden.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
AdTech-User für Verkäufer
„scoreAd“-UDF

Diese UDF wird von Verkäufern verwendet, um auszuwählen, welche der von Käufern erhaltenen Anzeigen die Auktion gewinnen.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
UDF für „reportResult“

Diese UDF ermöglicht dem Verkäufer, (letztendlich) Berichte auf Ereignisebene mit den Informationen zur erfolgreichen Anzeige zu erstellen.

function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}

Ad Retrieval API

In der MVP-Version ist der Anzeigen-Abrufdienst ein vom Käufer verwalteter und gehosteter Dienst und der Bidding-Dienst ruft Anzeigenkandidaten aus diesem Dienst ab. Ab April 2024 muss der Server zum Abrufen von Anzeigen in einer vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) ausgeführt werden und eine GRPC-/Proto-Oberfläche bereitstellen. AdTech-Unternehmen müssen diesen Server einrichten und seine URL im Rahmen der Bereitstellung des B&A-Stacks angeben. Eine Implementierung dieses Dienstes, der im TEE ausgeführt wird, ist im Privacy Sandbox GitHub verfügbar. In der restlichen Dokumentation gehen wir davon aus, dass dies der in der Bereitstellung verwendete Code ist.

Ab April 2024 wird das Abrufen von kontextbezogenen Pfadanzeigen in B&A-Versionen unterstützt. In diesem Fall erhält der Bidding-Server eine Liste mit Anzeigen-IDs, die vom RTB-Server während des kontextbezogenen Teils der Auktion gesendet werden. Die Kennungen werden an einen TEE KV-Server gesendet, um alle anzeigenbezogenen Informationen abzurufen, die während der Gebotsphase verwendet werden sollen (z. B. Anzeigen-Rendering-URL, Metadaten und Anzeigeneinbettungen für die Top-K-Auswahl). Dieser zweite Pfad benötigt keine spezifische Logik für die Bereitstellung. Daher wird hier nur beschrieben, wie der TEE-basierte Anwendungsfall für den Anzeigenabruf konfiguriert wird.

HandleRequest-UDF
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals) {
    return adsMetadataString;
}

Wobei:

  • requestMetadata: JSON. Server-Metadaten pro Anfrage an die UDF. Vorerst leer.
  • preparedDataForAdRetrieval: Der Inhalt dieses Felds hängt von der Strategie für den Anzeigenabruf ab. Beim Abrufen von kontextbezogenen Anzeigen enthält dieser Parameter die Rohsignale des Geräts, die vom Gebotsdienst übergeben werden. Beim Abrufen von TEE-Anzeigen mithilfe des Anzeigenabrufservers enthält dieser Parameter das Ergebnis der UDF prepareDataForAdRetrieval. Hinweis: In dieser Phase werden die geschützten App-Signale decodiert und unverschlüsselt.
  • deviceMetadata: JSON-Objekt mit Gerätemetadaten, die vom Anzeigendienst des Verkäufers weitergeleitet wurden. Weitere Informationen finden Sie in der B&A-Dokumentation.
    • X-Accept-Language ist die auf dem Gerät verwendete Sprache.
    • X-User-Agent: Der auf dem Gerät verwendete User-Agent.
    • X-BnA-Client-IP: IP-Adresse des Geräts
  • contextualSignals: Beliebiger String, der von dem kontextbezogenen Gebotsserver stammt, der von derselben DSP betrieben wird. Es wird erwartet, dass die UDF den String decodieren und verwenden kann. Kontextsignale können beliebige Informationen wie Versionsinformationen des ML-Modells für die geschützte Einbettung enthalten, die mithilfe von Protected App-Signalen übergeben werden.

Die UDF sollte bei Erfolg einen String zurückgeben. Der String wird an den Bidding-Server zurückgegeben, der ihn dann an die UDF generateBid übergibt. Auch wenn der String einfach ein einfacher String sein kann, sollte er höchstwahrscheinlich ein serielles Objekt sein, dessen Schema von jeder Anzeigentechnologie selbst definiert wird. Es gibt keine Einschränkung des Schemas, solange die generateBid-Logik der Anzeigentechnologie den String erkennen und verwenden kann.

System für die Entwicklung einrichten

Android

So richten Sie Ihre Android-Entwicklungsumgebung ein:

  1. Emulator (bevorzugt) oder physisches Gerät erstellen, auf dem das Bild für die Entwicklervorschau 10 ausgeführt wird
  2. Führen Sie den folgenden Befehl aus:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

Wählen Sie dann die Option zur Einwilligung in von Apps vorgeschlagene Werbung aus.

  1. Führen Sie den folgenden Befehl aus, um die entsprechenden APIs zu aktivieren. Möglicherweise müssen Sie dies gelegentlich wiederholen, da die Standardkonfiguration von „Deaktiviert“ regelmäßig synchronisiert wird.
adb shell device_config put adservices fledge_custom_audience_service_kill_switch false;  adb shell device_config put adservices fledge_select_ads_kill_switch false; adb shell device_config put adservices fledge_on_device_auction_kill_switch false; adb shell device_config put adservices fledge_auction_server_kill_switch false; adb shell "device_config put adservices disable_fledge_enrollment_check true";  adb shell device_config put adservices ppapi_app_allow_list '\*'; adb shell device_config put adservices fledge_auction_server_overall_timeout_ms 60000;
  1. Starten Sie das Gerät neu.
  2. Überschreiben Sie die Auktionsschlüssel des Geräts, sodass sie auf den Auktionsschlüsselserver verweisen. Dieser Schritt muss vor einer Auktion durchgeführt werden, um zu verhindern, dass falsche Schlüssel im Cache gespeichert werden.

Gebots- und Auktionsdienste

Informationen zum Einrichten der B&A-Server finden Sie in der Dokumentation zur Selfservice-Einrichtung.

In diesem Dokument wird die Konfiguration käuferspezifischer Server beschrieben, da für Verkäufer keine Änderungen erforderlich sind.

Voraussetzungen

Bevor ein B&A-Stack bereitgestellt wird, muss der Anzeigentechnologie-Käufer Folgendes tun:

  • Es muss ein eigener Abrufdienst für TEE-Anzeigen implementiert sein (siehe entsprechender Abschnitt).
  • Sorgen Sie dafür, dass der Anzeigentechnologie-Anbieter alle erforderlichen UDFs (prepareDataForAdRetrieval, generateBid, reportWin, HandleRequest) definiert und gehostet hat.

Es ist ebenfalls hilfreich, zu verstehen, wie die Protected Auktion mit Protected Audience zusammen mit B&A funktioniert.

Terraform-Konfiguration

Damit Anzeigentechnologie-Anbieter geschützte App-Signale nutzen können, müssen sie

  • Unterstützung geschützter App-Signale in B&A aktivieren.
  • Geben Sie URL-Endpunkte an, von denen die neuen UDFs für prepareDataForAdRetrieval, generateBid und reportWin abgerufen werden können.

Außerdem wird in diesem Leitfaden davon ausgegangen, dass Anzeigentechnologie-Anbieter, die B&A für das Remarketing verwenden möchten, weiterhin wie gewohnt alle vorhandenen Konfigurations-Flags für Remarketing-Auktionen setzen.

Konfiguration der Anzeigentechnologie des Käufers

Wenn Sie diese Demodatei als Beispiel verwenden, müssen Käufer die folgenden Flags festlegen:

  • Geschützte App-Signale aktivieren: Aktiviert, um Daten über geschützte App-Signale zu erfassen.
  • Protected App Signals-URLs: Legen Sie die URLs der Protected App Signals-Server fest.

AdTechs müssen in den Platzhaltern für die folgenden Felder die korrekten URLs ersetzen:

module "buyer" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"
    PROTECTED_APP_SIGNALS_GENERATE_BID_TIMEOUT_MS = "60000"
    TEE_AD_RETRIEVAL_KV_SERVER_ADDR               = "<service mesh address of the instance>"
    AD_RETRIEVAL_TIMEOUT_MS                       = "60000"
    BUYER_CODE_FETCH_CONFIG                       = <<EOF
    {
        "protectedAppSignalsBiddingJsUrl": "<URL to Protected App Signals generateBid UDF>",
        "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
        "urlFetchPeriodMs": 13000000,
        "prepareDataForAdsRetrievalJsUrl": "<URL to the UDF>"
    }
    EOF

  }  # runtime_flags

}  # Module "buyer"

Konfiguration der Anzeigentechnologie des Verkäufers

Wenn Sie die Demodatei als Beispiel verwenden, müssen Verkäufer die folgenden Flags festlegen. Hinweis: Hier ist nur die Konfiguration für geschützte App-Signale hervorgehoben. AdTech-Teams müssen dafür sorgen, dass sie in den Platzhaltern die richtigen URLs ersetzen:

module "seller" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"

    SELLER_CODE_FETCH_CONFIG                           = <<EOF
  {
    "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
    "urlFetchPeriodMs": 13000000,
    "protectedAppSignalsBuyerReportWinJsUrls": {"<Buyer Domain>": "URL to reportWin UDF"}
  }
  EOF

  }  # runtime_flags

}  # Module "seller"

KV und Anzeigen-Abrufdienste

Abhängig von den gewählten Strategien zur Unterstützung des Anzeigenabrufs muss das System eine oder zwei Instanzen des KV-Dienstes bereitstellen. Die KV-Instanzinstanz, die für den TEE-basierten Anzeigenabruf verwendet wird, wird Ad Retrieval Server genannt. Die Instanz, die den kontextbezogenen, pfadbasierten Abruf unterstützt, wird als KV Lookup Server bezeichnet.

In beiden Fällen folgt die Serverbereitstellung der Dokumentation im KV-Server-GitHub. Der Unterschied zwischen den beiden Fällen besteht darin, dass die Suche sofort und ohne zusätzliche Konfiguration funktioniert, während für den Abruf die UDF HandleRequest zur Implementierung der Abruflogik erforderlich ist. Weitere Informationen finden Sie im Onboarding-Leitfaden für KV-Server. B&A erwartet, dass beide Dienste im selben Service Mesh wie der Gebotsdienst bereitgestellt werden.

Beispieleinrichtung

Stellen Sie sich folgendes Szenario vor: Mithilfe der Protected App Signals API speichert ein Anzeigentechnologie-Anbieter relevante Signale basierend auf der App-Nutzung der Nutzer. In unserem Beispiel werden Signale gespeichert, die In-App-Käufe in mehreren Apps darstellen. Während einer Auktion werden die verschlüsselten Signale erfasst und an eine geschützte Auktion weitergegeben, die in B&A ausgeführt wird. Die UDFs des Käufers, die in der B&A ausgeführt werden, nutzen die Signale, um Anzeigenkandidaten abzurufen und ein Gebot zu berechnen.

[Käufer] Beispiele für Signale

Fügt ein Signal mit dem Schlüssel 0 und dem Wert 1 hinzu.

{
  "put": {
    "AA==": "AQ=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

Fügt ein Signal mit dem Schlüssel 1 und dem Wert 2 hinzu.

{
  "put": {
    "AQ==": "Ag=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

[Käufer] Encoder-Signale-Beispiel

Codiert jedes Signal in zwei Byte, wobei das erste Byte das erste Byte des Signalschlüssels und das zweite Byte das erste Byte des Signalwerts ist.

function encodeSignals(signals, maxSize) {
  // if there are no signals don't write a payload
  if (signals.size === 0) {
      return {};
  }

  let result = new Uint8Array(signals.size * 2);
  let index = 0;
  
  for (const [key, values] of signals.entries()) {
    result[index++] = key[0];
    result[index++] = values[0].signal_value[0];
  }
  
  return { 'status': 0, 'results': result};
}

[Käufer] PrepareDataForAdRetrieval – Beispiel

/**
 * `encodedOnDeviceSignals` is a Uint8Array and would contain
 * the app signals emanating from device. For purpose of the
 * demo, in our sample example, we assume that device is sending
 * the signals with pair of bytes formatted as following:
 * "<id><In app spending>". Where id corresponds to an ad category
 * that user uses on device, and the in app spending is a measure
 * of how much money the user has spent in this app category
 * previously. In our example, id of 0 will correspond to a
 * fitness ad category and a non-zero id will correspond to
 * food app category -- though this info will be useful
 * later in the B&A pipeline.
 *
 * Returns a JSON object indicating what type of ad(s) may be
 * most relevant to the user. In a real setup ad techs might
 * want to decode the signals as part of this script.
 *
 * Note: This example script makes use of only encoded device signals
 * but adtech can take other signals into account as well to prepare
 * the data that will be useful down stream for ad retrieval and
 * bid generation. The max length of the app signals used in this
 * sample example is arbitrarily limited to 4 bytes.
 */
function prepareDataForAdRetrieval(encodedOnDeviceSignals,
                                   encodedOnDeviceSignalsVersion,
                                   sellerAuctionSignals,
                                   contextualSignals) {
  if (encodedOnDeviceSignals.length === 0 || encodedOnDeviceSignals.length > 4 ||
      encodedOnDeviceSignals.length % 2 !== 0) {
     throw "Expected encoded signals length to be an even number in (0, 4]";
  }

  var preparedDataForAdRetrieval = {};
  for (var i = 0; i < encodedOnDeviceSignals.length; i += 2) {
    preparedDataForAdRetrieval[encodedOnDeviceSignals[i]] = encodedOnDeviceSignals[i + 1];
  }
  return preparedDataForAdRetrieval;
}

[Käufer] Beispiel für UDF beim Anzeigenabruf

In unserem Beispiel sendet der Server zum Abrufen von Anzeigen Metadaten (in diesem Beispiel eine ID für jede Anzeige, die aber andere Daten enthalten kann, die später bei der Generierung von Geboten hilfreich sein können) für jeden der Top k Anzeigenkandidaten.

function HandleRequest(requestMetadata, protectedSignals, deviceMetadata,
                      contextualSignals) {
 return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"

[Käufer] Beispiel für „generateBid“

/**
 * This script receives the data returned by the ad retrieval service
 * in the `ads` argument. This argument is supposed to contain all
 * the Protected App Signals related ads and the metadata obtained from the retrieval
 * service.
 *
 * `preparedDataForAdRetrieval` argument contains the data returned
 * from the `prepareDataForAdRetrieval` UDF.
 *
 * This script is responsible for generating bids for the ads
 * collected from the retrieval service and ad techs can decide to
 * run a small inference model as part of this script in order to
 * decide the best bid given all the signals available to them.
 *
 * For the purpose of the demo, this sample script assumes
 * that ad retrieval service has sent us most relevant ads for the
 * user and this scripts decides on the ad render URL as well as
 * what value to bid for each ad based on the previously decoded
 * device signals. For simplicity sake, this script only considers
 * 2 types of app categories i.e. fitness and food.
 *
 * Note: Only one bid is returned among all the
 * input ad candidates.
 */
function generateBid(ads, sellerAuctionSignals, buyerSignals, preparedDataForAdRetrieval) {
  if (ads === null) {
    console.log("No ads obtained from the ad retrieval service")
    return {};
  }     
        
  const kFitnessAd = "0";
  const kFoodAd = "1";
  const kBuyerDomain = "https://buyer-domain.com";
        
  let resultingBid = 0;
  let resultingRender = kBuyerDomain + "/no-ad";
  for (let i = 0 ; i < ads.length; ++i) {
    let render = "";
    let bid = 0;
    switch (ads[i].adId) {
      case kFitnessAd:
        render = kBuyerDomain + "/get-fitness-app";
        bid = preparedDataForAdRetrieval[kFitnessAd];
        break;
      case kFoodAd:
        render = kBuyerDomain + "/get-fastfood-app";
        bid = preparedDataForAdRetrieval[kFoodAd];
        break;
      default:
        console.log("Unknown ad category");
        render = kBuyerDomain + "/no-ad";
        break;
    }
    console.log("Existing bid: " + resultingBid + ", incoming candidate bid: " + bid);
    if (bid > resultingBid) {
      resultingBid = bid;
      resultingRender = render;
    }
  }
  return {"render": resultingRender, "bid": resultingBid};
}

[Käufer] reportWin-Beispiel

Die UDF vom Typ „reportWin“ meldet dem Käufer, dass er die Auktion gewonnen hat.

function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                                       buyerReportingSignals, directFromSellerSignals,
                                       egressPayload,
                                       temporaryUnlimitedEgressPayload) {
  sendReportTo("https://buyer-controlled-domain.com/");
  registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
  return;
}

[Verkäufer] KV-Server einrichten

Verkäufer müssen einen KV-Server für Bewertungssignale einrichten, damit eine Zuordnung von den Anzeigen-Rendering-URLs zu den entsprechenden Bewertungssignalen möglich ist. Beispiel: Wenn der Käufer https:/buyer-domain.com/get-fitness-app und https:/buyer-domain.com/get-fastfood-app zurückgibt, kann der Verkäufer beim Abfragen von SFE mit einem GET für https://key-value-server-endpoint.com?client_type=1&renderUrls=<render-url-returned-by-the-buyer> folgende Beispielantwort für Bewertungssignale erhalten:

{
   "renderUrls" : {
      "https:/buyer-domain.com/get-fitness-app" : [
         "1",
         "2"
      ],
      "https:/buyer-domain.com/get-fastfood-app" : [
         "3",
         "4"
      ]
   }
}

[Verkäufer] ScoreAd – Beispiel

/**
 * This module generates a random desirability score for the Protected App
 * Signals ad in this example. In a production deployment,
 * however, the sellers would want to use all the available signals to generate
 * a score for the ad.
 */
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function scoreAd(adMetadata, bid, auctionConfig,
                                   trustedScoringSignals, deviceSignals,
                                   directFromSellerSignals) {
  return {
    "desirability": getRandomInt(10000),
    "allowComponentAuction": false
  };
}

[Verkäufer] Beispiel für „reportResult“

function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}

Beispielanwendung

Als Beispiel dafür, wie die API zum Erstellen einer Anwendung verwendet werden kann, die einen wie oben beschriebenen einfachen Ablauf verwendet, haben wir eine Beispiel-App für Protected App-Signale erstellt, die sich in diesem Beispiel-Repository befindet.