A TRACIO é um sistema de identificação cliente-servidor. O cliente coleta sinais do navegador e os envia ao servidor, que calcula um identificador de visitante estável, executa algoritmos de detecção e retorna resultados enriquecidos. Esta seção explica cada estágio do 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 tracio.getResult() é chamado, o cliente coleta 300+ sinais distintos de navegador organizados em camadas. A coleta usa um pipeline de múltiplas fases com Web Workers e iframes compartilhados para desempenho.
O agente entrega 303 sinais distribuídos em 15 categorias:
| Categoria | Sinais | Categoria | Sinais |
|---|---|---|---|
| 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 cobre WebGL e WebGPU tanto quanto a renderização 2D; Tamper é a segunda maior categoria porque reconhecer um ambiente modificado exige mais sondagens do que ler um ambiente intacto.
O pipeline de coleta roda em quatro estágios para minimizar o bloqueio da thread principal:
Estágio 1 (Imediato): sinais de alta prioridade que são rápidos de coletar (propriedades de navigator, tela, fuso horário). A sonda TURN também começa aqui, pois roda concorrentemente.
Estágio 2 (Idle Callback): sinais síncronos que se beneficiam de um período ocioso (media queries de CSS, sondas de armazenamento, testes de cookies).
Estágio 3 (Async): sinais que exigem APIs assíncronas ou renderização (canvas, WebGL, impressão digital de áudio, detecção de fontes, renderização de emoji).
Web Worker: coleta de sinais isolada em uma thread dedicada (detecção de recursos WASM, doNotTrack).
Um iframe oculto compartilhado é criado uma vez e reutilizado por múltiplos coletores (emoji, MathML, cores do sistema, fontes, frame de tela) para evitar o custo de criar iframes separados por sinal.
Todo sinal segue uma estrutura consistente:
interface Signal<T> { s: number // Status code v: T // Value (when successful)}Códigos de status:
| Código | Significado |
|---|---|
0 | Sucesso |
-1 | Não disponível (propriedade undefined) |
-2 | Verificação secundária falhou |
-3 | Comportamento inesperado |
-4 | Timeout |
-5 | Desabilitado |
-6 | Bloqueado por CSP |
-7 | Erro de segurança |
Os sinais coletados são serializados em JSON, depois criptografados e comprimidos antes da transmissão:
Serialização JSON: todos os valores de sinais são empacotados em um objeto JSON indexado por sinal, mais campos de metadados (c para chave de API, t para tag, lid para linked ID).
Compressão: se o payload exceder 1024 bytes, ele é comprimido usando CompressionStream("deflate-raw").
Criptografia XOR: o payload é envolvido em um envelope de criptografia:
Codificação Base64: o payload criptografado é codificado em Base64url e enviado como o corpo do POST.
A requisição é enviada ao endpoint de ingress com parâmetros de query para a versão do cliente e a chave de API. As credenciais CORS são incluídas para enviar cookies first-party.
O servidor recebe o payload criptografado e o processa através de vários subsistemas:
O servidor decodifica o envelope XOR, descomprime se necessário e faz o parse dos dados JSON dos sinais. O código de status e o valor de cada sinal são extraídos e validados.
O ID de visitante é calculado usando uma abordagem de hashing em camadas (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 identityCada camada extrai seus sinais designados, constrói uma string canônica e a submete a hash com MurmurHash3-x64-128. Os três hashes das camadas são concatenados e codificados em base62 para produzir o ID de visitante final.
A pontuação de confiança (0.0 a 1.0) indica quão certo o sistema está de que este visitante foi corretamente identificado:
_vid_t corresponder a um visitante conhecido, a confiança é máxima.O engine de detecção de bots executa múltiplos detectores e soma suas saídas ponderadas em uma pontuação de bot; um sinal de falha imediata (hard-fail) define o veredito de bot por si só. O valor público bot.score é uma escala 0..100, e o veredito chega até você como bot.result. Os limiares exatos não são publicados: um limiar que dá para ler é um limiar ao qual dá para se ajustar. Os detectores contribuintes incluem:
Os detectores de instrumentação (Frida), root/jailbreak e app clonado existem na plataforma, mas seus slots de entrada são exclusivamente nativos — o agente de navegador não os coleta, então eles não entram em um veredito na web. Veja Detecção de bots para o que está plenamente ativo na web.
Os sinais de enriquecimento no servidor são calculados a partir dos dados brutos dos sinais e da IP intelligence. Eles incluem detecção de VPN/proxy/Tor, geolocalização de IP, análise de adulteração de navegador e suspect scoring.
O subsistema de IP intelligence fornece:
O servidor retorna uma resposta JSON contendo:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "bot": { "detected": false, "confidence": 2, "reasons": [] }}Este é o resultado para o qual tracio.getResult() resolve no navegador. O
evento completo e enriquecido — incluindo o bot_result canônico
(human / bot / uncertain), geolocalização e smart signals — é
entregue no servidor através de webhooks, pode ser lido pela
Server API e é exibido no dashboard.
O cliente armazena um token de visitante tanto em um cookie first-party (expiração de 365 dias, SameSite=Lax) quanto no localStorage para persistência entre sessões.
| Passo | Local | Descrição |
|---|---|---|
| 1 | Browser | Inicializar agente, criar iframe compartilhado |
| 2 | Browser | Coletar 300+ sinais (paralelo, multifase) |
| 3 | Browser | Criptografar e comprimir payload |
| 4 | Network | POST para o servidor |
| 5 | Server | Descriptografar, extrair sinais, calcular ID de visitante |
| 6 | Server | Executar detecção de bots e smart signals |
| 7 | Server | Construir resposta |
| 8 | Network | Retornar resposta JSON |
| 9 | Browser | Armazenar cookie de visitante |
Round-trip total: milissegundos. A coleta de sinais domina esse tempo — os saltos de rede e o trabalho no servidor são a parte menor — e ele varia conforme o dispositivo e a conexão do visitante. Nada disso bloqueia a renderização da página: o agente carrega de forma assíncrona e cada verificação que pode demorar é limitada pelo próprio timeout.