# Analyse d'anonymat

*Version 1.2 du 15 octobre 2026. Identifiant journalier pseudonyme, statistiques agrégées et seuils d'Equateur Analytics, en mode exempté.*

> **Projet à faire valider par un juriste avant publication.** Cette analyse justifie le caractère anonyme des statistiques produites, comme le permet le critère 4.1 de l'outil d'auto-évaluation de la CNIL quand les chiffres ne sont pas arrondis.

## Résumé

- L'identifiant d'un visiteur est **pseudonyme**, donc une donnée personnelle, tant que la clé du jour existe. Cette clé ne vit que dans la mémoire du serveur : elle n'est jamais écrite dans la base, ni dans ses sauvegardes, et elle est oubliée au plus tard 48 heures après la fin du jour (ou au redémarrage du serveur). Après, l'identifiant ne permet plus de remonter à une adresse IP, et il ne relie jamais deux jours entre eux.
- Les parcours détaillés, pseudonymes, restent sur le serveur pendant la durée de conservation choisie (13 mois par défaut). En mode exempté, ils ne sont **ni montrés ni exportés** : ils servent à calculer les totaux, les entonnoirs et les vues filtrées. Seule exception, le test en direct d'un objectif montre au propriétaire du site **sa propre** visite, celle du navigateur qui fait le test.
- Tout ce qui sort d'Equateur Analytics (tableau de bord, emails, rapports, liens partagés, exports) est **agrégé**. Les vues filtrées, les sources et les campagnes appliquent un **seuil de 3 visites**. Dans une vue filtrée, ce seuil s'applique **semaine par semaine**, sur des semaines entières et closes : comparer deux périodes ne révèle jamais une ou deux visites (point 5).
- Nous concluons que ces statistiques sont anonymes au sens de l'avis 05/2014 du G29, avec les risques résiduels décrits au point 7 et soumis à un juriste.

## 1. Méthode

L'avis 05/2014 du groupe de travail « Article 29 » (aujourd'hui le Comité européen de la protection des données) sur les techniques d'anonymisation retient trois critères. Un jeu de données est anonyme si l'on ne peut pas :

1. **individualiser** une personne, c'est-à-dire isoler les enregistrements qui la concernent ;
2. **corréler** des enregistrements relatifs à une même personne, dans un même jeu ou entre plusieurs jeux ;
3. **inférer** une information sur une personne à partir des autres données.

Nous appliquons ces trois critères à chaque donnée qu'Equateur Analytics produit ou conserve, en supposant un attaquant raisonnable : un utilisateur du compte, ou une personne qui reçoit un rapport ou un lien partagé, et qui connaît par ailleurs une partie de la vie d'un visiteur (par exemple, qu'un collègue a visité le site mardi).

## 2. Ce qui est traité, et pour combien de temps

| Donnée | Durée | Accessible à qui |
|---|---|---|
| Adresse IP, chaîne du navigateur, langue | Le temps de traiter la requête, jamais écrites | Personne |
| Sel du jour (256 bits aléatoires) | Dans la mémoire du serveur seulement, jamais écrit en base ni sauvegardé. Oublié au plus tard 48 heures après la fin du jour du site, et à chaque redémarrage | Le processus du serveur, le temps de calculer les identifiants. Une fois oublié, personne, pas même Equateur Analytics |
| Identifiant du jour : `sha256(sel du jour + domaine du site + adresse IP + navigateur)`, tronqué | Durée de conservation des parcours (13 mois par défaut, de 30 jours à 25 mois) | Le serveur, pour regrouper les pages d'une même visite |
| Parcours détaillés : pages, heure, source, campagne, pays, appareil, objectifs | Même durée | Le serveur, pour calculer les totaux. En mode exempté, ni l'interface ni les exports, sauf le test d'objectif, limité au navigateur qui teste. |
| Statistiques agrégées par jour | Tant que le site existe, fusionnées par mois au-delà de 25 mois | Les membres du site, les destinataires des emails, rapports et liens partagés |

## 3. L'identifiant du jour

**Individualisation.** Le jour même, l'identifiant regroupe les pages vues par un même navigateur sur une même adresse IP. C'est sa fonction : compter des visites, pas des pages. Il n'est jamais affiché ni exporté.

**Corrélation.** L'identifiant ne permet pas de suivre une personne :

- **entre sites**, car le domaine du site entre dans le calcul : le même navigateur sur deux sites produit deux identifiants sans rapport ;
- **entre jours**, car le sel change chaque jour : le même navigateur, le lendemain, produit un autre identifiant ;
- **vers une adresse IP**, car le sel est aléatoire (il n'est pas dérivé de la date), n'est jamais écrit (ni en base, ni dans le journal de la base, ni dans les sauvegardes) et est oublié au plus tard 48 heures après : il devient alors impossible de recalculer l'identifiant d'une adresse IP donnée, même en essayant toutes les adresses possibles.

**Inférence.** Pendant les 48 heures au plus où le sel existe, une personne qui aurait accès à la base et à la mémoire du serveur en marche, et qui connaîtrait l'adresse IP et le navigateur d'un visiteur, pourrait retrouver ses pages du jour. C'est pourquoi l'identifiant est traité comme une **donnée pseudonyme**, donc personnelle, et protégé comme telle (annexe 2 de l'accord de sous-traitance). Une copie de la base ou une sauvegarde ne contient jamais le sel. Une fois le sel oublié, ce rapprochement n'est plus possible.

Le même calcul sert au test en direct d'un objectif : le serveur calcule l'identifiant du jour de la personne qui teste (son adresse IP et son navigateur, au moment de la requête) et ne lui montre que les pages et événements de sa propre visite. Elle ne peut rien voir d'une autre visite, sauf un compteur par objectif.

**Conclusion.** L'identifiant est pseudonyme pendant 48 heures au plus, puis non rattachable. Il n'est jamais exposé. Le jour change selon le fuseau horaire du site, pour qu'une visite ne soit pas coupée en deux au milieu de la nuit locale. Un redémarrage du serveur tire un nouveau sel : une visite en cours à ce moment-là compte pour deux, ce qui gonfle légèrement les visites, jamais l'inverse.

## 4. Les statistiques agrégées

Les statistiques sont des comptes par jour et par dimension : visites, pages vues, temps d'engagement, conversions et valeur, ventilés par page, source, campagne, pays, appareil ou objectif.

**Individualisation.** Aucun enregistrement ne correspond à une personne. Une ligne peut cependant compter une seule visite : en choisissant une période d'un jour, le tableau des pages peut montrer « 1 visite sur la page /tarifs ». Les sources et les campagnes, elles, sont regroupées sous 3 visites en mode exempté : une source rare (un `utm_source` à un nom, un petit site référent) ne s'affiche pas seule. Les dimensions sont volontairement grossières (pays et non ville, famille de navigateur sans version, trois catégories d'appareils, domaine référent et non adresse complète), et l'heure de la visite n'apparaît jamais. Isoler une personne demande donc de savoir déjà qu'elle est venue ce jour-là, sur cette page.

**Corrélation.** Les dimensions sont ventilées une par une dans les vues non filtrées : on ne peut pas croiser « pays » et « page » et « appareil » pour une même visite. Le croisement n'est possible qu'en filtrant, et les vues filtrées appliquent le seuil décrit au point 5.

**Inférence.** Ce qu'une ligne peut révéler est limité à une page vue ou à un objectif atteint (par exemple « une demande de devis »). Le contenu des formulaires n'est jamais collecté, les noms d'événements sont masqués mot à mot (emails, suites de 5 chiffres ou plus, jetons), et les détails d'événements sont limités à une liste blanche de sept clés courtes, masquées (`fichier`, `vers`, `offre`, `formule`, `categorie`, `methode`, `etape`).

**Conclusion.** Les vues non filtrées sont anonymes : elles ne permettent ni d'isoler, ni de suivre, ni de déduire quoi que ce soit sur une personne sans connaissance préalable de sa visite.

## 5. Les seuils

| Situation | Règle |
|---|---|
| Vue filtrée (une source, une page, une campagne, un pays ou un appareil sélectionné) | Des semaines entières (du lundi au dimanche, fuseau du site) et closes seulement : « 7 jours », « 30 jours » et « 90 jours » deviennent les 1, 4 et 13 dernières semaines closes ; les mois et les plages libres sont étendus aux semaines qui les recouvrent, arrêtés au dernier dimanche passé ; une semaine dont la durée de conservation a commencé à effacer les parcours n'entre plus. Chaque nombre (visites, visites converties, rebonds, entrées, conversions et valeur, au total, par ligne, par point de courbe et pour la période de comparaison) est une somme de comptes hebdomadaires, et un compte hebdomadaire de moins de 3 n'y entre pas. Tout nombre qui reste sous 3, zéro compris, est affiché « < 3 ». Aucune semaine d'au moins 3 visites : aucun détail. « Autres (moins de 3 visites) » réunit, semaine par semaine, les comptes trop petits de toutes les lignes, avec le même seuil. |
| Sources, filtrées ou non (mode exempté) | Une source vue sur moins de 3 visites dans la période est regroupée, dans son canal, sous « Autres sources » : tableau de bord, conversions par source, exports, résumé du lundi, rapport mensuel. |
| Campagnes, filtrées ou non (mode exempté) | Une valeur vue sur moins de 3 visites dans la période est regroupée sous « Autres campagnes ». Avec la règle précédente, cela neutralise les liens personnalisés par destinataire. |
| Libellés de campagne et noms d'événements | Masqués mot à mot à la réception : `:email`, `:id` (5 chiffres ou plus, UUID), `:token` (longue chaîne aléatoire). |
| Exports | Agrégés uniquement, en totaux sur la période choisie : `sources` (canal × source), `pages`, `campagnes` (campagne × source × support), `objectifs` (objectif × source), avec les seuils ci-dessus, et `jours` (totaux du site par jour, toutes sources et pages confondues). Depuis une vue filtrée, l'export reprend exactement la vue affichée : mêmes semaines (dans le nom du fichier), mêmes seuils, « < 3 » pour un nombre masqué, et `jours` par semaine. |
| Test en direct d'un objectif | Détail limité à la visite du navigateur qui teste, sur 15 minutes au plus ; un compteur par objectif pour les autres. |
| Compteur « en ce moment » | Un nombre de personnes, sans page ni source. |
| Agrégats de plus de 25 mois | Lignes journalières fusionnées par mois. |

**Pourquoi 3 et non un arrondi à la dizaine.** Un petit site reçoit souvent moins de dix visites par jour sur une page ou une source. L'arrondi à la dizaine rendrait ses statistiques illisibles. Le seuil de 3, appliqué semaine par semaine dans les vues filtrées, empêche de cibler une seule visite dans une combinaison de critères, y compris en comparant deux périodes (ci-dessous), tout en laissant lisibles les volumes d'un petit site.

### Vues filtrées : pourquoi des semaines entières, et un seuil par semaine

**L'attaque.** Un seuil appliqué à chaque nombre affiché ne suffit pas. Le second ré-audit (octobre 2026) l'a montré : avec les filtres Luxembourg et Email, la plage « du 20 juillet au 2 septembre » comptait 7 visites, et « du 20 juillet au 3 septembre » en comptait 8. Chaque total dépassait 3, mais leur différence isolait une visite le 3 septembre, et la ligne de page qui changeait révélait sa page. Toute période qu'on peut décaler d'un jour (plage libre, ou « 7 jours » consulté un jour puis le lendemain) permet cette soustraction.

**La construction.** Toutes les vues filtrées reposent sur une même grille, fixe et commune à tous : les semaines du lundi au dimanche, dans le fuseau du site. Pour une combinaison de critères X (les filtres choisis, plus éventuellement une ligne : une page, une source, un pays, un objectif atteint…) et une semaine s, notons c(X, s) le nombre exact de visites, et f(c) = c si c ≥ 3, 0 sinon. Equateur Analytics n'affiche, pour X et une période P faite de semaines entières, que N(X, P) = somme des f(c(X, s)) pour s dans P, et « < 3 » si cette somme est nulle.

1. **Périodes emboîtées.** Si P est contenue dans P', alors N(X, P') − N(X, P) est la somme des f(c(X, s)) sur les semaines de P' absentes de P : elle vaut 0 ou au moins 3, jamais 1 ou 2.
2. **Toutes les combinaisons de vues.** Chaque nombre affiché ne dépend que des valeurs hebdomadaires f(c(X, s)). Quelles que soient les vues demandées et la façon de les additionner ou de les soustraire, on ne peut au mieux retrouver que ces valeurs hebdomadaires, qui sont exactement celles qu'affiche la vue d'une seule semaine : 0 ou au moins 3. Une semaine avec 1 ou 2 visites dans X est indiscernable d'une semaine vide, puisque 0 est lui aussi affiché « < 3 ».
3. **Des semaines qui ne changent plus.** Une visite appartient au jour où elle commence, et l'identifiant du jour change à minuit (heure du site) : aucune visite ne s'ajoute à une semaine une fois son dimanche passé. La semaine en cours n'entre donc dans aucune vue filtrée. La durée de conservation efface les parcours jour par jour : une semaine qui a commencé à perdre ses jours n'entre plus dans aucune vue. Le garde-fou de la formule gratuite (30 derniers jours) s'applique lui aussi par semaines entières. Revenir chaque jour sur la même vue ne fait donc qu'ajouter ou retirer des semaines entières.
4. **Tous les nombres de la vue.** Le même calcul vaut pour les visites, les visites converties, les rebonds et les entrées, au total et par ligne, pour chaque point de la courbe (une semaine) et pour la période de comparaison (autant de semaines juste avant, ou les mêmes semaines 52 semaines plus tôt). Les pages vues et l'engagement ne sont comptés que pour les semaines retenues (au moins 3 visites), les conversions et la valeur d'un objectif que pour les semaines d'au moins 3 visites converties : leurs différences portent toujours sur au moins 3 visites. Les taux sont calculés à partir de ces sommes.

**Vérification.** `test/vues-filtrees.test.ts` rejoue l'attaque du ré-audit (une visite seule, le 3 septembre, sur une page qu'elle est la seule à voir) : décaler la fin de la plage ne change plus rien. Le test demande ensuite environ 1 800 vues (chaque début et chaque fin de plage sur trois mois, les périodes prédéfinies demandées chaque jour pendant un mois, avec les deux comparaisons) et vérifie que tout nombre affiché vaut au moins 3 ou est masqué, que chacun est la somme des mêmes nombres semaine par semaine, et que deux périodes emboîtées ne diffèrent jamais de 1 ou 2.

**Ce que cela coûte.** Une combinaison de critères qui ne réunit jamais 3 visites dans une même semaine n'affiche rien, même si elle en totalise davantage sur la période (2 par semaine pendant 13 semaines, par exemple). Une vue filtrée ne montre pas la semaine en cours. Les volumes d'un petit site restent lisibles sur les combinaisons qui comptent (une source, un pays, une page fréquentée).

## 6. Ce qui est exclu par construction

- Aucun cookie, aucune écriture sur l'appareil, sauf le drapeau d'opposition d'un visiteur qui refuse la mesure. Le script lit l'adresse de la page, la page précédente (à la première page vue), la largeur de la fenêtre, `navigator.webdriver`, Global Privacy Control, Do Not Track et ce drapeau d'opposition ; aucune de ces lectures ne sert à reconnaître l'appareil (détail dans la grille, critère 3.2).
- Aucun identifiant client, aucun import de données personnelles, aucune fonction « User ID ».
- Aucun journal des visites, profil de visiteur, rejeu de session ni carte de chaleur.
- Aucun export ligne à ligne en mode exempté. En mode consentement, l'export ligne à ligne ne remonte jamais avant le passage en mode consentement.
- Aucune mise en commun entre sites ou entre clients.

## 7. Risques résiduels

1. **Connaissance préalable d'une visite.** Une personne qui sait qu'un visiteur précis est venu tel jour, par telle source, peut constater sur une vue non filtrée qu'une page a été vue ce jour-là depuis cette source. Elle n'apprend rien de plus que ce qu'elle savait déjà, sauf la page consultée. Le risque est faible, et le même que pour tout outil de mesure qui affiche des totaux journaliers.
2. **Parcours détaillés conservés sur le serveur.** Ils sont pseudonymes, inaccessibles dans l'interface et à l'export en mode exempté (hors test d'objectif, limité à sa propre visite), et supprimés au terme de la durée de conservation. Un accès frauduleux à la base, ou à une sauvegarde, les exposerait sans révéler d'adresse IP ni d'identité, et sans le sel qui permettrait de relier un identifiant à une adresse IP. Ce risque est couvert par les mesures de sécurité de l'accord de sous-traitance.
3. **Libellés personnels qui ne ressemblent pas à un identifiant.** Un lien de campagne `utm_source=jean.dupont` est enregistré tel quel dans les parcours. Il n'apparaît dans aucune statistique tant qu'il n'atteint pas 3 visites sur la période affichée. Le mode strict supprime ce risque en ignorant tous les paramètres de campagne.
4. **Totaux non filtrés d'une seule visite.** Les pages, pays et appareils ne sont pas seuillés hors filtre. Sur une période d'un jour, une ligne peut compter une visite (risque 1).
5. **Soustraction entre filtres.** Le seuil hebdomadaire protège chaque combinaison de critères et rend inutile la comparaison de périodes (point 5). Il n'empêche pas de soustraire, pour une même semaine, des lignes affichées d'un total affiché : si une semaine compte 10 visites du Luxembourg dont 9 venues de la recherche, on en déduit qu'une visite du Luxembourg est venue d'un autre canal, sans que la vue dise lequel (Luxembourg et Email affiche « < 3 », comme une semaine vide). En recoupant plusieurs de ces soustractions (canal, appareil, page…), on peut parfois déduire certains attributs de cette visite. C'est le problème classique du « secret secondaire » des tableaux statistiques. Il demande de savoir déjà qu'une personne est venue cette semaine-là, de nombreuses requêtes, et ne porte que sur les dimensions grossières décrites au point 4 ; la même déduction est possible, plus simplement, à partir des totaux non filtrés (risque 4). Une protection plus forte (masquage secondaire, ou arrondi des vues filtrées) rendrait les vues filtrées d'un petit site illisibles.

## 8. Points soumis à un juriste

1. Le caractère anonyme des agrégats non arrondis, avec un seuil de 3 dans les vues filtrées (semaine par semaine, sur des semaines entières et closes), sur les sources et sur les campagnes, mais pas sur les pages, pays et appareils hors filtre.
2. La conservation des parcours pseudonymes côté serveur pour calculer les totaux et les entonnoirs.
3. La conservation des agrégats au-delà de 25 mois, fusionnés par mois.
4. Le risque résiduel de soustraction entre filtres (risque 5 du point 7), et le choix d'un seuil hebdomadaire plutôt que d'un arrondi ou d'un masquage secondaire dans les vues filtrées.
