-
-
Notifications
You must be signed in to change notification settings - Fork 483
Description
Description
It would be great to for this excellent solution to optionally support Global Privacy Control.
It seems to be generally accepted to have it treated as an explicit out-out when the flag is set, UNLESS there's an actual decision indicated in cookies, in which case you respect the cookie. I'm tempted to say it doesn't make sense to try to log those cases, because you have to either start keeping 'already logged GPC' somewhere in a cookie/similar OR spam your logging endpoint, but I welcome feedback on that (and everything else).
I'd propose:
Acceptance Criteria
- solution must NOT write cookies signalling an explicit opt-out upon seeing the GPC signal
- solution must treat the GPC signal as a full opt-out for the purposes of consent enforcement AND suppress the banner upon initial visit (and subsequent page loads / normal interactions)
- solution must allow the consent banner to be popped up by the user by clicking on a footer link / similar - CookieConsent.show() and CookieConsent.showPreferences() must work, essentially, and should show the user as opted out of everything (because of the GPC signal)
- solution must IGNORE the GPC signal when there has been an explicit consent decision by the user (cookies take precedence over GPC opt-out signals, because they mean the user made a choice to pull up the banner and opt in)
- consent logging should not fire upon this solution seeing the GPC flag (this isn’t really a decision as such that needs to be logged, it would send a logging event on every page load, and it doesn’t seem at all in the spirit of the signal)
- explicit consent decisions should continue to log as normal
Proposed solution
It seems like something like this works as expected if I add it between the config definition and running Cookie Consent:
// window.ccConfig is a config object, this snippet modifies it to enforce GPC
var gpcFlagIsTrue = navigator.globalPrivacyControl // can replace this with 'true' or 'false' for simpler testing but make sure to change it back in prod
var noDecisionYet = typeof readCookie((ccConfig.cookie && ccConfig.cookie.name) || 'cc_cookie' ) !== 'string' // will be a string if already set
// disable anything optional when the GPC flag is true in opt-out mode (like the CCPA)
if (gpcFlagIsTrue && ccConfig.mode === 'opt-out' && noDecisionYet) {
logMessage('Enforcing the GPC flag by suppressing all optional tracking and the initial banner pop-up in opt-out mode - no cookies set.')
Object.keys(ccConfig.categories).forEach(function (cat){
var thisCat = ccConfig.categories[cat]
if (thisCat && thisCat.enabled === true && thisCat.readOnly !== true) {
thisCat.enabled = false
}
})
ccConfig.onModalShow = function (modalNameObj) {
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {}; // safety first!
var modalName = modalNameObj.modalName;
var alreadySuppressed = window.tealiumCmpIntegration.gpcAlreadySuppressedOnce === true;
var validDecision = CookieConsent.validConsent();
if (gpcFlagIsTrue && !validDecision && !alreadySuppressed) {
// We have to use setTimeout here to let the 'show' finish - it breaks if you hide it while it's showing
if (modalName === 'consentModal') setTimeout(CookieConsent.hide, 1);
if (modalName === 'preferencesModal') setTimeout(CookieConsent.hidePreferences, 1);
window.tealiumCmpIntegration.gpcAlreadySuppressedOnce = true // only suppress the first pop-up, to allow it to be manually popped-up
}
}
}
// GPC helper functions
function logMessage (message) {
var loggingFunction = (window.tealiumCmpIntegration && window.tealiumCmpIntegration.logger) || (window.utag && window.utag.DB)
return loggingFunction(message);
}
function readCookie (name) {
var reString = '(?:(?:^|.*;\\s*)' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$';
var re = new RegExp(reString);
var cookieValue = document.cookie.replace(re, "$1");
if (!cookieValue) return undefined;
return cookieValue;
}But it'd obviously be cleaner to do it inside the tool itself with a flag to optionally activate that enforcement.
Additional details
FAQ
Wait, why not just opt the user out and be done with it?
One could absolutely do something like this instead, setting an opt-out cookie based on the GPC flag:
var gpcFlagIsTrue = navigator.globalPrivacyControl // can replace this with 'true' or 'false' for simpler testing but make sure to change it back in prod
var noDecisionYet = !CookieConsent.validConsent();
// if new user with GPC flag, disable anything optional and supporess the pop-up when the GPC flag is true in opt-out mode (like the CCPA)
if (gpcFlagIsTrue && ccConfig.mode === 'opt-out' && noDecisionYet) {
ccConfig.autoShow = false
window.addEventListener('cc:onModalReady', function (detail) {
window.tealiumCmpIntegration.logger("Found GPC flag - opting user out of everything optional, setting a cookie even though that has side effects!")
CookieConsent.acceptCategory([]);
CookieConsent.acceptService([]);
});
}BUT that’s not the most satisfying way to handle GPC - many companies want to hold out hope, no matter how remote, that users will decide THEIR COMPANY is trusted and special and deserves to track them despite their GPC flag in their browser for all the normal unspecial companies. That means we need to make sure we don’t set a cookie (in case they deactivate the GPC flag, we want to behave as normal until they make an explicit choice), and that any cookie overrides the GPC signal. The solution in this question sets a cookie and doesn’t allow that, the code above the FAQ in the main body does (and the acceptance criteria are asking for no cookie).
What about opt-in mode? Does GPC play a role there?
All regulatory interpretation is ultimately up to the data controller - we’re just a data processor working on their behalf. But generally, since it’s a simple boolean, it’s rare that someone will think it needs to be enforced for GDPR. For CCPA, the California attorney general has made it clear that it needs to be treated as an opt-out though. It would be good to have the flag work in both opt-in and opt-out models though, following the same pattern.