TRACIO est un système d'identification client-serveur. Le client collecte des signaux du navigateur et les envoie au serveur, qui calcule un identifiant de visiteur stable, exécute des algorithmes de détection et renvoie des résultats enrichis. Cette section explique chaque étape du pipeline.
Browser TRACIO Cloud | | |-- Tracio.init({ publicKey }) ---------> | (init, no network) | | |-- tracio.getResult() ----------------> | | 1. Collect 130+ browser signals | | 2. Encrypt (XOR + deflate + B64) | | 3. POST to ingress endpoint | | | | |-- Decrypt & extract signals | |-- Compute visitor ID (MurmurHash3-128) | |-- Run bot detection (weighted scoring) | |-- Run smart signals (server-side enrichment) | |-- Run IP intelligence (VPN/proxy/Tor) | |-- Store visit event | | |<-- JSON response ------------------- | | visitorId, confidence, | | bot detection, smart signals | | | |-- Store visitor cookie (_vid_t) -----> | (365-day persistence)Lorsque tracio.getResult() est appelé, le client collecte 130+ signaux de navigateur distincts, organisés en tiers. La collecte utilise un pipeline multi-phases avec des Web Workers et des iframes partagées pour la performance.
| Catégorie | Nombre de signaux | Exemples |
|---|---|---|
| Canvas & WebGL | 9 | Empreinte canvas, renderer WebGL, paramètres WebGL, WebGPU |
| Audio | 3 | Empreinte AudioContext, latence de base, timing DRM |
| Polices & Rendu | 10 | Détection de polices, préférences de polices, MathML, rendu des emoji |
| Navigator & Plateforme | 25 | User-Agent, langues, écran, concurrence matérielle, fuseau horaire |
| Stockage & Cookies | 10 | localStorage, sessionStorage, cookies, quota de stockage |
| CSS & Media Queries | 10 | Schéma de couleurs, HDR, mouvement réduit, couleurs forcées |
| Réseau & WebRTC | 3 | Sonde TURN, RTT de connexion, version de l'app |
| Bot Detection | 15 | Flag webdriver, frameworks d'automatisation, eval length |
| Détection d'altération | 8 | Introspection des getters de propriétés, chaînes de prototypes, intégrité des fonctions natives |
| Extensions personnalisées | 14 | Empreinte mathématique, détection d'architecture, fonctionnalités WASM |
Le pipeline de collecte s'exécute en quatre étapes afin de minimiser le blocage du thread principal :
Étape 1 (Immédiate) : signaux haute priorité rapides à collecter (propriétés navigator, écran, fuseau horaire). La sonde TURN démarre également ici car elle s'exécute en parallèle.
Étape 2 (Idle Callback) : signaux synchrones qui bénéficient d'une période d'inactivité (media queries CSS, sondes de stockage, tests de cookies).
Étape 3 (Async) : signaux nécessitant des API asynchrones ou du rendu (canvas, WebGL, empreinte audio, détection de polices, rendu des emoji).
Web Worker : collecte de signaux isolée dans un thread dédié (détection des fonctionnalités WASM, doNotTrack).
Une iframe cachée partagée est créée une seule fois et réutilisée par plusieurs collecteurs (emoji, MathML, couleurs système, polices, cadre d'écran) afin d'éviter le surcoût lié à la création d'iframes séparées par signal.
Chaque signal suit une structure cohérente :
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Codes de statut :
| Code | Signification |
|---|---|
0 | Succès |
-1 | Non disponible (propriété undefined) |
-2 | Vérification secondaire échouée |
-3 | Comportement inattendu |
-4 | Timeout |
-5 | Désactivé |
-6 | Bloqué par CSP |
-7 | Erreur de sécurité |
Les signaux collectés sont sérialisés en JSON, puis chiffrés et compressés avant transmission :
Sérialisation JSON : toutes les valeurs de signaux sont regroupées dans un objet JSON indexé par signal, plus des champs de métadonnées (c pour la clé API, t pour le tag, lid pour le linked ID).
Compression : si le payload dépasse 1024 octets, il est compressé avec CompressionStream("deflate-raw").
Chiffrement XOR : le payload est enveloppé dans une enveloppe de chiffrement :
Encodage Base64 : le payload chiffré est encodé en Base64url et envoyé comme corps du POST.
La requête est envoyée à l'endpoint d'ingress avec des paramètres de requête pour la version du client et la clé API. Les credentials CORS sont inclus pour envoyer les cookies first-party.
Le serveur reçoit le payload chiffré et le traite à travers plusieurs sous-systèmes :
Le serveur décode l'enveloppe XOR, décompresse si nécessaire et parse les données de signaux JSON. Le code de statut et la valeur de chaque signal sont extraits et validés.
Le visitor ID est calculé selon une approche de hachage hiérarchisé (V3) :
Tier 1 (Frozen): 20 base62 characters - Stable hardware signals that rarely change - Canvas, WebGL renderer, audio fingerprint, fonts - Provides long-term visitor identity
Tier 2 (Semi-stable): 10 base62 characters - Signals that change with browser updates - User-Agent data, Client Hints, plugins - Extensible without breaking Tier 1
Tier 3 (Volatile): 10 base62 characters - Signals that change frequently - Screen resolution, timezone, language - Used for confidence scoring, not identityChaque tier extrait ses signaux désignés, construit une chaîne canonique et la hache avec MurmurHash3-x64-128. Les trois hashes de tiers sont concaténés et encodés en base62 pour produire le visitor ID final.
Le score de confiance (0.0 à 1.0) indique à quel point le système est certain que ce visiteur a été correctement identifié :
_vid_t correspond, la confiance est maximale.Le moteur de détection des bots exécute plusieurs détecteurs dont les sorties pondérées se combinent en un score de bot (seuils : bot ≥ 0.70, suspicious ≥ 0.30 ; un signal à échec forcé impose un verdict de bot). Les détecteurs contributeurs incluent :
Les signaux d'enrichissement côté serveur sont calculés à partir des données de signaux brutes et de l'IP intelligence. Ils incluent la détection VPN/proxy/Tor, la géolocalisation IP, l'analyse d'altération du navigateur et le suspect scoring.
Le sous-système d'IP intelligence fournit :
Le serveur renvoie une réponse JSON contenant :
{ "visitorId": "X7fh2Hg9LkMn3pQr", "bot": { "detected": false, "confidence": 2, "reasons": [] }}C'est le résultat auquel tracio.getResult() se résout dans le navigateur. L'événement
complet et enrichi — incluant le bot_result canonique
(human / bot / uncertain), la géolocalisation et les smart signals — est
livré côté serveur via les webhooks et affiché dans le
tableau de bord.
Le client stocke un token de visiteur à la fois dans un cookie first-party (expiration 365 jours, SameSite=Lax) et dans localStorage pour la persistance entre les sessions.
| Étape | Emplacement | Durée | Description |
|---|---|---|---|
| 1 | Navigateur | ~5ms | Initialiser l'agent, créer l'iframe partagée |
| 2 | Navigateur | ~50-150ms | Collecter 130+ signaux (parallèle, multi-phases) |
| 3 | Navigateur | ~5ms | Chiffrer et compresser le payload |
| 4 | Réseau | ~10-50ms | POST vers le serveur |
| 5 | Serveur | ~5-20ms | Déchiffrer, extraire les signaux, calculer le visitor ID |
| 6 | Serveur | ~5-15ms | Exécuter la bot detection et les smart signals |
| 7 | Serveur | ~5ms | Construire la réponse |
| 8 | Réseau | ~10-50ms | Renvoyer la réponse JSON |
| 9 | Navigateur | ~1ms | Stocker le cookie de visiteur |
Aller-retour total : généralement 80-300ms selon les conditions réseau et les capacités du navigateur.