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 300+ 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 300+ segnali distinti del browser organizzati in livelli. La raccolta utilizza una pipeline multi-fase con Web Worker e iframe condivisi per le prestazioni.
L'agente include 303 segnali distribuiti su 15 categorie:
| Categoria | Segnali | Categoria | Segnali |
|---|---|---|---|
| Navigator | 67 | Audio | 12 |
| Tamper | 56 | Privacy | 12 |
| Bot | 26 | Display | 11 |
| Canvas | 22 | Fonts | 11 |
| CSS | 18 | Network | 11 |
| Crypto | 15 | Storage | 11 |
| Persistence | 14 | Behavioral | 4 |
| Intl | 13 |
Canvas copre WebGL e WebGPU al pari del rendering 2D; Tamper è la seconda categoria per dimensione perché riconoscere un ambiente modificato richiede più sonde che leggerne uno intatto.
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 a un visitatore noto, la confidenza è massima.Il motore di rilevamento dei bot esegue più rilevatori e combina i loro output ponderati in un punteggio bot; un segnale hard-fail impone da solo un verdetto bot. Il valore pubblico bot.score è su scala 0..100 e il verdetto arriva come bot.result. Le soglie esatte non vengono pubblicate: una soglia che si può leggere è una soglia su cui ci si può tarare. I rilevatori che contribuiscono includono:
I rilevatori di strumentazione (Frida), root/jailbreak e app clonate esistono nella piattaforma, ma i loro slot di input sono solo nativi: l'agente browser non li raccoglie, quindi non contribuiscono a un verdetto web. Vedi Rilevamento dei bot per ciò che è pienamente attivo sul web.
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": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "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, è leggibile tramite la
Server API 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 | Descrizione |
|---|---|---|
| 1 | Browser | Inizializza l'agente, crea l'iframe condiviso |
| 2 | Browser | Raccoglie 300+ segnali (in parallelo, multi-fase) |
| 3 | Browser | Crittografa e comprime il payload |
| 4 | Rete | POST al server |
| 5 | Server | Decrittografa, estrae i segnali, calcola l'ID visitatore |
| 6 | Server | Esegue il rilevamento dei bot e gli smart signal |
| 7 | Server | Costruisce la risposta |
| 8 | Rete | Restituisce la risposta JSON |
| 9 | Browser | Memorizza il cookie del visitatore |
Round-trip totale: millisecondi. È la raccolta dei segnali a occuparne la maggior parte — i passaggi di rete e il lavoro lato server pesano meno — e varia con il dispositivo e la connessione del visitatore. Nulla di tutto ciò blocca il rendering della pagina: l'agente si carica in modo asincrono e ogni controllo potenzialmente lento è limitato da un proprio timeout.