TRACIO ist ein Client-Server-Identifizierungssystem. Der Client erfasst Browser-Signale und sendet sie an den Server, der einen stabilen Besucher-Identifikator berechnet, Erkennungsalgorithmen ausführt und angereicherte Ergebnisse zurückgibt. Dieser Abschnitt erläutert jede Stufe der 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)Wenn tracio.getResult() aufgerufen wird, erfasst der Client 300+ verschiedene Browser-Signale, die in Tiers organisiert sind. Die Erfassung nutzt eine mehrphasige Pipeline mit Web Workern und gemeinsam genutzten iframes für die Performance.
Der Agent liefert 303 Signale in 15 Kategorien:
| Kategorie | Signale | Kategorie | Signale |
|---|---|---|---|
| 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 deckt WebGL und WebGPU ebenso ab wie das 2D-Rendering; Tamper ist die zweitgrößte Kategorie, weil das Erkennen einer veränderten Umgebung mehr Proben erfordert als das Auslesen einer unveränderten.
Die Erfassungs-Pipeline läuft in vier Stufen, um das Blockieren des Main-Threads zu minimieren:
Stufe 1 (Sofort): Hochpriorisierte Signale, die schnell zu erfassen sind (Navigator-Eigenschaften, Screen, Zeitzone). Die TURN-Probe startet ebenfalls hier, da sie nebenläufig ausgeführt wird.
Stufe 2 (Idle Callback): Synchrone Signale, die von einer Leerlaufphase profitieren (CSS-Media-Queries, Storage-Probes, Cookie-Tests).
Stufe 3 (Async): Signale, die asynchrone APIs oder Rendering erfordern (Canvas, WebGL, Audio-Fingerprint, Schrifterkennung, Emoji-Rendering).
Web Worker: Isolierte Signalerfassung in einem dedizierten Thread (WASM-Feature-Erkennung, doNotTrack).
Ein gemeinsam genutzter versteckter iframe wird einmal erstellt und von mehreren Collectors wiederverwendet (Emoji, MathML, Systemfarben, Schriftarten, Screen-Frame), um den Overhead separater iframes pro Signal zu vermeiden.
Jedes Signal folgt einer einheitlichen Struktur:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Statuscodes:
| Code | Bedeutung |
|---|---|
0 | Erfolg |
-1 | Nicht verfügbar (Eigenschaft undefined) |
-2 | Sekundärprüfung fehlgeschlagen |
-3 | Unerwartetes Verhalten |
-4 | Timeout |
-5 | Deaktiviert |
-6 | Durch CSP blockiert |
-7 | Sicherheitsfehler |
Erfasste Signale werden zu JSON serialisiert, dann vor der Übertragung verschlüsselt und komprimiert:
JSON-Serialisierung: Alle Signalwerte werden in ein JSON-Objekt gepackt, nach Signal geschlüsselt, plus Metadatenfelder (c für API-Schlüssel, t für Tag, lid für Linked-ID).
Kompression: Überschreitet die Payload 1024 Bytes, wird sie mit CompressionStream("deflate-raw") komprimiert.
XOR-Verschlüsselung: Die Payload wird in einen Verschlüsselungsumschlag gewickelt:
Base64-Kodierung: Die verschlüsselte Payload wird Base64url-kodiert und als POST-Body gesendet.
Die Anfrage wird an den Ingress-Endpunkt mit Query-Parametern für Client-Version und API-Schlüssel gesendet. CORS-Credentials werden einbezogen, um First-Party-Cookies zu senden.
Der Server empfängt die verschlüsselte Payload und verarbeitet sie durch mehrere Subsysteme:
Der Server dekodiert den XOR-Umschlag, dekomprimiert bei Bedarf und parst die JSON-Signaldaten. Statuscode und Wert jedes Signals werden extrahiert und validiert.
Die Besucher-ID wird mit einem Tiered-Hashing-Ansatz (V3) berechnet:
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 identityJeder Tier extrahiert seine zugewiesenen Signale, baut einen kanonischen String auf und hasht ihn mit MurmurHash3-x64-128. Die drei Tier-Hashes werden verkettet und in base62 kodiert, um die finale Besucher-ID zu erzeugen.
Der Konfidenzwert (0.0 bis 1.0) gibt an, wie sicher das System ist, dass dieser Besucher korrekt identifiziert wurde:
_vid_t-Cookie mit einem bekannten Besucher überein, ist die Konfidenz maximal.Die Bot-Erkennungs-Engine führt mehrere Detektoren aus und kombiniert deren gewichtete Ausgaben zu einem Bot-Score; ein Hard-Fail-Signal erzwingt für sich allein ein Bot-Verdikt. Der öffentliche bot.score ist ein Wert von 0..100, und das Verdikt erreicht Sie als bot.result. Genaue Schwellenwerte werden nicht veröffentlicht — ein Schwellenwert, den man lesen kann, ist ein Schwellenwert, auf den man sich einstellen kann. Zu den beitragenden Detektoren gehören:
Detektoren für Instrumentierung (Frida), Root/Jailbreak und geklonte Apps existieren in der Plattform, aber ihre Eingabe-Slots sind rein nativ — der Browser-Agent erfasst sie nicht, sodass sie zu einem Web-Verdikt nicht beitragen. Siehe Bot-Erkennung für das, was im Web vollständig aktiv ist.
Serverseitige Anreicherungssignale werden aus den Rohsignaldaten und der IP-Intelligence berechnet. Dazu gehören VPN-/Proxy-/Tor-Erkennung, IP-Geolokalisierung, Browser-Tampering-Analyse und Suspect-Scoring.
Das IP-Intelligence-Subsystem stellt bereit:
Der Server gibt eine JSON-Antwort zurück, die Folgendes enthält:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "bot": { "detected": false, "confidence": 2, "reasons": [] }}Dies ist das Ergebnis, zu dem tracio.getResult() im Browser auflöst. Das
vollständige, angereicherte Ereignis — einschließlich des kanonischen bot_result
(human / bot / uncertain), der Geolokalisierung und der Smart Signals — wird
serverseitig über Webhooks zugestellt, ist über die
Server API lesbar und wird im Dashboard angezeigt.
Der Client speichert ein Besucher-Token sowohl in einem First-Party-Cookie (365 Tage Gültigkeit, SameSite=Lax) als auch in localStorage zur Persistenz über Sitzungen hinweg.
| Schritt | Ort | Beschreibung |
|---|---|---|
| 1 | Browser | Agent initialisieren, gemeinsamen iframe erstellen |
| 2 | Browser | 300+ Signale erfassen (parallel, mehrphasig) |
| 3 | Browser | Payload verschlüsseln und komprimieren |
| 4 | Netzwerk | POST an den Server |
| 5 | Server | Entschlüsseln, Signale extrahieren, Besucher-ID berechnen |
| 6 | Server | Bot Detection und Smart Signals ausführen |
| 7 | Server | Antwort erstellen |
| 8 | Netzwerk | JSON-Antwort zurückgeben |
| 9 | Browser | Besucher-Cookie speichern |
Gesamter Round-Trip: Millisekunden. Die Signalerfassung dominiert ihn — die Netzwerkwege und die serverseitige Arbeit sind der kleinere Teil — und er hängt vom Gerät und der Verbindung des Besuchers ab. Nichts davon blockiert das Rendering der Seite: Der Agent lädt asynchron, und jede Prüfung, die langsam sein kann, ist durch ein eigenes Timeout begrenzt.