Skip to content

Add Edge Cookie (EC) sync support for trusted-server integration#98

Draft
ChristianPavilonis wants to merge 1 commit intomainfrom
feature/ec-support
Draft

Add Edge Cookie (EC) sync support for trusted-server integration#98
ChristianPavilonis wants to merge 1 commit intomainfrom
feature/ec-support

Conversation

@ChristianPavilonis
Copy link
Copy Markdown
Contributor

Summary

  • Add three new endpoints (/sync/start, /sync/done, /resolve) that enable mocktioneer to act as a full EC sync partner with trusted-server — supporting pixel sync redirect chains, callback handling, and S2S pull sync resolution
  • Add OpenRTB 2.6 user.eids support and embed EC identity metadata (EdgeCookieInfo) in creative HTML comments, enabling end-to-end demo of the trusted-server EC identity pipeline
  • Add examples/register_partner.sh for one-step partner registration with trusted-server

New Endpoints

Route Method Purpose
/sync/start?ts_domain=... GET Sets mtkid cookie, redirects browser to TS /sync
/sync/done?ts_synced=... GET Callback from TS — returns 1x1 pixel
/resolve?ec_hash=...&ip=... GET Pull sync — returns deterministic mtk-{sha256(ec_hash|ip)[0:12]}

Security

  • Constant-time auth: Token comparison uses subtle::ConstantTimeEq on SHA-256 digests (no length leak)
  • Open redirect protection: ts_domain validated as clean hostname (no /, @, :, ?, #) + optional allowlist via MOCKTIONEER_TS_DOMAINS env var
  • Input validation: ec_hash requires exactly 64 hex characters; log output sanitized against control chars
  • Deterministic IDs: mtkid derived from SHA-256("mtkid:" || host) — no randomness per CLAUDE.md

Testing

  • 97 unit tests + 1 ignored (env-var auth, passes separately with --ignored)
  • 12 APS integration tests, 7 endpoint integration tests
  • cargo fmt, cargo clippy clean

WASM Note

MOCKTIONEER_PULL_TOKEN and MOCKTIONEER_TS_DOMAINS use std::env::var which returns Err on Cloudflare Workers. Auth and domain allowlist are silently disabled on that platform. Documented in code comments.

Implement mocktioneer as a full EC sync partner with three new endpoints:
- GET /sync/start: pixel sync redirect chain (sets mtkid, redirects to TS /sync)
- GET /sync/done: callback endpoint completing the redirect chain
- GET /resolve: S2S pull sync resolution (deterministic UID from ec_hash+IP)

Also adds OpenRTB 2.6 user.eids support and EC identity metadata in creatives,
enabling end-to-end demo of the trusted-server EC identity pipeline.

Security hardening from review:
- Constant-time token comparison via subtle::ConstantTimeEq (SHA-256 digest)
- Hostname validation on ts_domain (rejects path/auth/port injection)
- Domain allowlist via MOCKTIONEER_TS_DOMAINS env var
- Hex-only ec_hash validation
- Log sanitization for user-supplied values
- Deterministic mtkid generation (SHA-256 of host, no randomness)
/// **WASM note:** `std::env::var` returns `Err` on Cloudflare Workers,
/// which means auth is silently disabled on that platform. See
/// `TS_ALLOWED_DOMAINS_ENV` for the same limitation.
#[action]

Check failure

Code scanning / CodeQL

Cleartext logging of sensitive information High

This operation writes
uid
to a log file.

Copilot Autofix

AI 1 day ago

In general, the fix is to avoid writing sensitive or user-derived identifiers to logs in cleartext. Either omit them, or replace them with a sanitized/shortened/non-reversible form that’s sufficient for debugging but reduces privacy/abuse risk.

Here, the simplest, least disruptive fix is to stop logging the full uid value. The log already includes ec_hash (truncated) and ip, which should be enough for tracing. We can remove uid from the log line entirely while leaving all behavior unchanged for the HTTP response and UID computation.

Concretely, in crates/mocktioneer-core/src/routes.rs within handle_resolve, update the log::info! call around lines 796–801. Change the format string from "Pull sync resolve: ec_hash={}..., ip={}, uid={}" to "Pull sync resolve: ec_hash={}..., ip={}" and drop uid from the argument list. No new imports or helper functions are needed, and all other code (including returning uid in the JSON body) remains untouched.

Suggested changeset 1
crates/mocktioneer-core/src/routes.rs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/crates/mocktioneer-core/src/routes.rs b/crates/mocktioneer-core/src/routes.rs
--- a/crates/mocktioneer-core/src/routes.rs
+++ b/crates/mocktioneer-core/src/routes.rs
@@ -794,10 +794,9 @@
     let uid = format!("mtk-{}", &hex[..12]);
 
     log::info!(
-        "Pull sync resolve: ec_hash={}..., ip={}, uid={}",
+        "Pull sync resolve: ec_hash={}..., ip={}",
         &params.ec_hash[..8],
         params.ip,
-        uid
     );
 
     let body = Body::json(&ResolveResponse { uid: Some(uid) }).map_err(|e| {
EOF
@@ -794,10 +794,9 @@
let uid = format!("mtk-{}", &hex[..12]);

log::info!(
"Pull sync resolve: ec_hash={}..., ip={}, uid={}",
"Pull sync resolve: ec_hash={}..., ip={}",
&params.ec_hash[..8],
params.ip,
uid
);

let body = Body::json(&ResolveResponse { uid: Some(uid) }).map_err(|e| {
Copilot is powered by AI and may make mistakes. Always verify output.
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.

1 participant