ℹ️ Trusted Server is an open-source runtime and edge-orchestration layer for modern publishers - executing 3rd-party scripts and your entire ad-stack server-side, all under 1st-party control. Our goal is to move ad-related code execution and control from web browsers to publisher controlled, "trusted" edge-cloud infrastructure.
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
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 git@github.com: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)
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.