Consent Management
Signal provides comprehensive consent management that integrates with your Consent Management Platform (CMP), enforces consent rules per-integration before delivery, and passes the correct consent signals to each vendor API.
How Consent Works in Signal
- Capture — Datafly.js reads consent state from your CMP’s cookie or storage location.
- Attach — Two views of the consent state are attached to every event payload:
context.consent.categories— the customer’s CMP-specific codes (e.g.statistics,C0002).context.consent.canonical— Signal’s fixed vocabulary, mapped from those codes.
- Enforce — The pipeline engine filters integrations based on consent before delivery.
- Translate — Vendor blueprints reference consent through
context.consent.canonical.<purpose>, so the same blueprint works for any CMP. - Audit — Every filtering decision is logged.
The two views: categories vs canonical
Signal emits both views on every event so blueprints stay portable across CMPs:
{
"context": {
"consent": {
"categories": {
"necessary": true,
"preferences": true,
"statistics": false,
"marketing": false
},
"canonical": {
"essential": true,
"functional": true,
"analytics": false,
"marketing": false
}
}
}
}| View | Keys | Use it when |
|---|---|---|
categories | The customer’s CMP codes verbatim (e.g. Cookiebot’s statistics, OneTrust’s C0002). | Custom blueprints that intentionally tie to one CMP, or when surfacing the raw signal in audit/UI. |
canonical | A fixed vocabulary of essential, functional, analytics, marketing, personalization. | Vendor blueprints that ship with Signal. References stay valid no matter which CMP the customer uses. |
See Canonical Categories for the full vocabulary, classification guidance, and migration notes.
Supported CMPs
Signal supports reading consent from any CMP, with first-class auto-seeding for the most common ones:
| CMP | Cookie / Storage | Auto-seeded categories |
|---|---|---|
| Cookiebot | CookieConsent (cookie) | necessary, preferences, statistics, marketing |
| OneTrust | OptanonConsent (cookie) | C0001, C0002, C0003, C0004 |
| Didomi | didomi_token (cookie) | Configured per deployment |
| Osano | osano_consentmanager (cookie) | Configured per deployment |
| IAB TCF v2.0 | euconsent-v2 (cookie) | Configured per deployment |
| Custom | Any cookie or localStorage key | Configured per deployment |
When you select a known CMP in Settings → Consent, Signal pre-populates the standard categories and their canonical classifications. You can override these or add custom categories at any time.
Cookie format support
Signal’s parser handles five formats so you rarely need transformation logic in your CMP integration:
- JSON object —
{"necessary":true,"marketing":false} - JS object literal (Cookiebot’s native shape) —
{stamp:'abc==',necessary:true,...} - Colon-delimited, comma-separated —
essential:1,functional:1,analytics:0,marketing:0 - URL query string (OneTrust) —
groups=C0001:1,C0002:1,C0003:0,C0004:0 - Semicolon-delimited
key=value—analytics=1;marketing=0;functional=1
URL-encoding and double-encoding are handled transparently.
Per-Vendor Consent Enforcement
Consent enforcement happens at two stages:
- At ingestion — before any vendor-side identifier sync runs, Signal checks the visitor’s recorded consent against each sync’s required category (default
marketing). Denied vendors are silently omitted so the browser never fires the corresponding match-pixel redirect. See Identity. - At delivery — before events reach each vendor’s API. Each integration can have a consent category gate; events without the required consent are filtered and never delivered.
Both stages honour the pipeline’s consent_mode: explicit (GDPR, absent → denied) or implicit (CCPA, absent → granted).
Vendor-side identifier syncs trigger ePrivacy / PECR cookie-consent obligations even though Signal stores the resulting ID server-side. The browser → vendor redirect causes the vendor to read/write cookies on the vendor’s domain, which is exactly what ePrivacy regulates. Server-side storage location does not remove the consent requirement. The gating described above is on by default and should remain enabled for any pipeline handling UK/EU traffic.
How blueprints reference consent
Vendor blueprints reference consent through the canonical view:
# GA4 blueprint — works for Cookiebot, OneTrust, Didomi, anything
- target: "@root.consent.ad_user_data"
source: "context.consent.canonical.marketing"
transform:
type: value_map
map:
"true": GRANTED
"false": DENIEDThe customer chooses how their CMP’s categories map to Signal’s canonical vocabulary in Settings → Consent. Once that mapping is set, every blueprint that references canonical.marketing (Meta CAPI, Google Ads, TikTok, GA4 …) reads the right value automatically.
Vendor-Specific Rules
In addition to the pipeline-level consent gate, each delivery layer applies vendor-specific consent enforcement. The blueprint determines the exact behaviour; the table below shows the typical defaults shipped with Signal:
| Vendor | When canonical.marketing denied | Action |
|---|---|---|
| Meta CAPI | denied | Strip PII (email, phone, fbp, fbc, IP, UA). Set data_processing_options=['LDU']. |
| Google Ads | any state | Include Consent Mode v2 params. Google handles modelling internally. |
| GA4 | any state | Include ad_user_data and ad_personalization in payload. |
| TikTok | denied | Strip PII (email, phone, ttp, ttclid, IP, UA). Set limited_data_use=true. |
| Microsoft UET | denied | Suppress event entirely (UET does not support degraded delivery). |
Consent Audit Logging
Every consent filtering decision is recorded in the consent_filtered_events table:
| Field | Description |
|---|---|
pipeline_id | Which pipeline the event was processed through |
integration_id | Which integration was blocked |
consent_category | The consent category that was denied |
event_type | The type of event (page, track, etc.) |
event_name | The specific event name |
anonymous_id_hash | SHA256 hash of the anonymous ID (privacy-safe) |
filtered_at | Timestamp of the filtering decision |
This provides a complete audit trail for compliance reviews without storing PII.
Configuration
1. Add a consent provider
- Go to Settings → Consent.
- Click Add Provider and pick your CMP (or Custom).
- Cookie name, storage type, and standard categories are pre-populated for known CMPs.
- Each category has a Canonical Category dropdown — set it to one of
essential,functional,analytics,marketing,personalization. Leave blank for unclassified categories (they still appear undercategoriesbut not undercanonical).
2. Pipeline-Level Consent Gate
Each integration attached to a pipeline can have a consent category:
- Go to Pipelines → [Your Pipeline] → Integrations.
- Click an integration.
- Set the Consent Category (typically
marketing,analytics, orfunctional— these refer to the canonical vocabulary). - Set the Consent Mode (“Explicit” for GDPR, “Implicit” for CCPA).
Events without the required consent for that category will be filtered before delivery.
3. Notify the SDK on consent change
Whenever the user updates consent (CMP banner, preferences page), call:
datafly.refreshConsent();This is cheap and idempotent — modules diff internally. The next event the SDK sends carries the new state.