TRACIO è un sistema di identificazione client-server. Il client raccoglie i segnali del browser e li invia al server, che calcola un identificatore stabile del visitatore, esegue algoritmi di rilevamento e restituisce risultati arricchiti. Questa sezione spiega ogni fase della 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)Quando viene chiamato tracio.getResult(), il client raccoglie 130+ segnali distinti del browser organizzati in livelli. La raccolta utilizza una pipeline multi-fase con Web Worker e iframe condivisi per le prestazioni.
| Categoria | Numero di segnali | Esempi |
|---|---|---|
| Canvas e WebGL | 9 | Fingerprint del canvas, renderer WebGL, parametri WebGL, WebGPU |
| Audio | 3 | Fingerprint di AudioContext, latenza di base, timing DRM |
| Font e rendering | 10 | Rilevamento dei font, preferenze dei font, MathML, rendering delle emoji |
| Navigator e piattaforma | 25 | User-Agent, lingue, schermo, hardware concurrency, fuso orario |
| Storage e cookie | 10 | localStorage, sessionStorage, cookie, quota di storage |
| CSS e media query | 10 | Schema di colori, HDR, movimento ridotto, colori forzati |
| Rete e WebRTC | 3 | Probe TURN, RTT della connessione, versione dell'app |
| Bot Detection | 15 | Flag webdriver, framework di automazione, lunghezza di eval |
| Rilevamento manomissione | 8 | Introspezione dei getter delle proprietà, catene di prototipi, integrità della funzione nativa |
| Estensioni personalizzate | 14 | Fingerprint matematico, rilevamento dell'architettura, funzionalità WASM |
La pipeline di raccolta viene eseguita in quattro fasi per ridurre al minimo il blocco del main thread:
Fase 1 (Immediata): segnali ad alta priorità che sono rapidi da raccogliere (proprietà di navigator, schermo, fuso orario). Anche il probe TURN parte qui poiché viene eseguito in modo concorrente.
Fase 2 (Idle Callback): segnali sincroni che traggono vantaggio da un periodo di inattività (media query CSS, probe dello storage, test dei cookie).
Fase 3 (Async): segnali che richiedono API asincrone o rendering (canvas, WebGL, fingerprint audio, rilevamento dei font, rendering delle emoji).
Web Worker: raccolta isolata dei segnali in un thread dedicato (rilevamento delle funzionalità WASM, doNotTrack).
Un iframe nascosto condiviso viene creato una sola volta e riutilizzato da più collector (emoji, MathML, colori di sistema, font, frame dello schermo) per evitare l'overhead della creazione di iframe separati per ogni segnale.
Ogni segnale segue una struttura coerente:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Codici di stato:
| Codice | Significato |
|---|---|
0 | Successo |
-1 | Non disponibile (proprietà undefined) |
-2 | Controllo secondario fallito |
-3 | Comportamento inatteso |
-4 | Timeout |
-5 | Disabilitato |
-6 | Bloccato da CSP |
-7 | Errore di sicurezza |
I segnali raccolti vengono serializzati in JSON, quindi crittografati e compressi prima della trasmissione:
Serializzazione JSON: tutti i valori dei segnali vengono impacchettati in un oggetto JSON con chiave per segnale, più campi di metadati (c per la chiave API, t per il tag, lid per il linked ID).
Compressione: se il payload supera i 1024 byte, viene compresso usando CompressionStream("deflate-raw").
Crittografia XOR: il payload viene racchiuso in un envelope di crittografia:
Codifica Base64: il payload crittografato viene codificato in Base64url e inviato come corpo del POST.
La richiesta viene inviata all'endpoint di ingress con parametri di query per la versione del client e la chiave API. Le credenziali CORS sono incluse per inviare i cookie di prima parte.
Il server riceve il payload crittografato e lo elabora attraverso diversi sottosistemi:
Il server decodifica l'envelope XOR, decomprime se necessario e analizza i dati JSON dei segnali. Il codice di stato e il valore di ciascun segnale vengono estratti e validati.
L'ID visitatore viene calcolato usando un approccio di hashing a livelli (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 identityOgni livello estrae i segnali a esso designati, costruisce una stringa canonica e la sottopone ad hashing con MurmurHash3-x64-128. I tre hash dei livelli vengono concatenati e codificati in base62 per produrre l'ID visitatore finale.
Il punteggio di confidenza (da 0.0 a 1.0) indica quanto il sistema è certo che questo visitatore sia stato identificato correttamente:
_vid_t corrisponde, la confidenza è massima.Il motore di rilevamento dei bot esegue più rilevatori i cui output ponderati vengono combinati in un punteggio bot (soglie: bot ≥ 0.70, suspicious ≥ 0.30; un segnale hard-fail forza un verdetto bot). I rilevatori che contribuiscono includono:
I segnali di arricchimento lato server vengono calcolati dai dati grezzi dei segnali e dall'IP intelligence. Questi includono il rilevamento di VPN/proxy/Tor, la geolocalizzazione dell'IP, l'analisi della manomissione del browser e il suspect scoring.
Il sottosistema di IP intelligence fornisce:
Il server restituisce una risposta JSON contenente:
{ "visitorId": "X7fh2Hg9LkMn3pQr", "bot": { "detected": false, "confidence": 2, "reasons": [] }}Questo è il risultato a cui tracio.getResult() si risolve nel browser. L'evento
completo e arricchito — incluso il canonico bot_result
(human / bot / uncertain), la geolocalizzazione e gli smart signal — viene
consegnato lato server tramite webhooks ed è visibile nella
dashboard.
Il client memorizza un token del visitatore sia in un cookie di prima parte (scadenza a 365 giorni, SameSite=Lax) sia in localStorage per la persistenza tra le sessioni.
| Passo | Posizione | Durata | Descrizione |
|---|---|---|---|
| 1 | Browser | ~5ms | Inizializza l'agente, crea l'iframe condiviso |
| 2 | Browser | ~50-150ms | Raccoglie 130+ segnali (in parallelo, multi-fase) |
| 3 | Browser | ~5ms | Crittografa e comprime il payload |
| 4 | Rete | ~10-50ms | POST al server |
| 5 | Server | ~5-20ms | Decrittografa, estrae i segnali, calcola l'ID visitatore |
| 6 | Server | ~5-15ms | Esegue il rilevamento dei bot e gli smart signal |
| 7 | Server | ~5ms | Costruisce la risposta |
| 8 | Rete | ~10-50ms | Restituisce la risposta JSON |
| 9 | Browser | ~1ms | Memorizza il cookie del visitatore |
Round-trip totale: tipicamente 80-300ms a seconda delle condizioni di rete e delle capacità del browser.