Google Tag Manager, Google Analytics et RGPD

Franck Scandolera

Configurez votre tracking Analytics avec Google Tag Manager pour être RGPD friendly.

Le règlement général sur la protection des données (RGPD) arrive à grands pas (25 mai 2018) qu’il n’y a plus de temps à perdre pour être conforme. Si comme moi vous gérez des sites WP, il y a pas mal de ménage à faire pour être conforme. Pour plus d’info, consulter le site de la www.cnil.fr pour mieux comprendre les étapes clés de mise en conformité RGPD.
Le sujet étant tellement vaste et complexe, je vais essayer de centrer cet article sur la partie collecte de données Analytics avec Google Tag Manager.

La RGDP et l’Analytics.

Les données Analytics sont des données personnelles, car elles sont reliées in fine à un utilisateur, plus précisément à son identifiant « CID » stocké dans le cookie _ga (Web) ou au Mobile ID (App).
Nous devons expliquer en toute transparence aux utilisateurs, le type de données personnelles collectées, leur utilisation ainsi que la durée de conservation.  Nous devons également leur expliquer comment faire valoir leurs droits de consultation (simple – basé sur le CID), de modification (très complexe/inutile en WA – « modifier tel hit, car je n’ai pas vu cette page… »), de portabilité (complexe/inutile en WA – migrer données comportementales/CID GA vers AT-Internet) et de suppression (simple – basé sur le CID) de leurs données personnelles.
Côté consentement, c’est encore flou,surtout en ce qui concerne le consentement préalable (avant dépose de cookie)…
A priori, pas de consentement préalable si :

  • L’utilisateur est clairement informé au préalable du traitement des données Analytics et marketing et qu’il a la possibilité de s’y opposer. À vérifier pour la partie Marketing…

Le consentement préalable serait obligatoire si :

  • Si la finalité principale est d’alimenter des traitements accessoire. Traitement qui sort a priori du scope Web ou App Analytics (analyses agrégées et anonymes de l’expérience utilisateur, des usages et performances des fonctionnalités et de la réalisation des objectifs), comme le remarkting ou la personnalisation des messages promotionnels.
  • Si collecte de données sensibles (santé, religion, sexualité, bancaire…).

La GDPR précise le rôle de deux acteurs clés dans la gestion des données, le Data Controler (les éditeurs de sites et d’APP) et les Data Processor (les éditeurs de solution de données). Pour cadrer les responsabilités, le Data Controler et le Data Processor doivent s’entendre sur les conditions relatives au traitement des données (Data Processing Terms ou DPT).
En résumé dans un contexte Web Analytics :

En tant que Data Controler, les éditeurs de site Web ont l’obligation d’être en phase avec la RGPD, de la collecte à l’usage des données personnelles (dimensions/métriques directement reliées à l’identifiant anonyme stocké dans le cookie _ga ou natif comme le mobile ID). Par exemple, on devrait pouvoir reporter librement des données agrégées tant qu’elles ne sont pas directement contextualisées à un  ID utilisateur anonyme (CID) ou non (UID). Pour personnaliser des données comportementales ou les partager dans des systèmes tiers (ex. DMP, CRM), il faudrait avoir le consentement préalable des utilisateurs.

Google Tag Manager, Analytics et RGPD.

Avant l’exploitation des données personnalisées, il y a une phase de setup « RGPD Friendly » à mettre en oeuvre.
Voici quelques exemples utiles de configuration Google Tag Manager et Analytics.

  • Accepter les conditions Data Processing Terms dans Google Analytics.
  • Accepter l’avenant relatif au traitement des données dans Google Tag Manager.
  • Exiger la validation en deux étapes des identifiants de connexion pour certaines opérations.
  • Masquer l’adresse IP pour supprimer le dernier octet de l’adresse IP des internautes.
  • Forcer les pages HTTP à envoyer les hits en HTTPS.
  • Fixer la durée d’expiration du cookie _ga à 13 mois, depuis sa création.
  • Expurger les données personnellement identifiables (PII) envoyées à GA.
  • Conditionner l’activation des fonctionnalités de publicité des hits GA selon le consentement utilisateur (cookie).

Google Analytics, acceptez les conditions Data Processing Terms.

Il s’agit d’un avenant qui définit les responsabilités du traitement des données entre le Data Controler (nous) et le Data Processer (Google). Vous devez accepter l’avenant soit changer d’outil Analytics, il ne semble pas possible de pouvoir discuter les clauses. Pour découvrir et valider le DPT (ou DPA Data Processing Agrement), rendez-vous dans Google Analytics > Admin > Compte > Modification du traitement des données. Une fois l’avenant validé, il faudra communiquer à Google le contact des représentants de l’entreprise (juridique, gérant, CDO..) dans le formulaire « DPA ». Mais si le formulaire refuse d’enregistrer vos contacts (comme c’était le cas pour ma pomme), vous devrez créer préalablement un compte entreprise dans Google Analytics Suite Home…
google-analytics-RGPD-DPT-data-processing-terms

Accepter les conditions Data Processing Terms dans Google Tag Manager.

Comme pour Google Analytics, vous devez accepter DPT de Google Tag Manager. Rendez-vous dans l’administration de votre compte Google Tag Manager pour accepter l’avenant relatif au traitement des données.

Exiger la validation en deux étapes des identifiants de connexion pour certaines opérations.

Toujours dans l’admin du compte Google Tag Manager, activer l’option « Exiger la validation en deux étapes des identifiants de connexion pour certaines opérations. » Plus d’info directement chez Google https://support.google.com/accounts/answer/185839?hl=fr&ref_topic=2954345.
google-analytics-tag-manager-RGPD-double-verification

Google Tag Manager anonymisez l’adresse IP.

Anonymiser les IP permet de supprimer le dernier octet de l’IP et donc de dégrader sa précision. À noter que par défaut vous n’avez pas accès aux adresses IP collectées par Google Analytics. En tant que données personnelles directes (IP, email, photo…) vous n’avez pas le droit de la stocker dans GA.
Pour supprimer le dernier octet des IP dans Google Tag Manager, il faut définir le champ « anonymiseIP » sur « true » des hits Google Analytics. Pour cela, définissez un nouveau champ « anonymizeIp » avec la valeur « true » dans toutes vos balises Universal. Le plus simple est d’utiliser une variable ‘Paramètres Google Analytics » (cf. image ci-dessous) à appeler dans toutes les balises pour centraliser les configurations Universal Analytics.
google-analytics-RGPD-GTM-anonymizeIP

Forcer les pages HTTP à envoyer les hits en HTTPS.

Par défaut les pages HTTPS envoient les hits en HTTPS, et les pages HTTP envoient le hit en HTTP. Le but est d’envoyer tous les hits en HTTPS. Pour cela, définissez un nouveau champ « forceSSL » avec la valeur « true » dans toutes vos balises Universal. Le plus simple est d’utiliser une variable ‘Paramètres Google Analytics » (cf. image ci-dessous) à appeler dans toutes les balises pour centraliser les configurations Universal Analytics.

Fixer la durée d’expiration du cookie _ga à 13 mois, depuis sa création.

La durée de 13 mois est la durée max légale de conservation d’un cookie et cela à partir de sa création. Or l’expiration du cookie de Google Analytics (« _ga=GA1.2.480157514.1520623338 ») est de 24 mois glissant depuis la dernière visite.
Pour améliorer notre conformité au RGPD, nous devons donc modifier la durée d’expiration par défaut du cookie _ga. Voici comment procéder avec Google Tag Manager.
1 – Créer une variable GTM « cookie » pour récupérer le CID contenu dans le cookie  « _ga ».
2 – Créer une variable JavaScript personnalisée « cookie _ga expires 13 months » pour calculer et retourner la nouvelle date d’expiration en secondes.

function(){
try {
    var ga = {{cookie _ga}};
    var ga_create= (Number(ga.split(".").pop()))*1000;
    var sec_expire = 60*60*24*30*13*1000;
    var t = new Date().getTime();
    var t0 = new Date(ga_create).getTime();
    var t1 = t0 + sec_expire;
    var t_diff = Math.round((t1-t)/1000);
    return t_diff;
} catch(e){
  	return sec_expire/1000;
	console.log(e);
}
}

Explications :

  1. var ga fait référence à  la variable GTM « cookie _ga », qui représente la valeur du cookie _ga ex. « GA1.2.1008265330.1520804885 ».
  2. var ga_create fait référence à la date de création du cookie _ga en millisecondes écoulées depuis le 1er janvier 1970. Pour obtenir l’information, on découpe la chaîne « ga » à partir des « . » pour récupérer via la méthode push() le dernier élément « 1520804885 », qui correspond à la date de création du cookie. Un dernier élément qu’on convertit en nombre avant de le multiplier par 1000, pour avoir la version millisecondes.
  3. var sec_expire correspond à 13 mois en millisecondes.
  4. var t représente à maintenant en nombre de millisecondes écoulées depuis le 1er janvier 1970, généré via new Date().getTime().
  5. var t0 représente la date de création du cookie en nombre de millisecondes écoulées depuis le 1er janvier 1970.
  6. var t1 représente la date d’expiration en millisecondes calculer à partir de la date de création du cookie _ga + 13 mois.
  7. var t_diff représente la différence en secondes entre t1 et t. C’est cette valeur qui va renseigner le paramètre cookieExpires des hits Google Analytics.

3 – Configurer le paramètre « cookieExpires  » avec la nouvelle date d’expiration dans la variable « Paramètres Google Analytics » qui doit être appelée par toutes les balises Google Analytics.
4 – Tester et aller boire un café.

Expurger les données personnellement identifiables (PII) envoyées à GA.

Les données personnelles directes peuvent s’intégrer dans vos données « à l’insu de votre plein gré », par exemple quand vous reportez la variable intégrée GTM « Click URL » d’un clic sur un lien mailto ou quand les données d’un formulaire sont passées dans l’URL, etc. Le but et de détecter et remplacer les PII par un message du type « REDACTED EMAIL » au moment de l’envoi des données (hitPayload – protocole de mesures) au serveur GA. Le script pour faire le job est celui de Simo avec quelques RegExp en plus (à tester sur votre site).
Intégrez ce script dans une variable « JavaScript personnalisé », nommée par exemple « js – GA customTask ». Si nécessaire, ajoutez/adaptez les expressions RegExp pour qu’elles correspondent aux PII de votre site.

function() {
return function(model) {
// Add the PII patterns into this array as objects
var piiRegex = [{
  name: 'EMAIL',
  regex: /[^\/]{4}@[^\/]{4}/g
},{
  name: 'TEL',
  regex: /((tel=)|(telephone=)|(phone=)|(mobile=)|(mob=))[\d\+\s][^&\/\?]+/gi
},{
  name: 'NAME',
  regex: /((prenom=)|(nom=)|(firstname=)|(lastname=)|(surname=))[^&\/\?]+/gi
}];
var globalSendTaskName = '_' + model.get('trackingId') + '_sendHitTask';
// Fetch reference to the original sendHitTask
var originalSendTask = window[globalSendTaskName] = window[globalSendTaskName] || model.get('sendHitTask');
var i, hitPayload, parts, val;
// Overwrite sendHitTask with PII purger
model.set('sendHitTask', function(sendModel) {
  hitPayload = sendModel.get('hitPayload').split('&');
  for (i = 0; i < hitPayload.length; i++) {
	parts = hitPayload[i].split('=');
	// Double-decode, to account for web server encode + analytics.js encode
	val = decodeURIComponent(decodeURIComponent(parts[1]));
	piiRegex.forEach(function(pii) {
	  val = val.replace(pii.regex, '[REDACTED ' + pii.name + ']');
	});
	parts[1] = encodeURIComponent(val);
	hitPayload[i] = parts.join('=');
  }
  sendModel.set('hitPayload', hitPayload.join('&'), true);
  originalSendTask(sendModel);
});
};
}

Appelez la variable « js – GA customTask » dans un champ « customTask » dans votre variable « GA Setup » (variable « Paramètres Google Analytics ») qui doit être utilisée dans toutes vos balises Google Analytics. Une fois que vous avez ajouté cette variable à vos tags Google Analytics,  les hits de ces balises  seront analysés par cette variable, qui remplace les instances de PII par la chaîne [REDACTED pii_type].
google-analytics-RGPD-GTM-customTask-remove-pii
En résumé, en début de script on liste dans un tableau « piiRegex », plusieurs objets avec 2 propriétés « name » et « regex », pour identifier et reporter les PII qui seront expurgés du hitPayload.
On met de coté le sendHitTask original dans la variable « originalSendTask » pour pouvoir l’opérer « model.set » et expurger les PII du hitPayload.  On split la chaine « hitPayload » à partir de « & » pour servir de condition incrémentale de la boucle « for ». Une boucle pour passer à la moulinette « piiRegex.forEach », chaque valeur « hitPayload[i].split(‘=’) » des variables afin de remplacer par [REDACTED ‘ + pii.name + ‘], les valeurs correspondantes avec les propriétés « regex » du tableau piiRegex.

Conditionner l’activation des fonctionnalités de publicité des hits GA selon le consentement utilisateur (cookie).

L’activation des fonctionnalités de publicité (DoubleClick) est associée à la configuration d’un hit Google Analytics. Or d’un point de vue du consentement, les deux appartiennent à deux familles différentes, les stats pour GA (améliorer l’UX et les performances) et l’advertising pour les fonctionnalités DC (ciblage personnalisé). Pour distinguer les deux configurations, nous devons une fois de plus utiliser le customTask pour hacker les hits GA et les modifier selon le consentement (opt out == true/false).
Pour gérer dans Google Tag Manager le consentement utilisateur, nous devons récupérer l’infirmation dans une variable dataLayer (un DL positionné au-dessus du script GTM dans le head) ou cookie. Dans l’exemple, le consentement est stocké dans des 2 cookies « cookie_ga_opt_out » et « cookie_dc_opt_out » dont la valeur peut être « true » ou « false ». True = on ne doit pas déclencher.
google-analytics-RGPD-GTM-cookie-GA-opt-out
Pour conditionner le déclenchement de GA ou la redirection DC, on va modifier la variable custom JavaScript  « js – GA customTask » qui dégradait les PII.  Il est inutile de créer une nouvelle variable JavaScript, car on peut utiliser qu’un seul champ customTask par balise Universal. Donc tous les scripts qui visent à modifier le hitPayload doivent être regroupés dans une seule et même variable que je nomme souvent « js – GA customTask ».

function() {
	return function(model) {
		// Liste des objets PII de référence pour identifier les données dans le payload.
		var piiRegex = [{
			name: 'EMAIL',
			regex: /[^\/]{4}@[^\/]{4}/g
			},{
			name: 'TEL',
			regex: /((tel=)|(telephone=)|(phone=)|(mobile=)|(mob=))[\d\+\s][^&\/\?]+/gi
			},{
			name: 'NAME',
			regex: /((prenom=)|(nom=)|(firstname=)|(lastname=)|(surname=))[^&\/\?]+/gi
			}];
			var globalSendTaskName = '_' + model.get('trackingId') + '_sendHitTask';
		// Récupération des données originales sendHitTask
		var originalSendTask = window[globalSendTaskName] = window[globalSendTaskName] || model.get('sendHitTask');
		var i, hitPayload, parts, val;
		// Teste si cookie_dc_opt_out. Si oui, on supprime les paramètres du hit ce qui annule l'envoi.
		if ({{cookie_dc_opt_out}} === 'true') {
			model.set('displayFeaturesTask', null);
		}
		// Teste si service GA est opt-out. Si oui, on supprime les paramètres du hit ce qui annule l'envoi.
		if ({{cookie_ga_opt_out}} === 'true') {
			model.set('sendHitTask', null);
		} else {
			  // Sinon on libere le sendHitTask, sans les données PII purgées.
			model.set('sendHitTask', function(sendModel) {
			hitPayload = sendModel.get('hitPayload').split('&');
			for (i = 0; i < hitPayload.length; i++) {
				parts = hitPayload[i].split('=');
				// Double-decode, to account for web server encode + analytics.js encode
				val = decodeURIComponent(decodeURIComponent(parts[1]));
				piiRegex.forEach(function(pii) {
				val = val.replace(pii.regex, '[REDACTED ' + pii.name + ']'); // On remplace les données PII par "REDACTED" (expurgés).
			});
			parts[1] = encodeURIComponent(val);
			hitPayload[i] = parts.join('=');
			}
			sendModel.set('hitPayload', hitPayload.join('&'), true);
			originalSendTask(sendModel); // envoi des données
		});
		};
	};
}

En résumé, j’ai ajouté le code en gras qui conditionne l’exécution du code qui purge les PII.
Si « opt out » égale « true » alors, désactive le hit. Pour désactiver le hit GA ou la redirection DC, il suffit de passer en paramètre « null ».
model.set(‘displayFeaturesTask’, null)
model.set(‘sendHitTask’, null)

// Teste si cookie_dc_opt_out. Si oui, on supprime les paramètres du hit ce qui annule l'envoi.
if ({{cookie_dc_opt_out}} === 'true') {
    model.set('displayFeaturesTask', null);
}
// Teste si service GA est opt-out. Si oui, on supprime les paramètres du hit ce qui annule l'envoi.
 if ({{cookie_ga_opt_out}} === 'true') {
	model.set('sendHitTask', null);
 } else {
/ *** CODE QUI PURGE LES PII  *** /
}

Voilà, on arrive au bout de l’article Google Tag Manager et Google Analytics et RGPD. Maintenant c’est à vous de jouer !