TRACIO เป็นระบบระบุตัวตนแบบ client-server ไคลเอนต์จะเก็บสัญญาณของเบราว์เซอร์แล้วส่งไปยังเซิร์ฟเวอร์ ซึ่งจะคำนวณตัวระบุผู้เยี่ยมชมที่เสถียร รันอัลกอริทึมการตรวจจับ และส่งผลลัพธ์ที่ถูกเสริมข้อมูลกลับมา ส่วนนี้จะอธิบายแต่ละขั้นตอนของ 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)เมื่อมีการเรียก tracio.getResult() ไคลเอนต์จะเก็บสัญญาณของเบราว์เซอร์ที่แตกต่างกันมากกว่า 300 สัญญาณ ซึ่งจัดระเบียบไว้เป็น tier การเก็บใช้ pipeline แบบหลายเฟสร่วมกับ Web Worker และ iframe ที่ใช้ร่วมกันเพื่อประสิทธิภาพ
เอเจนต์ให้บริการ 300+ สัญญาณใน 15 หมวดหมู่:
| หมวดหมู่ | สัญญาณ | หมวดหมู่ | สัญญาณ |
|---|---|---|---|
| Tamper | 82 | Fonts | 15 |
| Navigator | 72 | Network | 15 |
| Bot | 32 | Persistence | 14 |
| Canvas | 26 | Intl | 13 |
| CSS | 19 | Audio | 12 |
| Privacy | 17 | Storage | 12 |
| Crypto | 16 | Behavioral | 5 |
| Display | 15 |
Canvas ครอบคลุมทั้ง WebGL และ WebGPU เท่า ๆ กับการเรนเดอร์ 2D ส่วน Tamper เป็นหมวดหมู่ที่ใหญ่ที่สุด เพราะการตรวจให้รู้ว่าสภาพแวดล้อมถูกดัดแปลงนั้นต้องใช้การตรวจสอบมากกว่าการอ่านสภาพแวดล้อมที่ไม่ถูกดัดแปลง
Pipeline การเก็บสัญญาณทำงานเป็นสี่ขั้นตอนเพื่อลดการบล็อก main thread ให้น้อยที่สุด:
ขั้นตอนที่ 1 (Immediate): สัญญาณที่มีความสำคัญสูงและเก็บได้รวดเร็ว (คุณสมบัติของ navigator, screen, timezone) TURN probe ก็เริ่มทำงานที่นี่เช่นกันเพราะรันแบบคู่ขนาน
ขั้นตอนที่ 2 (Idle Callback): สัญญาณแบบ synchronous ที่ได้ประโยชน์จากช่วงที่ว่าง (CSS media query, storage probe, cookie test)
ขั้นตอนที่ 3 (Async): สัญญาณที่ต้องใช้ API แบบ asynchronous หรือการเรนเดอร์ (canvas, WebGL, audio fingerprint, การตรวจจับฟอนต์, emoji rendering)
Web Worker: การเก็บสัญญาณแบบแยกอิสระใน thread เฉพาะ (การตรวจจับฟีเจอร์ WASM, doNotTrack)
iframe ที่ซ่อนไว้และใช้ร่วมกันจะถูกสร้างขึ้นเพียงครั้งเดียวและนำกลับมาใช้ซ้ำโดย collector หลายตัว (emoji, MathML, สีของระบบ, ฟอนต์, screen frame) เพื่อหลีกเลี่ยง overhead ของการสร้าง iframe แยกต่อสัญญาณ
สัญญาณทุกตัวมีโครงสร้างที่สอดคล้องกัน:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Status code:
| Code | Meaning |
|---|---|
0 | Success |
-1 | Not available (property undefined) |
-2 | Secondary check failed |
-3 | Unexpected behavior |
-4 | Timeout |
-5 | Disabled |
-6 | CSP blocked |
-7 | Security error |
สัญญาณที่เก็บได้จะถูก serialize เป็น JSON จากนั้นเข้ารหัสและบีบอัดก่อนการส่ง:
JSON serialization: ค่าของสัญญาณทั้งหมดจะถูกแพ็กลงในออบเจ็กต์ JSON โดยใช้สัญญาณเป็น key พร้อมกับฟิลด์ metadata (c สำหรับ API key, t สำหรับ tag, lid สำหรับ linked ID)
การบีบอัด: หาก payload มีขนาดเกิน 1024 ไบต์ จะถูกบีบอัดด้วย CompressionStream("deflate-raw")
XOR Encryption: payload จะถูกห่อหุ้มไว้ในซองการเข้ารหัส:
Base64 encoding: payload ที่เข้ารหัสแล้วจะถูกเข้ารหัสแบบ Base64url และส่งเป็น POST body
คำขอจะถูกส่งไปยัง ingress endpoint พร้อม query parameter สำหรับเวอร์ชันของไคลเอนต์และ API key โดยมีการรวม CORS credentials ไว้ด้วยเพื่อส่ง first-party cookie
เซิร์ฟเวอร์รับ payload ที่เข้ารหัสไว้และประมวลผลผ่านหลาย subsystem:
เซิร์ฟเวอร์ถอดรหัสซอง XOR คลายการบีบอัดเมื่อจำเป็น และ parse ข้อมูลสัญญาณ JSON status code และค่าของสัญญาณแต่ละตัวจะถูกสกัดออกมาและตรวจสอบความถูกต้อง
Visitor ID คำนวณโดยใช้แนวทาง tiered hashing (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 identityแต่ละ tier จะสกัดสัญญาณที่กำหนดไว้ สร้าง string แบบ canonical แล้ว hash ด้วย MurmurHash3-x64-128 hash ของทั้งสาม tier จะถูกนำมาต่อกันและเข้ารหัสเป็น base62 เพื่อสร้าง visitor ID สุดท้าย
Confidence score (0.0 ถึง 1.0) บ่งบอกว่าระบบมั่นใจแค่ไหนว่าผู้เยี่ยมชมรายนี้ถูกระบุตัวตนอย่างถูกต้อง:
_vid_t ตรงกับผู้เยี่ยมชมที่ระบบรู้จักอยู่แล้ว ค่า confidence จะสูงสุดเอนจิน bot detection รัน detector หลายตัวและรวมผลลัพธ์แบบถ่วงน้ำหนักของแต่ละตัวเข้าเป็นคะแนนบอต โดยสัญญาณ hard-fail เพียงอย่างเดียวก็กำหนดผลตัดสินว่าเป็นบอตได้ ค่าที่เปิดเผยต่อสาธารณะคือ bot.score ซึ่งเป็นสเกล 0..100 และผลตัดสินจะส่งถึงคุณในชื่อ bot.result ระบบไม่เปิดเผยค่า threshold ที่แน่นอน เพราะ threshold ที่อ่านได้ก็คือ threshold ที่ปรับตัวเข้าหาได้ detector ที่มีส่วนร่วมได้แก่:
detector สำหรับ instrumentation (Frida), root/jailbreak และแอปที่ถูกโคลนนั้นมีอยู่ในแพลตฟอร์ม แต่ช่องรับข้อมูลของ detector เหล่านี้เป็นแบบเนทีฟเท่านั้น เอเจนต์ฝั่งเบราว์เซอร์ไม่ได้เก็บข้อมูลดังกล่าว จึงไม่มีผลต่อผลตัดสินบนเว็บ ดูสิ่งที่ทำงานได้เต็มรูปแบบบนเว็บได้ที่ การตรวจจับบอต
สัญญาณเสริมข้อมูลฝั่งเซิร์ฟเวอร์คำนวณจากข้อมูลสัญญาณดิบและ IP intelligence ซึ่งรวมถึงการตรวจจับ VPN/proxy/Tor, การระบุตำแหน่งทางภูมิศาสตร์ของ IP, การวิเคราะห์การดัดแปลงเบราว์เซอร์ และ suspect scoring
Subsystem IP intelligence ให้บริการ:
เซิร์ฟเวอร์ส่ง JSON response กลับมาโดยมีเนื้อหา:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "bot": { "detected": false, "confidence": 2, "reasons": [] }}นี่คือผลลัพธ์ที่ tracio.getResult() resolve ออกมาในเบราว์เซอร์ ส่วน
event ฉบับเต็มที่ถูกเสริมข้อมูล — รวมถึง bot_result แบบ canonical
(human / bot / uncertain), geolocation และ smart signal — จะถูก
ส่งฝั่งเซิร์ฟเวอร์ผ่าน webhook อ่านได้ผ่าน
Data API และแสดงใน dashboard
ไคลเอนต์จัดเก็บ visitor token ทั้งใน first-party cookie (หมดอายุ 365 วัน, SameSite=Lax) และใน localStorage เพื่อความคงอยู่ข้ามเซสชัน
| ขั้นตอน | ตำแหน่ง | คำอธิบาย |
|---|---|---|
| 1 | เบราว์เซอร์ | เริ่มต้นเอเจนต์ สร้าง iframe ที่ใช้ร่วมกัน |
| 2 | เบราว์เซอร์ | เก็บสัญญาณมากกว่า 300 รายการ (ขนานกัน หลายเฟส) |
| 3 | เบราว์เซอร์ | เข้ารหัสและบีบอัด payload |
| 4 | เครือข่าย | POST ไปยังเซิร์ฟเวอร์ |
| 5 | เซิร์ฟเวอร์ | ถอดรหัส แยกสัญญาณ คำนวณ visitor ID |
| 6 | เซิร์ฟเวอร์ | รัน bot detection และ smart signals |
| 7 | เซิร์ฟเวอร์ | สร้าง response |
| 8 | เครือข่าย | ส่ง JSON response กลับ |
| 9 | เบราว์เซอร์ | จัดเก็บคุกกี้ของผู้เยี่ยมชม |
Round-trip ทั้งหมด: อยู่ในระดับมิลลิวินาที โดยส่วนที่ใช้เวลามากที่สุดคือการเก็บสัญญาณ ส่วนการเดินทางผ่านเครือข่ายและงานฝั่งเซิร์ฟเวอร์ใช้เวลาน้อยกว่า และเวลาทั้งหมดขึ้นอยู่กับอุปกรณ์และการเชื่อมต่อของผู้เยี่ยมชม ทั้งหมดนี้ไม่บล็อกการเรนเดอร์หน้าเว็บ เพราะเอเจนต์โหลดแบบอะซิงโครนัส และการตรวจสอบทุกรายการที่อาจใช้เวลานานถูกจำกัดด้วย timeout ของตัวเอง