Skip to content

Add Osano consent mirror integration#773

Merged
ChristianPavilonis merged 6 commits into
mainfrom
feature/osano-integration
Jun 22, 2026
Merged

Add Osano consent mirror integration#773
ChristianPavilonis merged 6 commits into
mainfrom
feature/osano-integration

Conversation

@ChristianPavilonis

Copy link
Copy Markdown
Collaborator

Summary

  • Adds an explicitly-enabled Osano consent mirror that copies Osano IAB API output into the standard consent cookies Trusted Server already reads.
  • Refactors CMP mirror module inclusion so Sourcepoint and Osano are loaded through normal integration configuration instead of unconditional JS inclusion.
  • Documents the implemented design and adds Rust/Vitest coverage for registration, module selection, ownership, retries, and failure handling.

Changes

File Change
crates/js/lib/src/integrations/osano/index.ts New Osano browser consent mirror for us_privacy, __gpp, __gpp_sid, and euconsent-v2 with _ts_consent_src=osano ownership.
crates/js/lib/test/integrations/osano/index.test.ts Vitest coverage for mirroring behavior, ownership preservation, stale-cookie clearing, failures, timeouts, retries, and initialization.
crates/trusted-server-core/src/integrations/osano.rs Minimal enabled/disabled integration registration for the JS-only Osano module.
crates/trusted-server-core/src/integrations/mod.rs Adds Osano to the integration builder list.
crates/trusted-server-core/src/integrations/registry.rs Tracks enabled integration IDs so opt-in JS-only registrations can be included; removes Sourcepoint from unconditional JS inclusion.
trusted-server.toml Adds disabled-by-default [integrations.osano] config block.
docs/superpowers/specs/2026-06-17-osano-consent-mirror-design.md Captures the implemented design.

Closes

Closes #772

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: cd crates/js/lib && node build-all.mjs
  • Other: cd docs && npx prettier --check .

Checklist

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

Comment thread crates/js/lib/test/integrations/osano/index.test.ts Fixed

@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

The Osano mirror is a good direction and the PR has solid CI coverage, but I found two consent-state correctness issues that should be fixed before merge. I also included a small registry refactor request and two non-blocking follow-ups around migration/docs.

Blocking

🔧 wrench

  • Overlapping mirror attempts can apply stale consent: mirrorOsanoConsent() awaits async IAB API reads without guarding against older attempts completing after newer consent events, so a delayed callback can overwrite the current consent state. (crates/js/lib/src/integrations/osano/index.ts:394)
  • GPP empty-value clearing bypasses the Osano readiness guard: USP and TCF empty values wait for Osano readiness before clearing stale cookies, but GPP ready-with-empty clears immediately. (crates/js/lib/src/integrations/osano/index.ts:290)

Non-blocking

♻️ refactor

  • Derive JS module availability instead of hardcoding integration IDs: JS_EXCLUDED has to stay in sync with Rust registrations and generated TSJS modules. Prefer checking whether trusted_server_js::module_bundle(id) exists for each enabled integration. (crates/trusted-server-core/src/integrations/registry.rs:1144)

🤔 thinking

  • Sourcepoint mirror is now opt-in, which is a behavior change: existing deployments that relied on the unconditional Sourcepoint GPP mirror will stop shipping that JS unless they explicitly enable [integrations.sourcepoint]. This likely deserves a migration note. (crates/trusted-server-core/src/integrations/registry.rs:1146)

🌱 seedling

  • Public integration docs should mention Osano enablement: the design spec is useful, but operators will likely look in public guide/configuration docs for [integrations.osano] enabled = true and the first-request/next-request limitation.

CI Status

  • Analyze (actions): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (rust): PASS
  • CodeQL: PASS
  • browser integration tests: PASS
  • cargo fmt: PASS
  • cargo test: PASS
  • format-docs: PASS
  • format-typescript: PASS
  • integration tests: PASS
  • prepare integration artifacts: PASS
  • vitest: PASS

Comment thread crates/js/lib/src/integrations/osano/index.ts
Comment thread crates/js/lib/src/integrations/osano/index.ts Outdated
Comment thread crates/trusted-server-core/src/integrations/registry.rs Outdated
Comment thread crates/trusted-server-core/src/integrations/registry.rs
@ChristianPavilonis

Copy link
Copy Markdown
Collaborator Author

Also addressed the non-inline docs feedback in e62f8e0 by adding public Osano enablement docs, linking the Osano guide from the sidebar and integrations overview, and documenting the first-request/subsequent-request limitation.

@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

Re-review. Both prior 🔧 blockers and all three non-blocking items from the earlier review are resolved, each with regression coverage, and CI is fully green.

  • Stale overlapping consent — fixed via the mirrorGeneration guard; only the latest in-flight attempt applies (mirrorOsanoConsent). Covered by a dedicated overlap test.
  • GPP empty-value clearing — now routes through the same Osano-readiness guard as USP/TCF (emptyAfterOsanoReadyResult). Covered by preserve-until-ready and clear-when-ready tests.
  • JS module derivationjs_module_ids() now derives availability from trusted_server_js::module_bundle(id) over enabled integrations instead of a hardcoded denylist. Verified behavior-preserving against main (only the intended Sourcepoint change).
  • Sourcepoint opt-in — documented as a Breaking CHANGELOG entry plus a migration note in the Sourcepoint guide.
  • Public docs — added the Osano guide, configuration section, sidebar/overview links, and the first-request limitation.

I independently traced the cookie ownership/clearing state machine, the multi-attempt generation race, and the denylist→allowlist refactor — no blocking issues. Approving. Two optional non-blocking notes are left inline.

CI Status

  • cargo fmt: PASS
  • cargo clippy / Analyze (rust): PASS
  • cargo test: PASS
  • vitest: PASS
  • format-typescript / format-docs: PASS
  • browser + integration tests: PASS

Comment thread crates/js/lib/src/integrations/osano/index.ts
Comment thread crates/js/lib/src/integrations/osano/index.ts
@ChristianPavilonis ChristianPavilonis merged commit 5b0a413 into main Jun 22, 2026
14 checks passed
@aram356 aram356 deleted the feature/osano-integration branch June 22, 2026 19:10
aram356 added a commit that referenced this pull request Jun 22, 2026
Reconcile main (Osano CMP mirror #773, fastly extraction out of core,
EC/storage refactors) with this branch's EdgeZero/fastly-0.12 bump.

Resolution decisions:
- Keep this branch's dependency bump: fastly/log-fastly 0.12 and edgezero
  git deps tracking branch=main (over main's pinned rev + 0.11.12), plus
  the trusted-server-* crate renames.
- Take main's newer runtime code for conflicted files (EC http:: migration,
  settings, geo, testlight, adapter restructure), then forward-port it to
  the edgezero-main / fastly-0.12 API surface:
  - Body::into_bytes() now returns Option<Bytes>; buffered sites use
    unwrap_or_default() (batch_sync, pull_sync, identify/testlight tests).
  - fastly 0.12 get_tls_protocol()/get_tls_cipher_openssl_name() return
    Result<Option>; call sites use .ok().flatten().
  - edgezero-main moved adapter symbols into submodules
    (request::into_core_request, config_store::FastlyConfigStore,
    context::FastlyRequestContext) and made router oneshot()/IntoResponse
    into_response() fallible; dispatch and test sites updated accordingly.
- Accept main's deletion of core storage/secret_store.rs (fastly removal).
- Fix a directory-rename gap: main added Osano JS under the old crates/js
  path; relocated into crates/trusted-server-js so the bundle is discovered.

Verified: cargo fmt/clippy/test --workspace, wasm release build,
JS vitest + format. All green.
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.

Add Osano CMP consent mirror integration for EC gating

3 participants