ℹ️ Trusted Server is an open-source, cloud based orchestration framework and runtime for publishers. It moves code execution and operations that traditionally occurs in browsers (via 3rd party JS) to secure, zero-cold-start WASM binaries running in WASI supported environments. It importantly gives publishers benefits such as: dramatically increasing control over how and who they share their data with (while maintaining user-privacy compliance), increasing revenue from inventory inside cookie restricted or non-JS environments, ability to serve all assets under 1st party context, and provides secure cryptographic functions to ensure trust across the programmatic ad ecosystem.
Trusted Server is the new execution layer for the open-web, returning control of 1st party data, security, and overall user-experience back to publishers.
At this time, Trusted Server is designed to work with Fastly Compute. Follow these steps to configure Fastly Compute and deploy it.
-
Create account at Fastly if you don’t have one - manage.fastly.com
-
Log in to the Fastly control panel.
- Go to Account > API tokens > Personal tokens.
- Click Create token
- Name the Token
- Choose User Token
- Choose Global API Access
- Choose what makes sense for your Org in terms of Service Access
- Copy key to a secure location because you will not be able to see it again
-
Create new Compute Service
- Click Compute and Create Service
- Click “Create Empty Service” (below main options)
- Add your domain of the website you’ll be testing or using and click update
- Click on “Origins” section and add your ad-server / ssp partner information as hostnames (note after you save this information you can select port numbers and TLS on/off)
- IMPORTANT: when you enter the FQDN or IP ADDR information and click Add you need to enter a “Name” in the first field that will be referenced in your code so something like “my_ad_partner_1”
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install fastly/tap/fastly
fastly version
fastly profile create
brew install asdf
asdf plugin add rust
asdf install rust $(grep '^rust ' .tool-versions | awk '{print $2}')
asdf reshim
brew install asdf
asdf plugin add nodejs
asdf install nodejs $(grep '^nodejs ' .tool-versions | awk '{print $2}')
asdf reshim
Edit ~/.bash_profile to add path for asdf shims:
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
Edit ~/.zshrc to add path for asdf shims:
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
See https://asdf-vm.com/guide/getting-started.html#_2-configure-asdf
git clone [email protected]:IABTechLab/trusted-server.git
ℹ️ Note that you’ll have to edit the following files for your setup:
- fastly.toml (service ID, author, description)
- trusted-server.toml (KV store ID names - optional)
cargo build
fastly compute publish
cargo install viceroy
- Review configuration for local_server
- Review env variables overrides in .env.dev
export $(grep -v '^#' .env.dev | xargs -0)
fastly -i compute serve
cargo test
viceroy
will not display line number of the failed test. Rerun it with cargo test_details
.
cargo fmt
: Ensure uniform code formattingcargo clippy
: Ensure idiomatic codecargo check
: Ensure compilation succeeds on Linux, MacOS, Windows and WebAssemblycargo bench
: Run all benchmarks
-
/first-party/ad
(GET): returns HTML for a single slot (slot
,w
,h
query params). The server inspects returned creative HTML and rewrites: -
All absolute images and iframes to
/first-party/proxy?tsurl=<base-url>&<original-query-params>&tstoken=<sig>
(1×1 pixels are detected server‑side heuristically for logging). Thetstoken
is derived from encrypting the full target URL and hashing it. -
/third-party/ad
(POST): accepts tsjs ad units and proxies to Prebid Server. -
/first-party/proxy
(GET): unified proxy for resources referenced by creatives.- Query params:
tsurl
: Target URL without query (base URL) — required- Any original target query parameters are included at top level as-is (order preserved)
tstoken
: Base64 URL‑safe (no padding) SHA‑256 digest of the encrypted full target URL — required
- Behavior:
- Reconstructs the full target URL from
tsurl
+ provided parameters in order, computeststoken
by encrypting with XChaCha20‑Poly1305 (deterministic nonce) and hashing the bytes with SHA‑256, and validates it. - HTML responses: proxied and rewritten (images/iframes/pixels) via creative rewriter
- Image responses: proxied; if content‑type is missing, sets
image/*
; logs likely 1×1 pixels via size/URL heuristics - Follows HTTP redirects (301/302/303/307/308) up to four hops, reapplying the forwarded synthetic ID and switching to
GET
after a 303; logs when the redirect limit is reached. - When forwarding to the target URL, no
tstoken
is included (it is not part of the target URL).
- Reconstructs the full target URL from
- Query params:
-
Synthetic ID propagation: reads the trusted ID from the incoming cookie/header and appends
synthetic_id=<value>
to the target URL sent to the third-party origin while preserving existing query strings.- Redirect following re-applies the identifier on each hop so downstream origins see a consistent ID even when assets bounce through intermediate trackers.
-
/first-party/click
(GET): first‑party click redirect handler for anchors and clickable areas.- Query params: same as
/first-party/proxy
(usestsurl
, original params,tstoken
). - Behavior:
- Validates
tstoken
against the reconstructed full URL (same enc+SHA256 scheme). - Emits a
302 Found
withLocation: <reconstructed_target_url>
— content is not parsed or proxied. - If a synthetic identifier is available, appends
synthetic_id=<value>
to the redirect target. - Logs click metadata (tsurl, whether params are present, target URL, referer, user agent, and Trusted Server ID header) for observability.
- Validates
- Query params: same as
-
Publisher origin proxy (
handle_publisher_request
): retrieves/generates the synthetic ID, stamps the response withX-Synthetic-*
headers, and sets thesynthetic_id
cookie (Secure, SameSite=Lax) when absent so subsequent creative and click proxies can propagate the identifier.
Notes
- Rewriting uses
lol_html
. Only absolute and protocol‑relative URLs are rewritten; relative URLs are left unchanged. - For the proxy endpoint, the base URL is carried in
tsurl
, the original query parameters are preserved individually, andtstoken
authenticates the reconstructed full URL. - Synthetic identifiers are generated by
crates/common/src/synthetic.rs
and are surfaced in three places: publisher responses (headers + cookie), creative proxy target URLs (synthetic_id
query param), and click redirect URLs. This ensures downstream partners can correlate impressions and clicks without direct third-party cookies.