TRACIO is een client-server-identificatiesysteem. De client verzamelt browsersignalen en stuurt ze naar de server, die een stabiele bezoekersidentificator berekent, detectiealgoritmen uitvoert en verrijkte resultaten teruggeeft. In dit hoofdstuk wordt elke fase van de pipeline uitgelegd.
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)Wanneer tracio.getResult() wordt aangeroepen, verzamelt de client 130+ verschillende browsersignalen die in tiers zijn georganiseerd. De verzameling gebruikt een meerfasige pipeline met Web Workers en gedeelde iframes voor de performance.
| Categorie | Aantal signalen | Voorbeelden |
|---|---|---|
| Canvas & WebGL | 9 | Canvas-fingerprint, WebGL-renderer, WebGL-parameters, WebGPU |
| Audio | 3 | AudioContext-fingerprint, base-latency, DRM-timing |
| Fonts & Rendering | 10 | Fontdetectie, fontvoorkeuren, MathML, emoji-rendering |
| Navigator & Platform | 25 | User-Agent, talen, screen, hardware-concurrency, tijdzone |
| Storage & Cookies | 10 | localStorage, sessionStorage, cookies, storage-quota |
| CSS & Media Queries | 10 | Kleurschema, HDR, reduced motion, forced colors |
| Netwerk & WebRTC | 3 | TURN-probe, verbindings-RTT, app-versie |
| Bot Detection | 15 | Webdriver-flag, automatiseringsframeworks, eval-length |
| Tamper Detection | 8 | Property-getter-introspectie, prototypeketens, native-function-integriteit |
| Custom Extensions | 14 | Math-fingerprint, architectuurdetectie, WASM-features |
De verzamelingspipeline draait in vier fasen om het blokkeren van de main thread te minimaliseren:
Fase 1 (Direct): Signalen met hoge prioriteit die snel te verzamelen zijn (navigator-eigenschappen, screen, tijdzone). De TURN-probe start hier ook, aangezien deze gelijktijdig wordt uitgevoerd.
Fase 2 (Idle Callback): Synchrone signalen die profiteren van een inactieve periode (CSS-media-queries, storage-probes, cookie-tests).
Fase 3 (Async): Signalen die asynchrone API's of rendering vereisen (canvas, WebGL, audio-fingerprint, fontdetectie, emoji-rendering).
Web Worker: Geïsoleerde signaalverzameling in een dedicated thread (WASM-featuredetectie, doNotTrack).
Er wordt eenmalig een gedeeld verborgen iframe aangemaakt dat door meerdere collectors wordt hergebruikt (emoji, MathML, systeemkleuren, fonts, screen-frame), om de overhead van het aanmaken van aparte iframes per signaal te vermijden.
Elk signaal volgt een consistente structuur:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Statuscodes:
| Code | Betekenis |
|---|---|
0 | Succes |
-1 | Niet beschikbaar (eigenschap undefined) |
-2 | Secundaire controle mislukt |
-3 | Onverwacht gedrag |
-4 | Timeout |
-5 | Uitgeschakeld |
-6 | Geblokkeerd door CSP |
-7 | Beveiligingsfout |
Verzamelde signalen worden geserialiseerd naar JSON en vervolgens vóór verzending versleuteld en gecomprimeerd:
JSON-serialisatie: Alle signaalwaarden worden verpakt in een JSON-object, gesleuteld per signaal, plus metadatavelden (c voor API-sleutel, t voor tag, lid voor linked ID).
Compressie: Als de payload groter is dan 1024 bytes, wordt deze gecomprimeerd met CompressionStream("deflate-raw").
XOR-versleuteling: De payload wordt in een versleutelingsenvelop verpakt:
Base64-codering: De versleutelde payload wordt Base64url-gecodeerd en als POST-body verzonden.
Het verzoek wordt naar het ingress-endpoint gestuurd met query-parameters voor de client-versie en API-sleutel. CORS-credentials worden meegestuurd om first-party-cookies te verzenden.
De server ontvangt de versleutelde payload en verwerkt deze via verschillende subsystemen:
De server decodeert de XOR-envelop, decomprimeert indien nodig en parseert de JSON-signaaldata. De statuscode en waarde van elk signaal worden geëxtraheerd en gevalideerd.
De bezoekers-ID wordt berekend met een tiered hashing-aanpak (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 identityElke tier extraheert zijn aangewezen signalen, bouwt een canonieke string op en hasht deze met MurmurHash3-x64-128. De drie tier-hashes worden aaneengeschakeld en in base62 gecodeerd om de uiteindelijke bezoekers-ID te produceren.
De confidence-score (0.0 tot 1.0) geeft aan hoe zeker het systeem is dat deze bezoeker correct is geïdentificeerd:
_vid_t-cookie overeenkomt, is de confidence maximaal.De bot-detectie-engine voert meerdere detectoren uit waarvan de gewogen uitkomsten worden gecombineerd tot een bot-score (drempelwaarden: bot ≥ 0.70, suspicious ≥ 0.30; een hard-fail-signaal forceert een bot-verdict). Bijdragende detectoren zijn onder meer:
Server-side verrijkingssignalen worden berekend uit de ruwe signaaldata en IP-intelligence. Deze omvatten VPN-/proxy-/Tor-detectie, IP-geolocatie, browser-tampering-analyse en suspect-scoring.
Het IP-intelligence-subsysteem levert:
De server retourneert een JSON-antwoord met daarin:
{ "visitorId": "X7fh2Hg9LkMn3pQr", "bot": { "detected": false, "confidence": 2, "reasons": [] }}Dit is het resultaat waartoe tracio.getResult() in de browser wordt geresolved. Het
volledige, verrijkte event — inclusief de canonieke bot_result
(human / bot / uncertain), geolocatie en smart signals — wordt
server-side geleverd via webhooks en getoond in het
dashboard.
De client slaat een bezoekers-token op in zowel een first-party-cookie (365 dagen geldig, SameSite=Lax) als localStorage voor persistentie over sessies heen.
| Stap | Locatie | Duur | Beschrijving |
|---|---|---|---|
| 1 | Browser | ~5ms | Agent initialiseren, gedeeld iframe aanmaken |
| 2 | Browser | ~50-150ms | 130+ signalen verzamelen (parallel, meerfasig) |
| 3 | Browser | ~5ms | Payload versleutelen en comprimeren |
| 4 | Netwerk | ~10-50ms | POST naar de server |
| 5 | Server | ~5-20ms | Ontsleutelen, signalen extraheren, bezoekers-ID berekenen |
| 6 | Server | ~5-15ms | Bot detection en smart signals uitvoeren |
| 7 | Server | ~5ms | Antwoord opbouwen |
| 8 | Netwerk | ~10-50ms | JSON-antwoord retourneren |
| 9 | Browser | ~1ms | Bezoekers-cookie opslaan |
Totale round-trip: Doorgaans 80-300ms, afhankelijk van netwerkomstandigheden en browsermogelijkheden.