Skip to content

Commit 5f03559

Browse files
committed
Updated documentation
1 parent 5b06482 commit 5f03559

30 files changed

+1181
-513
lines changed

.env.example

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Trusted Server Environment Variables
2+
# Copy this file to .env.dev, .env.staging, or .env.production and fill in values
3+
# See docs/guide/configuration.md for details
4+
5+
# =============================================================================
6+
# Publisher Settings
7+
# =============================================================================
8+
TRUSTED_SERVER__PUBLISHER__DOMAIN=publisher.com
9+
TRUSTED_SERVER__PUBLISHER__COOKIE_DOMAIN=.publisher.com
10+
TRUSTED_SERVER__PUBLISHER__ORIGIN_URL=https://origin.publisher.com
11+
TRUSTED_SERVER__PUBLISHER__PROXY_SECRET=<your-proxy-secret>
12+
13+
# =============================================================================
14+
# Synthetic ID Settings
15+
# =============================================================================
16+
TRUSTED_SERVER__SYNTHETIC__COUNTER_STORE=counter_store
17+
TRUSTED_SERVER__SYNTHETIC__OPID_STORE=opid_store
18+
TRUSTED_SERVER__SYNTHETIC__SECRET_KEY=<your-synthetic-secret>
19+
# Template variables: client_ip, user_agent, first_party_id, auth_user_id, publisher_domain, accept_language
20+
TRUSTED_SERVER__SYNTHETIC__TEMPLATE={{ client_ip }}:{{ user_agent }}:{{ first_party_id }}
21+
22+
# =============================================================================
23+
# Request Signing (optional)
24+
# =============================================================================
25+
TRUSTED_SERVER__REQUEST_SIGNING__ENABLED=false
26+
# TRUSTED_SERVER__REQUEST_SIGNING__CONFIG_STORE_ID=<fastly-config-store-id>
27+
# TRUSTED_SERVER__REQUEST_SIGNING__SECRET_STORE_ID=<fastly-secret-store-id>
28+
29+
# =============================================================================
30+
# Response Headers (optional)
31+
# =============================================================================
32+
# TRUSTED_SERVER__RESPONSE_HEADERS__X_CUSTOM_HEADER=custom-value
33+
34+
# =============================================================================
35+
# Integrations
36+
# =============================================================================
37+
38+
# Prebid
39+
TRUSTED_SERVER__INTEGRATIONS__PREBID__ENABLED=false
40+
# TRUSTED_SERVER__INTEGRATIONS__PREBID__SERVER_URL=https://prebid-server.com/openrtb2/auction
41+
# TRUSTED_SERVER__INTEGRATIONS__PREBID__TIMEOUT_MS=1000
42+
# TRUSTED_SERVER__INTEGRATIONS__PREBID__BIDDERS=kargo,rubicon,appnexus
43+
# TRUSTED_SERVER__INTEGRATIONS__PREBID__AUTO_CONFIGURE=false
44+
# TRUSTED_SERVER__INTEGRATIONS__PREBID__DEBUG=false
45+
46+
# Next.js
47+
TRUSTED_SERVER__INTEGRATIONS__NEXTJS__ENABLED=false
48+
# TRUSTED_SERVER__INTEGRATIONS__NEXTJS__REWRITE_ATTRIBUTES=href,link,url
49+
50+
# Didomi
51+
TRUSTED_SERVER__INTEGRATIONS__DIDOMI__ENABLED=false
52+
# TRUSTED_SERVER__INTEGRATIONS__DIDOMI__SDK_ORIGIN=https://sdk.privacy-center.org
53+
# TRUSTED_SERVER__INTEGRATIONS__DIDOMI__API_ORIGIN=https://api.privacy-center.org
54+
55+
# Permutive
56+
TRUSTED_SERVER__INTEGRATIONS__PERMUTIVE__ENABLED=false
57+
# TRUSTED_SERVER__INTEGRATIONS__PERMUTIVE__ORGANIZATION_ID=
58+
# TRUSTED_SERVER__INTEGRATIONS__PERMUTIVE__WORKSPACE_ID=
59+
# TRUSTED_SERVER__INTEGRATIONS__PERMUTIVE__PROJECT_ID=
60+
61+
# Lockr
62+
TRUSTED_SERVER__INTEGRATIONS__LOCKR__ENABLED=false
63+
# TRUSTED_SERVER__INTEGRATIONS__LOCKR__APP_ID=
64+
# TRUSTED_SERVER__INTEGRATIONS__LOCKR__CACHE_TTL_SECONDS=3600
65+
66+
# =============================================================================
67+
# Rewrite Configuration (optional)
68+
# =============================================================================
69+
# Comma-separated list of domains to exclude from first-party rewriting
70+
# TRUSTED_SERVER__REWRITE__EXCLUDE_DOMAINS=*.edgecompute.app

.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
fastly 13.1.0
1+
fastly 13.3.0
22
rust 1.91.1
3-
nodejs 24.10.0
3+
nodejs 24.12.0

README.md

Lines changed: 22 additions & 240 deletions
Original file line numberDiff line numberDiff line change
@@ -1,250 +1,32 @@
11
# Trusted Server
22

3-
:information_source: 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](https://webassembly.org) binaries running in [WASI](https://github.com/WebAssembly/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.
3+
Trusted Server is an open-source, cloud-based orchestration framework and runtime for publishers. It moves code execution and operations that traditionally occur in browsers (via 3rd party JS) to secure, zero-cold-start [WASM](https://webassembly.org) binaries running in [WASI](https://github.com/WebAssembly/WASI) supported environments.
44

5-
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.
5+
**Key benefits:**
66

7-
At this time, Trusted Server is designed to work with Fastly Compute. Follow these steps to configure Fastly Compute and deploy it.
7+
- Dramatically increases control over data sharing while maintaining privacy compliance
8+
- Increases revenue from inventory in cookie-restricted or non-JS environments
9+
- Serves all assets under first-party context
10+
- Provides secure cryptographic functions for trust across the programmatic ad ecosystem
811

9-
## Getting Started: Edge-Cloud Support on Fastly
12+
At this time, Trusted Server is designed to work with [Fastly Compute](https://www.fastly.com/products/compute).
1013

11-
- Create account at Fastly if you don’t have one - manage.fastly.com
12-
- Log in to the Fastly control panel.
13-
- Go to Account > API tokens > Personal tokens.
14-
- Click Create token
15-
- Name the Token
16-
- Choose User Token
17-
- Choose Global API Access
18-
- Choose what makes sense for your Org in terms of Service Access
19-
- Copy key to a secure location because you will not be able to see it again
14+
## Documentation
2015

21-
- Create new Compute Service
22-
- Click Compute and Create Service
23-
- Click “Create Empty Service” (below main options)
24-
- Add your domain of the website you’ll be testing or using and click update
25-
- Click on “Origins” section and add your ad-server / SSP integration information as hostnames (note after you save this information you can select port numbers and TLS on/off)
26-
- 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_integration_1”
27-
-
16+
📚 **[View Full Documentation](docs/guide/getting-started.md)**
2817

29-
:warning: With a dev account, Fastly gives you a test domain by default, but you’re also able to create a CNAME to your own domain when you’re ready, along with 2 free TLS certs (non-wildcard). Note that Fastly Compute ONLY accepts client traffic via TLS, though origins and backends can be non-TLS.
18+
| Guide | Description |
19+
| ---------------------------------------------------- | -------------------------------------------- |
20+
| [Getting Started](docs/guide/getting-started.md) | Installation, setup, and first deployment |
21+
| [Fastly Setup](docs/guide/fastly.md) | Fastly account, Compute service, and origins |
22+
| [Configuration](docs/guide/configuration.md) | Configuration options and settings |
23+
| [Synthetic IDs](docs/guide/synthetic-ids.md) | Privacy-preserving identifier generation |
24+
| [Ad Serving](docs/guide/ad-serving.md) | Ad server integration and setup |
25+
| [First-Party Proxy](docs/guide/first-party-proxy.md) | Proxy configuration for first-party context |
26+
| [Request Signing](docs/guide/request-signing.md) | Cryptographic request signing with Ed25519 |
27+
| [API Reference](docs/guide/api-reference.md) | Complete API endpoint documentation |
28+
| [Integration Guide](docs/guide/integration-guide.md) | Building custom integrations |
3029

31-
## CLI and OS Tools Installation
30+
## License
3231

33-
### Brew
34-
35-
:warning: Follow the prompts before and afterwards (to configure system path, etc)
36-
37-
#### Install Brew
38-
39-
```sh
40-
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
41-
```
42-
43-
### Fastly CLI
44-
45-
#### Install Fastly CLI
46-
47-
```sh
48-
brew install fastly/tap/fastly
49-
```
50-
51-
#### Verify Installation and Version
52-
53-
```sh
54-
fastly version
55-
```
56-
57-
:warning: fastly cli version should be at least v12.1.0
58-
59-
#### Create profile and follow interactive prompt for pasting your API Token created earlier:
60-
61-
```sh
62-
fastly profile create
63-
```
64-
65-
### Rust
66-
67-
#### Install Rust with asdf (our preference)
68-
69-
```sh
70-
brew install asdf
71-
asdf plugin add rust
72-
asdf install rust $(grep '^rust ' .tool-versions | awk '{print $2}')
73-
asdf reshim
74-
```
75-
76-
### NodeJS
77-
78-
#### Install NodeJS with asdf
79-
80-
```sh
81-
brew install asdf
82-
asdf plugin add nodejs
83-
asdf install nodejs $(grep '^nodejs ' .tool-versions | awk '{print $2}')
84-
asdf reshim
85-
```
86-
87-
#### Fix path for Bash
88-
89-
Edit ~/.bash_profile to add path for asdf shims:
90-
91-
```sh
92-
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
93-
```
94-
95-
#### Fix path for ZSH
96-
97-
Edit ~/.zshrc to add path for asdf shims:
98-
99-
```sh
100-
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
101-
```
102-
103-
#### Other shells
104-
105-
See https://asdf-vm.com/guide/getting-started.html#_2-configure-asdf
106-
107-
### Clone Trusted Server and Configure Build
108-
109-
#### Clone Project (assumes you have 'git' installed on your system)
110-
111-
```sh
112-
git clone [email protected]:IABTechLab/trusted-server.git
113-
```
114-
115-
### Configure
116-
117-
#### Edit configuration files
118-
119-
:information_source: Note that you'll have to edit the following files for your setup:
120-
121-
- fastly.toml (service ID, author, description, Config/Secret Store IDs for request signing)
122-
- trusted-server.toml (KV store ID names - optional, request signing configuration)
123-
124-
### Build
125-
126-
```sh
127-
cargo build
128-
```
129-
130-
### Deploy to Fastly
131-
132-
```sh
133-
fastly compute publish
134-
```
135-
136-
## Devleopment
137-
138-
#### Install viceroy for running tests
139-
140-
```sh
141-
cargo install viceroy
142-
```
143-
144-
#### Run Fastly server locally
145-
146-
- Review configuration for [local_server](fastly.toml#L16)
147-
- Review env variables overrides in [.env.dev](.env.dev)
148-
149-
```sh
150-
export $(grep -v '^#' .env.dev | xargs -0)
151-
```
152-
153-
```sh
154-
fastly -i compute serve
155-
```
156-
157-
#### Tests
158-
159-
```sh
160-
cargo test
161-
```
162-
163-
:warning: if test fails `viceroy` will not display line number of the failed test. Rerun it with `cargo test_details`.
164-
165-
#### Additional Rust Commands
166-
167-
- `cargo fmt`: Ensure uniform code formatting
168-
- `cargo clippy`: Ensure idiomatic code
169-
- `cargo check`: Ensure compilation succeeds on Linux, MacOS, Windows and WebAssembly
170-
- `cargo bench`: Run all benchmarks
171-
172-
## Request Signing
173-
174-
Trusted Server supports cryptographic signing of OpenRTB requests and other API calls using Ed25519 keys.
175-
176-
### Configuration
177-
178-
Request signing requires Fastly Config Store and Secret Store for key management:
179-
180-
1. **Create Fastly Stores** (via Fastly Control Panel or CLI):
181-
- Config Store: `jwks_store` - stores public keys (JWKs) and key metadata
182-
- Secret Store: `signing_keys` - stores private signing keys
183-
184-
2. **Configure in trusted-server.toml**:
185-
186-
```toml
187-
[request_signing]
188-
enabled = true # Set to true to enable request signing
189-
config_store_id = "<your-fastly-config-store-id>" # Config Store ID from Fastly
190-
secret_store_id = "<your-fastly-secret-store-id>" # Secret Store ID from Fastly
191-
```
192-
193-
### Key Management Endpoints
194-
195-
Once configured, the following endpoints are available:
196-
197-
- **`GET /.well-known/ts.jwks.json`**: Returns active public keys in JWKS format for signature verification
198-
- **`POST /verify-signature`**: Verifies a signature against a payload and key ID (useful for testing)
199-
- Request body: `{"payload": "...", "signature": "...", "kid": "..."}`
200-
- Response: `{"verified": true/false, "kid": "...", "message": "..."}`
201-
202-
#### Admin Endpoints (Key Rotation)
203-
204-
- **`POST /admin/keys/rotate`**: Generates and activates a new signing key
205-
- Optional body: `{"kid": "custom-key-id"}` (auto-generates date-based ID if omitted)
206-
- Response includes new key ID, previous key ID, and active keys list
207-
- **`POST /admin/keys/deactivate`**: Deactivates or deletes a key
208-
- Request body: `{"kid": "key-to-deactivate", "delete": false}`
209-
- Set `delete: true` to permanently remove the key (also deactivates it)
210-
211-
:warning: Key rotation keeps both the new and previous key active to allow for graceful transitions. Deactivate old keys manually when no longer needed.
212-
213-
## First-Party Endpoints
214-
215-
- `/first-party/ad` (GET): returns HTML for a single slot (`slot`, `w`, `h` query params). The server inspects returned creative HTML and rewrites:
216-
- 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). The `tstoken` is derived from encrypting the full target URL and hashing it.
217-
- `/third-party/ad` (POST): accepts tsjs ad units and proxies to Prebid Server.
218-
- `/first-party/proxy` (GET): unified proxy for resources referenced by creatives.
219-
- Query params:
220-
- `tsurl`: Target URL without query (base URL) — required
221-
- Any original target query parameters are included at top level as-is (order preserved)
222-
- `tstoken`: Base64 URL‑safe (no padding) SHA‑256 digest of the encrypted full target URL — required
223-
- Behavior:
224-
- Reconstructs the full target URL from `tsurl` + provided parameters in order, computes `tstoken` by encrypting with XChaCha20‑Poly1305 (deterministic nonce) and hashing the bytes with SHA‑256, and validates it.
225-
- HTML responses: proxied and rewritten (images/iframes/pixels) via creative rewriter
226-
- Image responses: proxied; if content‑type is missing, sets `image/*`; logs likely 1×1 pixels via size/URL heuristics
227-
- 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.
228-
- When forwarding to the target URL, no `tstoken` is included (it is not part of the target URL).
229-
- 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.
230-
- Redirect following re-applies the identifier on each hop so downstream origins see a consistent ID even when assets bounce through intermediate trackers.
231-
232-
- `/first-party/click` (GET): first‑party click redirect handler for anchors and clickable areas.
233-
- Query params: same as `/first-party/proxy` (uses `tsurl`, original params, `tstoken`).
234-
- Behavior:
235-
- Validates `tstoken` against the reconstructed full URL (same enc+SHA256 scheme).
236-
- Emits a `302 Found` with `Location: <reconstructed_target_url>` — content is not parsed or proxied.
237-
- If a synthetic identifier is available, appends `synthetic_id=<value>` to the redirect target.
238-
- Logs click metadata (tsurl, whether params are present, target URL, referer, user agent, and Trusted Server ID header) for observability.
239-
240-
- Publisher origin proxy (`handle_publisher_request`): retrieves/generates the synthetic ID, stamps the response with `X-Synthetic-*` headers, and sets the `synthetic_id` cookie (Secure, SameSite=Lax) when absent so subsequent creative and click proxies can propagate the identifier.
241-
242-
Notes
243-
244-
- Rewriting uses `lol_html`. Only absolute and protocol‑relative URLs are rewritten; relative URLs are left unchanged.
245-
- For the proxy endpoint, the base URL is carried in `tsurl`, the original query parameters are preserved individually, and `tstoken` authenticates the reconstructed full URL.
246-
- 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 integrations can correlate impressions and clicks without direct third-party cookies.
247-
248-
## Integration Modules
249-
250-
- See [`docs/integration_guide.md`](docs/integration_guide.md) for the full integration module guide, covering configuration, proxy routing, HTML shim hooks, and the `testlight` example implementation.
32+
Apache License 2.0

docs/.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vitepress/cache
2+
.vitepress/dist
3+
node_modules

docs/.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"trailingComma": "es5",
6+
"proseWrap": "preserve"
7+
}

0 commit comments

Comments
 (0)