Skip to content

Datadome: Add configurable bypass header and remove tag injection for bypasses - #992

Open
ChristianPavilonis wants to merge 9 commits into
mainfrom
log/datadome
Open

Datadome: Add configurable bypass header and remove tag injection for bypasses#992
ChristianPavilonis wants to merge 9 commits into
mainfrom
log/datadome

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Align the two DataDome protection layers: when Fastly's authoritative client IP matches an IP-based exclusion, Trusted Server skips the Protection API and omits only its automatically injected DataDome browser tag from processed HTML.
  • Add a temporary, secret-backed staging bypass for access-controlled browser tests. A matching x-ts-datadome-bypass header skips server-side protection, suppresses the automatic tag, and is removed before the request reaches DataDome or the publisher origin.
  • Add structured, privacy-safe protection decision logs and cache safeguards for tag-suppressed HTML.

The issue was that an IP allowlist skipped server-side DataDome validation but still allowed the automatically injected browser tag to run. The new flow keeps those layers consistent while providing a controlled way to test protected staging sites without logging client IPs or exposing bypass credentials.

Changes

File Change
crates/trusted-server-core/benches/html_processor_bench.rs Updates the HTML processor benchmark fixture for the new suppression setting.
crates/trusted-server-core/src/config.rs Validates the staging bypass configuration during deployment validation.
crates/trusted-server-core/src/html_processor.rs Carries the request-scoped suppression decision into HTML integration processing and tests tag omission.
crates/trusted-server-core/src/integrations/datadome.rs Adds staging bypass configuration, the private suppression marker, startup validation, and the injector guard.
crates/trusted-server-core/src/integrations/datadome/protection.rs Handles the secret-backed bypass, marks eligible IP exclusions, logs protection outcomes without client IPs, and adds regression coverage.
crates/trusted-server-core/src/integrations/registry.rs Allows request filters to attach private typed annotations while preserving normal header effects.
crates/trusted-server-core/src/platform/test_support.rs Adds test service builders with configurable client IP and supporting stores.
crates/trusted-server-core/src/publisher.rs Propagates suppression through buffered and streaming HTML paths, removes conditional validators, and makes suppressed HTML private and non-shared-cacheable.
crates/trusted-server-core/src/response_privacy.rs Shares the CDN cache-header list with the new suppression privacy policy and covers cdn-cache-control.
docs/guide/integrations/datadome.md Documents the staging bypass, IP-only tag suppression behavior, cache privacy, and diagnostic logging.
docs/superpowers/plans/2026-08-03-datadome-ip-excluded-client-tag.md Records the implementation plan and behavioral acceptance criteria.
docs/superpowers/specs/2026-08-03-datadome-ip-excluded-client-tag-design.md Records the design, boundaries, and privacy requirements for the feature.

Scope

This PR is intentionally limited to the existing DataDome request-filter, HTML-processing, publisher, and privacy paths, plus their tests and operator documentation. It does not change JavaScript bundles, publisher-originated DataDome markup, direct DataDome integration routes, or unrelated adapters; the staging bypass is included because it uses the same request-scoped protection decision and is needed for controlled staging verification.

Closes

Closes #994

Test plan

  • cargo test-fastly
  • cargo test-axum
  • cargo test-cloudflare
  • cargo clippy-fastly
  • cargo clippy-axum
  • cargo clippy-cloudflare
  • cargo fmt --all -- --check
  • Docs Prettier check
  • git diff --check
  • Live production/browser verification (deferred until deployment)

Checklist

  • Changes follow CLAUDE.md conventions
  • No secrets or credentials committed
  • New behavior has tests

ChristianPavilonis added a commit that referenced this pull request Aug 3, 2026
This reverts commit 5226d8a, reversing
changes made to 0dc9b19.
ChristianPavilonis added a commit that referenced this pull request Aug 3, 2026
@ChristianPavilonis ChristianPavilonis changed the title Add DataDome protection decision logs Add DataDome decision logging and IP-exclusion tag suppression Aug 3, 2026
ChristianPavilonis added a commit that referenced this pull request Aug 3, 2026
@ChristianPavilonis ChristianPavilonis changed the title Add DataDome decision logging and IP-exclusion tag suppression Align DataDome tag injection with exclusions and add a staging bypass Aug 6, 2026
@ChristianPavilonis ChristianPavilonis changed the title Align DataDome tag injection with exclusions and add a staging bypass Datadome: Add configurable bypass header and remove tag injection for bypasses Aug 6, 2026
@ChristianPavilonis
ChristianPavilonis marked this pull request as ready for review August 6, 2026 18:18

@aram356 aram356 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.

Summary

Aligns the two DataDome protection layers (IP-based exclusions now skip the Protection API and omit only Trusted Server's auto-injected browser tag) and adds a secret-backed staging bypass header. The design is sound: single scope evaluation, typed request extension instead of a synthetic header, constant-time credential comparison, cache privacy on tag-suppressed HTML, and no client IPs in logs. One CI gate is failing and there are a handful of non-blocking concerns, detailed inline.

Blocking

🔧 wrench

  • format-docs CI failure: docs/superpowers/plans/2026-08-03-datadome-ip-excluded-client-tag.md fails the pinned Prettier check (stray blank lines after indented code blocks inside list items, at lines 139, 163, 223, 244, 252, 335, and 346). Fix with cd docs && npx prettier --write superpowers/plans/2026-08-03-datadome-ip-excluded-client-tag.md.

Non-blocking

🤔 thinking

  • Bypass header reaches the origin when the bypass is disabled (protection.rs:176, inline)
  • Validator stripping is over-broad and misses Range parity with the ad-stack strip (publisher.rs:2908, inline)
  • Suppression marker rides a one-slot-per-integration document-state map (html_processor.rs:250, inline)

♻️ refactor

  • Duplicate cdn-cache-control entry in CDN_CACHE_HEADERS (response_privacy.rs:25, inline)
  • Missing regression test for publisher-originated tags under suppression (datadome.rs:846, inline)

🌱 seedling

  • No expiry or environment guard on the staging bypass (datadome.rs:129, inline)

CI Status

  • fmt: PASS
  • rust tests (fastly/axum/cloudflare/spin + cross-adapter parity): PASS
  • cloudflare/spin checks: PASS
  • vitest: PASS
  • format-typescript: PASS
  • format-docs: FAIL
  • integration tests (browser, Fastly EC lifecycle): pending at review time

Comment thread crates/trusted-server-core/src/response_privacy.rs Outdated
Comment thread crates/trusted-server-core/src/integrations/datadome/protection.rs Outdated
Comment thread crates/trusted-server-core/src/publisher.rs Outdated
Comment thread crates/trusted-server-core/src/html_processor.rs
Comment thread crates/trusted-server-core/src/integrations/datadome.rs
Comment thread crates/trusted-server-core/src/integrations/datadome.rs
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.

DataDome: suppress client-side tag for IP-excluded requests

2 participants