From 1610e9daf9370ce979f2b2e990d96d753700c72b Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 15 Jul 2026 21:10:41 -0500 Subject: [PATCH 1/5] Add first-class APS OpenRTB integration --- CHANGELOG.md | 2 + TESTING.md | 5 +- .../trusted-server-core/src/auction/README.md | 51 +- .../src/auction/formats.rs | 185 +- .../src/auction/orchestrator.rs | 179 +- .../src/auction/telemetry.rs | 3 + .../trusted-server-core/src/auction/types.rs | 138 +- .../src/creative_opportunities.rs | 31 +- .../src/integrations/adserver_mock.rs | 202 +- .../src/integrations/aps.rs | 2280 +++++++++-------- .../src/integrations/mod.rs | 4 + .../src/integrations/prebid.rs | 57 +- crates/trusted-server-core/src/openrtb.rs | 14 +- crates/trusted-server-core/src/publisher.rs | 86 +- .../README.md | 1 + .../browser/tests/shared/aps-renderer.spec.ts | 614 +++++ .../configs/trusted-server.integration.toml | 7 +- .../trusted-server-js/lib/src/core/auction.ts | 99 +- .../trusted-server-js/lib/src/core/request.ts | 10 +- .../trusted-server-js/lib/src/core/types.ts | 22 + .../lib/src/integrations/aps/render.ts | 301 +++ .../lib/src/integrations/gpt/index.ts | 47 +- .../lib/test/core/auction.test.ts | 94 + .../lib/test/core/request.test.ts | 102 + .../lib/test/fixtures/aps-renderer-v1.json | 18 + .../lib/test/integrations/aps/render.test.ts | 295 +++ .../lib/test/integrations/gpt/ad_init.test.ts | 189 +- docs/guide/auction-orchestration.md | 150 +- docs/guide/configuration.md | 5 +- docs/guide/integrations/aps.md | 454 +--- docs/roadmap.md | 12 +- ...-15-aps-openrtb-first-class-integration.md | 897 +++++++ ...03-19-auction-orchestration-flow-design.md | 6 + ...-openrtb-first-class-integration-design.md | 839 ++++++ trusted-server.example.toml | 6 +- 35 files changed, 5651 insertions(+), 1754 deletions(-) create mode 100644 crates/trusted-server-integration-tests/browser/tests/shared/aps-renderer.spec.ts create mode 100644 crates/trusted-server-js/lib/src/integrations/aps/render.ts create mode 100644 crates/trusted-server-js/lib/test/fixtures/aps-renderer-v1.json create mode 100644 crates/trusted-server-js/lib/test/integrations/aps/render.test.ts create mode 100644 docs/superpowers/plans/2026-07-15-aps-openrtb-first-class-integration.md create mode 100644 docs/superpowers/specs/2026-07-15-aps-openrtb-first-class-integration-design.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bc49c80b..28a4e4806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **Breaking** — Replaced the legacy APS contextual integration with APS OpenRTB at `/e/pb/bid`. APS configuration now uses canonical `account_id` (`pub_id` remains a compatibility alias), no longer requires APS-specific slot IDs, and defaults script creative eligibility off. Operators must update the endpoint, disable native APS demand for Trusted Server cohorts, and prepare GAM/Universal Creative targeting for `hb_bidder=aps` before rollout. - **Breaking** — `bid_param_zone_overrides` inner values must now be JSON objects; previously non-object or empty values (`"header" = "x"`, `"header" = {}`) were accepted and silently produced a dead rule at runtime. They now fail at startup with a configuration error. Operators upgrading should audit their `bid_param_zone_overrides` config for non-object zone entries. - **Breaking** — Sourcepoint browser module inclusion now requires explicit `[integrations.sourcepoint].enabled = true`; operators relying on the previous unconditional Sourcepoint module should enable the integration before upgrading. @@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added typed APS renderer transport for direct auctions and GAM/Prebid Universal Creative, using a minimized one-bid envelope, a fragment-bound nonce, and an opaque sandboxed renderer endpoint. - Added Osano consent mirror integration docs and public enablement guidance. - Implemented basic authentication for configurable endpoint paths (#73) - Added integrations guide with example `testlight` integration diff --git a/TESTING.md b/TESTING.md index e1ac1c3a2..c4a8c43ea 100644 --- a/TESTING.md +++ b/TESTING.md @@ -131,8 +131,9 @@ INFO: Running 2 bidders in parallel INFO: Requesting bids from: prebid INFO: Prebid returned 2 bids (time: 120ms) INFO: Requesting bids from: aps -INFO: APS (MOCK): returning 2 bids in 80ms -INFO: GAM mediation: slot 'header-banner' won by 'amazon-aps' at $2.50 CPM +INFO: APS requests bids for 2 impressions +INFO: APS returns 2 accepted bids in 80ms +INFO: GAM mediation: slot 'header-banner' won by 'aps' at $2.50 CPM ``` ### Verify Provider Registration diff --git a/crates/trusted-server-core/src/auction/README.md b/crates/trusted-server-core/src/auction/README.md index dcc9e1506..fad3cb4d5 100644 --- a/crates/trusted-server-core/src/auction/README.md +++ b/crates/trusted-server-core/src/auction/README.md @@ -117,7 +117,7 @@ When a request arrives at the `/auction` endpoint, it goes through the following ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ 9. Each Provider Processes Request │ -│ - Transform AuctionRequest → Provider format (e.g., APS TAM) │ +│ - Transform AuctionRequest → Provider OpenRTB request │ │ - Send HTTP request to provider endpoint │ │ - Parse provider response │ │ - Transform → AuctionResponse with Bid[] │ @@ -188,30 +188,21 @@ AdSlot { #### 3. Provider Execution Each registered provider (APS, Prebid, etc.) receives the `AuctionRequest` and: -- Transforms it to their specific format (e.g., APS TAM, OpenRTB) +- Transforms it to the provider's OpenRTB request format - Makes HTTP request to their endpoint - Parses the response - Returns `AuctionResponse` with `Bid[]` For example, APS provider: ```rust -// Transform AuctionRequest → ApsBidRequest -let aps_request = ApsBidRequest { - pub_id: "5128", - slots: vec![ - ApsSlot { - slot_id: "header-banner", - sizes: vec![[728, 90], [970, 250]], - slot_name: Some("header-banner"), - } - ], - page_url: Some("https://example.com"), - ua: Some("Mozilla/5.0..."), - timeout: Some(800), -}; - -// HTTP POST to http://localhost:6767/e/dtb/bid -// Parse response → AuctionResponse +// Transform AuctionRequest → APS OpenRTB request +// - ext.account = configured account_id +// - ext.sdk = { source: "prebid", version: "2.2.0" } +// - banner slots become secure impressions with matching formats/floors +// - existing consent, identity, device, and geo privacy gates apply + +// HTTP POST to https://web.ads.aps.amazon-adsystem.com/e/pb/bid +// Parse decoded-price response → AuctionResponse with a typed renderer ``` #### 4. Response Assembly @@ -222,17 +213,29 @@ The orchestrator collects all bids and creates an OpenRTB response: "id": "auction-response", "seatbid": [ { - "seat": "amazon-aps", + "seat": "aps", "bid": [ { - "id": "amazon-aps-header-banner", + "id": "fictional-selected-bid-id", "impid": "header-banner", "price": 2.5, - "adm": "