Skip to content

feat(container): unify cookie consent with the OVHcloud CMP#23055

Open
MehdiZaghouani wants to merge 2 commits into
developfrom
MANAGER-22048-container-cmp-integration
Open

feat(container): unify cookie consent with the OVHcloud CMP#23055
MehdiZaghouani wants to merge 2 commits into
developfrom
MANAGER-22048-container-cmp-integration

Conversation

@MehdiZaghouani

Copy link
Copy Markdown
Contributor

Summary

Integrates the OVHcloud CMP (Consent Management Platform) into the container
app to unify cookie consent across OVHcloud properties (the website, the order
funnel and Manager V8 already use it). Two commits:

  1. feat(container): add cmp facade to load the consent platform — a small
    framework-agnostic facade (src/cmp/) that declares the host context in
    window.__cmpConfig and injects the two-stage CMP loader.
  2. feat(container): drive tracking consent through the cmpCookiePolicy
    becomes a bridge: the CMP banner replaces the in-house consent modal for
    EU/CA and its choices drive the existing shell tracking plugin.

The Piano tracking stack is untouched: same bundled SDK, same tracking
plugin methods, same postMessage RPC for child apps (legacy iframes included).
Only the source of the consent boolean changes — the CMP instead of the
in-house TC_PRIVACY_CENTER modal.

ref: #MANAGER-22048

Workflow

Container boot (EU/CA)
  |
  +-- cmp.load()
  |     +-- window.__cmpConfig = { locale, region, environment, scripts: [] }
  |     |     (scripts intentionally empty: the CMP owns the consent UI and
  |     |      the cmp_consent cookie ONLY -- it injects no tag container,
  |     |      Piano stays bundled and gated by the tracking plugin)
  |     +-- inject cmp.iife.js (loader -> version.json -> versioned bundle)
  |
  +-- cmp.whenReady()
        |
        +-- cmp.isError() ------------------> FALLBACK: legacy TC_PRIVACY_CENTER
        |     (loader blocked, outage)        modal, unchanged behavior
        |
        +-- cmp.getConsent()
        |     +-- null ...................... CMP banner on screen;
        |     |                               tracking waits (beforeConsent)
        |     +-- { analytics: true } ....... trackingPlugin.init(true)
        |     +-- { analytics: false } ...... trackingPlugin.setEnabled(false)
        |                                     + delete clientSideUserId
        |
        +-- cmp.onConsentChange(choices)
              -> trackingPlugin.onUserConsentFromModal(choices.analytics)
                 (banner choice, preferences update, withdrawal)

US region: unchanged -- no CMP, tracking auto-enabled as today.
Child apps: unchanged -- they keep calling the tracking plugin over the
shell postMessage RPC; consent stays enforced centrally in the container.

Key design points

  • Consent mapping: the Manager's single tracking consent maps to the CMP
    analytics category; cmp_consent becomes the source of truth (read
    exclusively through the window.__cmp API, never parsed directly).
  • Endpoints: production (manager.{eu,ca,us}.ovhcloud.com) loads the CMP
    from www.ovhcloud.com (CORS-open, verified); every other hostname declares
    preproduction (fail-closed) and loads the preprod CMP — local dev works
    with zero setup.
  • Resilience: cmp:ready is armed before injection and time-bounded
    (10 s); on loader error or timeout the legacy modal takes over
    automatically, so consent collection survives a CMP outage.
  • Existing users are re-prompted once by the CMP banner (their consent
    lives in the legacy cookie, which the CMP does not read) — fresh consent
    under the current policy version.

Tests

  • 21 new/updated tests (13 cmp facade, 8 CookiePolicy bridge covering the CMP
    paths, the consent-change forwarding, and the 3 legacy-fallback scenarios).
  • Full container suite green (235 tests). Validated locally end-to-end:
    banner replaces the legacy modal, accept/refuse drive Piano, preferences
    modal, legacy fallback when the CMP host is blocked.

@MehdiZaghouani
MehdiZaghouani requested a review from a team as a code owner July 24, 2026 07:52
@MehdiZaghouani MehdiZaghouani changed the title Manager 22048 container cmp integration feat(container): unify cookie consent with the OVHcloud CMP Jul 24, 2026
@MehdiZaghouani
MehdiZaghouani force-pushed the MANAGER-22048-container-cmp-integration branch from 22d2e51 to dc1269c Compare July 24, 2026 07:55
Mehdi Zaghouani added 2 commits July 24, 2026 10:52
Loads the OVHcloud CMP (Consent Management Platform) from the container:
declares window.__cmpConfig (locale, region, environment resolved from
the hostname, fail-closed to preproduction) then injects the two-stage
stable-name loader, and wraps the window.__cmp API (whenReady,
getConsent, onConsentChange, showPreferences). The loader URLs come
from the VITE_CMP_LOADER_URL and VITE_CMP_LOADER_URL_PREPROD build
variables — the same build artifact is deployed to every environment,
so both ship in the dist and the effective one is selected at runtime
from the hostname; unset means the CMP is unavailable there and the
legacy consent modal takes over. scripts is intentionally empty: Piano
stays bundled and consent-gated by the tracking plugin — the CMP owns
the consent UI and the cmp_consent cookie only. cmp:ready is armed
before injection and time-bounded; isError() lets the caller fall back
to the legacy modal.

ref: #MANAGER-22048
Signed-off-by: Mehdi Zaghouani <mehdi.zaghouani@corp.ovh.com>
The CMP replaces the in-house consent modal for EU/CA: its banner and
preferences modal own the consent UX, the cmp_consent cookie becomes
the source of truth, and the Manager's single tracking consent maps to
the CMP analytics category. CookiePolicy becomes a bridge: it applies
the CMP choices to the shell tracking plugin (init / setEnabled /
onUserConsentFromModal) so every child app, legacy iframes included,
stays gated through the existing plugin RPC. The legacy
TC_PRIVACY_CENTER modal is kept as an automatic fallback when the CMP
cannot come up, and the US region keeps its auto-enabled behavior.

ref: #MANAGER-22048
Signed-off-by: Mehdi Zaghouani <mehdi.zaghouani@corp.ovh.com>
@MehdiZaghouani
MehdiZaghouani force-pushed the MANAGER-22048-container-cmp-integration branch from dc1269c to 5e3bdca Compare July 24, 2026 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant