Skip to content

feat: make integration proxy paths configurable per customer#759

Open
vasujain00 wants to merge 2 commits into
IABTechLab:mainfrom
vasujain00:feat/741-configurable-proxy-paths
Open

feat: make integration proxy paths configurable per customer#759
vasujain00 wants to merge 2 commits into
IABTechLab:mainfrom
vasujain00:feat/741-configurable-proxy-paths

Conversation

@vasujain00

@vasujain00 vasujain00 commented Jun 8, 2026

Copy link
Copy Markdown

Fixes #741

Summary

  • Adds a proxy_prefix() method to the IntegrationProxy trait allowing integrations to use customer-configured paths instead of hardcoded /integrations/{name} paths
  • Implements configurable proxy_path for the Didomi integration as the first adopter
  • Backwards-compatible: default behavior unchanged when proxy_path is not set

Changes

File Change
crates/trusted-server-core/src/integrations/registry.rs Added proxy_prefix() method to IntegrationProxy trait; updated get(), post(), put(), delete(), patch() helpers to use it
crates/trusted-server-core/src/integrations/didomi.rs Added proxy_path config field; overrides proxy_prefix() when set; updated routes and path stripping

Closes

Closes #741

Test plan

  • cargo test --workspace
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • JS tests: cd crates/js/lib && npx vitest run
  • JS format: cd crates/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: New test registers_custom_proxy_path verifies custom path routes correctly and default path no longer matches

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code -- use expect("should ...")
  • Uses tracing macros (not println!)
  • New code has tests
  • No secrets or credentials committed

Fixes IABTechLab#741

Adds a `proxy_prefix()` method to the `IntegrationProxy` trait with a
default implementation that preserves existing behavior
(`/integrations/{name}`). Integrations can override this to use a
customer-configured path that is harder for ad blockers to target.

Implements the feature for the Didomi integration as the first example:

  [integrations.didomi]
  proxy_path = "my-custom-consent-path"

When `proxy_path` is set, routes are registered under
`/<proxy_path>/*` instead of the default
`/integrations/didomi/consent/*`. The same pattern can be adopted by
other integrations.

This is a backwards-compatible change -- if `proxy_path` is not set,
the default prefix is used and existing deployments are unaffected.
@vasujain00 vasujain00 marked this pull request as draft June 8, 2026 19:21
@vasujain00 vasujain00 marked this pull request as ready for review June 8, 2026 19:21

@ChristianPavilonis ChristianPavilonis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution — making these proxy paths configurable is a good direction, and I appreciate that the default route behavior is covered. I found two implementation gaps that look worth addressing before relying on custom Didomi paths.

I left the main items inline. One additional follow-up: once the behavior is wired through, please update docs/guide/integrations/didomi.md to document proxy_path, its default, accepted format, and the custom endpoint examples.

/// Custom proxy path prefix to avoid ad-blocker detection.
/// Defaults to "integrations/didomi/consent" if not set.
#[serde(default)]
pub proxy_path: Option<String>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom path also needs to reach the client-side URL builder

Thanks for adding the config knob here. One important gap: this field only changes the Rust route registration, but the Didomi browser module still builds sdkPath from the hard-coded /integrations/didomi/consent/ path in crates/js/lib/src/integrations/didomi/index.ts. With proxy_path set, this PR registers only the custom route and the new test asserts the old route no longer matches, so pages would still request the old prefix and miss the proxy.

Could we pass the resolved prefix to the JS runtime (for example via a small head-injected window.__tsjs_didomi.proxyPath config) and have the TypeScript fall back to the current default when it is absent?


fn proxy_prefix(&self) -> String {
match &self.config.proxy_path {
Some(custom) => format!("/{}", custom.trim_start_matches('/')),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please validate or canonicalize proxy_path before using it for routes

This normalizes leading slashes, but malformed values can still register surprising routes. For example, proxy_path = "my-custom-consent/" becomes /my-custom-consent//*, so the intended /my-custom-consent/loader.js request would not match. Empty/root paths, //, query/fragment characters, and matchit route metacharacters would also be risky here.

I’d suggest validating/canonicalizing once at config load or construction time: allow an optional leading slash, store/return exactly /{path}, and reject empty/root/trailing-slash/query/fragment/wildcard/route-metacharacter values. A few tests around leading slash normalization and invalid values would make this much safer for a customer-facing config field.

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.

Make integration proxy paths configurable per customer

3 participants