Skip to content

Move OpenRTB into an auction protocol module - #1388

Open
jwrosewell wants to merge 49 commits into
feature/44-client-hintsfrom
feature/45-openrtb
Open

jwrosewell wants to merge 49 commits into
feature/44-client-hintsfrom
feature/45-openrtb

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Changes

Area Change
crates/trusted-server-core/src 25 files, 1434 lines added, 1486 removed
crates/auction-protocol/openrtb 8 files, 1406 lines added, 596 removed
docs/superpowers 1 file, 95 lines added, 0 removed
docs/guide 3 files, 46 lines added, 37 removed
crates/auction/prebid-server 2 files, 29 lines added, 24 removed
crates/auction/aps 2 files, 26 lines added, 20 removed
Cargo.lock 1 file, 9 lines added, 0 removed
crates/testing/iabtl 2 files, 8 lines added, 4 removed
crates/ad-server/iabtl 1 file, 3 lines added, 3 removed
CHANGELOG.md 1 file, 1 line added, 0 removed
crates/auction/prebid 1 file, 1 line added, 1 removed

Closes

Closes #1336

Spec

Spec: auction-protocol

Test plan

CI on this pull request at dfd2e3b passed all 20 checks.

  • cargo test-fastly && cargo test-axum
  • cargo clippy-fastly && cargo clippy-axum
  • cargo fmt --all -- --check
  • JS tests: cd crates/trusted-server-js/lib && npx vitest run
  • JS format: cd crates/trusted-server-js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: the full workflow set of this repository, run on this pull request at dfd2e3b

Checklist

  • Feature PRs: spec linked above, ending in a review log of two or more review rounds
  • Changes follow AGENTS.md conventions
  • No unwrap() in production code (clippy denies unwrap_used in CI)
  • Uses log macros as AGENTS.md asks (not println!)
  • New code has tests
  • No secrets or credentials committed

On top of the 51Degrees client hints middleware (#1386). Issue: #1336.

Kept current. This update only merges the pull request below (#1386), which brings Tech Lab's main at 7aa5c99, the changes made lower in the stack and fiftyone-caching 4.5.13 (#1372).

What this adds

What changes.

OpenRTB is a protocol module and core's auction names no protocol on the way to a demand source. The request builder, the response reader and the regulations object leave crates/trusted-server-core/src/auction/openrtb.rs and openrtb.rs for crates/auction-protocol/openrtb, core's demand interface speaks its own neutral types, and the identifiers a request carries are the identity module's own type in ec/eids.rs.

How it works.

  • Core's demand interface is neutral. A compiled demand source builds an outbound request (body, headers, the slots it covers and what it captured) from the routed facts and parses the response, and the routed provider sends what the source built. The dimension admission rules stay in core as neutral rules any reader applies.
  • OpenRTB is a driver. OpenRtbDriver in the protocol crate implements core's interface around the OpenRtbDemand hook the demand crates implement, with the request builder, the regulations object, the finalization and the response reader that core held. APS and Prebid Server implement the hook and wrap themselves in the driver, and the mock ad server reads only core's admission rules.
  • Identifiers are the identity module's. Eid and Uid live in ec/eids.rs, because the cookie, the header, the body field and the identify API carry them with no auction involved, and the protocol crate formats them to the wire.

Why

The seam made each demand source a module and left them all speaking the one protocol core knows. A standard is a vendor as much as a product is, and the auction protocol is the largest standard core still carries.

What breaks

A demand crate implemented against core's previous OpenRTB hook implements OpenRtbDemand from the protocol crate and wraps itself in the driver. A deployment's settings do not change.

The commits

  1. The identifiers a request carries are the identity module's own type.
  2. OpenRTB is a protocol module, and core's demand interface names no protocol.
  3. The guide, the changelog and a design page describe the auction protocol module.
  4. A merge of the series below, after which the consent records' reading moves with the builder into the protocol crate and its additional consent switch goes, the Prebid cookie series' identifiers are the identity module's type, the seam probe's demand source implements the protocol crate's hook and is wrapped in its driver, and the APS and Prebid Server test helpers format the core identifiers to the wire.
  5. The OpenRTB crate's identifier formatter and tests satisfy clippy.
  6. A merge of the 51Degrees client hints middleware.
  7. The auction protocol design states who applies admission and what the series breaks, and takes its round 2 corrections.
  8. The design page's header names the pull request that carries it.
  9. Merges of the series below, which carry the fixes made lower in the stack, the page origin change and Tech Lab main at 7aa5c99.

What is not in this pull request

The browser-facing response. auction/formats.rs still writes the OpenRTB response the endpoints return, so core still depends on the generated types crate. Moving it needs an interface the endpoint calls and a decision for the maintainers: which protocol writes the response when no demand source is selected, where a disabled auction answers an empty OpenRTB body today, and when the selected sources' protocols differ. The design page records the question.

`Eid` and `Uid` move from core's OpenRTB module to `ec::eids`, beside the
helpers that resolve them from the identity graph and carry them in the
`x-ts-eids` header. The identity cookie, that header, the identify API and
the auction request body all carry this shape, so it is the identity
module's, and an auction protocol formats it into its own request from
here. The OpenRTB user extension refers to the moved type and every import
follows it. The serialization tests move with the types.
Core's demand seam is neutral. A compiled demand source builds its own
request from the routed input, the transport facts and the signing input
core settles, answering the body, the headers, the ids of the slots it
asks for and any state it keeps for the answer, or nothing when it has
nothing to ask for, and reads its own answer into core's bids. Core sends
what the source built and reads the answer against those slots. The
dimension admission rules every reader applies are `auction::admission`,
the notification policy and the ignored bidder parameter count are the
provider's, and the routed auction and its transport facts are public.

Everything OpenRTB moves to `crates/auction-protocol/openrtb`: the wire
types with their extension objects, the request builder, the response
reader, the identifier formatting, and `OpenRtbDemand`, the hook trait a
demand implementation that speaks OpenRTB fills in, run through core's
seam by `OpenRtbDriver`. The plain implementation wraps its source in the
driver, as `auction.prebid-server` and `auction.aps` now do, and
`ad-server.mock` reads bids by core's admission rules. Core's own
`openrtb` module, `auction/openrtb.rs` and its tests are gone, and core's
test stand-ins speak a plain JSON of their own. The browser-facing response
in `auction/formats.rs` still uses the generated types, so core's manifest
keeps that one dependency for now. A deployment's settings do not change.
…col module

The design page says what core keeps, what the protocol crate holds, what
is not in this change and why, and which tests cover it. The guide's
module table and demand paragraph follow the move, and the changelog
carries the breaking change for crates outside core.
The consent series' reading of the neutral consent records moves with the
OpenRTB builder into the protocol crate, and its additional consent switch
goes from the moved field policy. The Prebid cookie series' identifiers are
the identity module's type. The seam probe's demand source implements the
protocol crate's hook and is wrapped in its driver, as the vendors are, and
the APS and Prebid Server test helpers format the core identifiers to the
wire.
The formatter's inner struct names every field, and two header reads pass
the method itself.
… series breaks

Review round 1 found that the design named an ad server module that does
not exist, said the Prebid EID cookie parser and the consent decoders were
still to move when the two series below had moved them, and said a reader
in any crate admits a bid by the rules core applies when core only offers
the rules. The design now says what the code does on all three, adds the
adapters, consent and privacy, signing, failure, compatibility and the
missing tests, asks the reviewer whether core should enforce admission,
and records the review round.

The auction README and the Prebid guide now name the provider and the
files that exist.
Review round 2 found no blocking issues and three corrections. The
related specs line pointed at a pull request that was closed on 15
October, so it now names the open pull request that holds each of the
three specs and the one that holds the earlier design documents of the
stack. The note on an identifier extension that is not an object now
says the extension is dropped and the identifier is still sent. The
round 1 entry in the review log no longer says all of that round's
advice was applied, because two stale code comments are left for a later
change. The round 2 entry and a revision record row are added.
@jwrosewell
jwrosewell added this pull request to stack #1401 October 15, 2026 17:56
@jwrosewell
jwrosewell removed this pull request from stack #1401 October 15, 2026 20:51
# Conflicts:
#	docs/guide/integration-guide.md
@jwrosewell
jwrosewell removed this pull request from stack #1408 October 18, 2026 20:15
@jwrosewell jwrosewell closed this Oct 18, 2026
@jwrosewell jwrosewell reopened this Oct 18, 2026
@jwrosewell
jwrosewell added this pull request to stack #1418 October 19, 2026 12:18
@jwrosewell
jwrosewell removed this pull request from stack #1418 October 19, 2026 16:30
@jwrosewell jwrosewell closed this Oct 19, 2026
@jwrosewell jwrosewell reopened this Oct 19, 2026
@jwrosewell
jwrosewell added this pull request to stack #1421 October 19, 2026 17:38
@jwrosewell
jwrosewell removed this pull request from stack #1421 October 19, 2026 18:29
@jwrosewell
jwrosewell added this pull request to stack #1422 October 19, 2026 19:20
@jwrosewell jwrosewell changed the title OpenRTB is an auction protocol module, and core sends the request a demand source builds Move OpenRTB into an auction protocol module Oct 19, 2026
@jwrosewell
jwrosewell marked this pull request as ready for review October 19, 2026 20:24
@jwrosewell
jwrosewell removed this pull request from stack #1422 October 28, 2026 11:47
@jwrosewell
jwrosewell added this pull request to stack #1465 October 28, 2026 18:28

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core's auction speaks OpenRTB

1 participant