Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,16 @@ jobs:
with:
node-version: ${{ steps.shared-setup.outputs.node-version }}
cache: npm
cache-dependency-path: crates/trusted-server-integration-tests/browser/package-lock.json
cache-dependency-path: |
crates/trusted-server-integration-tests/browser/package-lock.json
crates/trusted-server-js/lib/package-lock.json

- name: Build TSJS browser fixtures
working-directory: crates/trusted-server-js/lib
run: |
npm ci
npm run build
npm run build:prebid-external

- name: Install Playwright
working-directory: crates/trusted-server-integration-tests/browser
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ 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.
- Added optional APS `inventory_domain` and `inventory_page_origin` overrides for deployments whose edge hostname differs from the APS-authorized inventory identity.
- Preserved APS renderer capabilities through the client-side `trustedServer` Prebid adapter, allowing its generated `hb_adid` to render through GAM and Prebid Universal Creative instead of producing an empty creative.

### Security

- Validate synthetic ID format on inbound values from the `x-synthetic-id` header and `synthetic_id` cookie; values that do not match the expected format (`64-hex-hmac.6-alphanumeric-suffix`) are discarded and a fresh ID is generated rather than forwarded to response headers, cookies, or third-party APIs

### Added

- Added opt-in APS HTTP debug metadata for controlled test sites, exposing the direct request and response under `/auction` provider metadata using the Prebid Server `debug.httpcalls` shape.
- 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
Expand Down
5 changes: 3 additions & 2 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
51 changes: 27 additions & 24 deletions crates/trusted-server-core/src/auction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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[] │
Expand Down Expand Up @@ -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
Expand All @@ -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": "<iframe src=\"/first-party/proxy?tsurl=...\">",
"w": 728,
"h": 90,
"crid": "amazon-aps-creative",
"adomain": ["amazon.com"]
"ext": {
"trusted_server": {
"renderer": {
"type": "aps",
"version": 1,
"accountId": "example-account",
"bidId": "fictional-selected-bid-id",
"tagType": "iframe",
"creativeUrl": "https://creative.example/render",
"aaxResponse": "<base64 minimized one-bid envelope>",
"width": 728,
"height": 90
}
}
}
}
]
}
Expand Down
Loading
Loading