# How OmniRoute's TLS Stealth Fingerprinting Works to Avoid AI Detection

> OmniRoute's TLS stealth fingerprinting crafts browser-identical handshakes, making your traffic undetectable by AI. Avoid AI detection with this advanced routing technique.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: internals
- Published: 2026-08-11

---

**OmniRoute avoids AI provider detection by routing requests through a native TLS client that crafts browser-identical ClientHello handshakes, making traffic indistinguishable from genuine Chrome or Edge browsers.**

OmniRoute is an open-source AI routing proxy that masks its identity using **TLS stealth fingerprinting**. When enabled, it replaces Node.js's distinctive TLS signature with a custom-built handshake that mimics real browser fingerprints. This technique bypasses Cloudflare challenges, bot detectors, and AI-provider rate limits that filter based on JA3 hashes and TLS metadata.

## How TLS Fingerprint Detection Blocks AI Proxies

AI providers and CDN services like Cloudflare analyze the **ClientHello** message sent during TLS negotiation. Standard Node.js applications emit a unique combination of:

- TLS version and cipher suites
- Extension order and supported curves
- JA3 fingerprint hash

These signatures are cataloged by security vendors. When OmniRoute sends a vanilla Node.js `fetch`, detection systems immediately flag it as automated traffic.

## OmniRoute's Stealth Architecture

The stealth system operates through **six coordinated components** controlled by feature flags and provider allow-lists.

### 1. Feature Flag Activation

Stealth mode is gated by `ENABLE_TLS_FINGERPRINT`, defined in [`src/shared/constants/featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/featureFlagDefinitions.ts). The flag must be explicitly set to `"true"`—it defaults off to preserve normal operation.

```bash

# Enable TLS stealth globally

export ENABLE_TLS_FINGERPRINT=true

```

### 2. Provider Targeting with TLS_FINGERPRINT_PROVIDERS

Not all providers require stealth. OmniRoute uses `TLS_FINGERPRINT_PROVIDERS` to filter which upstream services receive masked traffic:

```bash

# Comma-separated list of providers to fingerprint

export TLS_FINGERPRINT_PROVIDERS="claude,grok,perplexity,codex"

```

This allow-list ensures stealth resources are only spent where detection risk exists.

### 3. Native TLS Client Singleton ([`tlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tlsClient.ts))

The core stealth logic lives in [`open-sse/utils/tlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/tlsClient.ts). This file exports a global `TlsClient` instance that wraps the `tls-client-node` binary.

Key responsibilities:

- **Binary lifecycle**: Downloads and caches the native executable on first use
- **Circuit-breaker pattern**: Tracks failure rates and temporarily disables stealth if errors exceed threshold
- **API compatibility**: Exposes `tlsClient.fetch(url, options)` matching standard `fetch` semantics

```typescript
// From open-sse/utils/tlsClient.ts
const tlsClient = new TlsClient();
export const tlsFetch = tlsClient.fetch.bind(tlsClient);

```

When `ENABLE_TLS_FINGERPRINT === "true"`, the singleton initializes `buildNativeTlsClientOptions()` from [`open-sse/services/tlsClientDownloadDir.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/tlsClientDownloadDir.ts) to configure the binary.

### 4. Binary Management ([`tlsClientDownloadDir.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tlsClientDownloadDir.ts))

[`open-sse/services/tlsClientDownloadDir.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/tlsClientDownloadDir.ts) handles platform detection and binary provisioning:

- Detects OS/architecture (Linux x64, macOS ARM64, etc.)
- Downloads pre-compiled `tls-client-node` release if absent
- Writes to deterministic cache directory for reuse
- Exposes `buildNativeTlsClientOptions()` with profile names, proxy URLs, and timeouts

This separation keeps the main codebase portable while delegating low-level TLS crafting to a specialized native tool.

### 5. Provider-Specific Wrappers

Each stealth-enabled provider has a dedicated wrapper in `open-sse/services/`. Examples include:

| Provider | File Path | Profile Constant |
|----------|-----------|------------------|
| Claude | [`claudeTlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/claudeTlsClient.ts) | `CLAUDE_PROFILE` |
| Grok | [`grokTlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/grokTlsClient.ts) | `GROK_PROFILE` |
| Perplexity | [`perplexityTlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/perplexityTlsClient.ts) | `PERPLEXITY_PROFILE` |
| ChatGPT | [`chatgptTlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/chatgptTlsClient.ts) | `CHATGPT_PROFILE` |

These wrappers import `tlsClient.fetch` and bind it to provider-specific configurations:

```typescript
// Simplified from claudeTlsClient.ts
import { tlsFetch } from "../utils/tlsClient";

export function tlsFetchClaude(url: string, options: RequestInit) {
  return tlsFetch(url, {
    ...options,
    tlsProfile: "chrome_120", // JA3 fingerprint matching Chrome 120
    // Additional Claude-specific headers and behavior
  });
}

```

Internal executor code ([`executors/claude-web/transport.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/executors/claude-web/transport.ts)) then calls `tlsFetchClaude` instead of native `fetch`.

### 6. Fallback and Resilience

[`open-sse/utils/proxyFetch.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/proxyFetch.ts) coordinates the decision logic. If any of the following occur:

- `ENABLE_TLS_FINGERPRINT` is disabled
- Provider not in `TLS_FINGERPRINT_PROVIDERS`
- Binary download fails
- Circuit-breaker is open (too many recent failures)

…the request automatically **falls back to standard Node.js fetch**. This graceful degradation ensures service continuity even when stealth is unavailable.

## Complete Configuration Example

```typescript
// Environment setup (equivalent to .env file)
process.env.ENABLE_TLS_FINGERPRINT = "true";
process.env.TLS_FINGERPRINT_PROVIDERS = "claude,grok,perplexity";
// Optional: route binary through corporate proxy
process.env.TLS_CLIENT_PROXY = "http://proxy.example.com:8080";

// Application code
import { tlsFetchClaude } from "open-sse/services/claudeTlsClient";

async function stealthQuery(prompt: string) {
  const response = await tlsFetchClaude(
    "https://claude.ai/api/organizations/[org]/completion",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        prompt,
        model: "claude-3-opus-20240229",
        max_tokens: 4096,
      }),
    }
  );

  return response.json();
}

```

When executed, this produces a **TLS handshake identical to Chrome 120**: same JA3 hash, extension order, cipher suite preferences, and SNI behavior. Detection infrastructure classifies OmniRoute as legitimate browser traffic.

## Circuit-Breaker and Operational Safety

The `TlsClient` class implements a **failure threshold circuit breaker**:

- Successive native binary failures increment an internal counter
- After threshold (configurable, default 5 failures in 60 seconds), circuit **opens**
- Open circuit blocks stealth attempts for backoff period (default 30 seconds)
- Requests during open circuit use standard fetch fallback

This prevents cascading failures from repeatedly spawning a misconfigured or corrupted binary.

## Inbound TLS Capture ([`tlsCapture.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tlsCapture.ts))

For OmniRoute's **TPROXY transparent proxy mode**, [`src/mitm/tproxy/tlsCapture.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/mitm/tproxy/tlsCapture.ts) provides `isTlsClientHello()` to detect TLS handshakes on raw socket streams. This enables:

- TLS termination when OmniRoute sits inline between client and upstream
- Extraction of SNI for routing decisions
- Optional re-encryption with stealth fingerprint on outbound leg

This completes the full proxy pipeline: inbound traffic captured, optionally inspected, then re-emitted with browser-mimicking TLS signatures.

## Summary

- **OmniRoute's TLS stealth fingerprinting** masks Node.js origins by substituting native `fetch` with a custom binary that crafts browser-identical ClientHello messages.
- **Feature flags** (`ENABLE_TLS_FINGERPRINT`, `TLS_FINGERPRINT_PROVIDERS`) provide granular, runtime control over which providers receive stealth treatment.
- **Architecture components**: flag definitions, singleton client, binary downloader, provider wrappers, circuit-breaker, and fallback logic work together in [`open-sse/utils/tlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/tlsClient.ts) and related files.
- **Resilience mechanisms** include automatic fallback to standard fetch and circuit-breaker protection against binary failures.
- **Result**: AI providers see standard browser fingerprints, bypassing JA3-based bot detection and Cloudflare interstitial challenges.

## Frequently Asked Questions

### What is a JA3 fingerprint and why does it matter for AI detection?

A **JA3 fingerprint** is an MD5 hash derived from TLS ClientHello fields including version, cipher suites, and extensions. Security systems maintain allow-lists of "good" browser JA3 signatures and block outliers. Node.js emits a distinctive JA3 that rarely matches browsers, making automated traffic trivial to identify and throttle. OmniRoute's native binary generates JA3 hashes identical to Chrome or Edge, eliminating this detection vector.

### Can I use TLS stealth fingerprinting without downloading external binaries?

No. The `tls-client-node` binary is **required** for stealth operation. The implementation in [`open-sse/services/tlsClientDownloadDir.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/tlsClientDownloadDir.ts) automatically handles download and caching on first use. If the binary cannot be retrieved (air-gapped environments, restricted networks), OmniRoute falls back to standard Node.js fetch without stealth—functionality is preserved but detection risk increases.

### How do I verify that TLS stealth is actually active for my requests?

Check runtime logs at `DEBUG=omni:tls` level. When stealth is engaged, you'll see entries referencing `tls-client-node` spawn, profile selection (e.g., `chrome_120`), and successful JA3 negotiation. Silent fallback to native fetch indicates stealth was bypassed—verify `ENABLE_TLS_FINGERPRINT="true"`, provider is in `TLS_FINGERPRINT_PROVIDERS`, and binary exists in the cache directory returned by [`tlsClientDownloadDir.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tlsClientDownloadDir.ts).

### Does TLS stealth fingerprinting impact request latency?

Yes, with **modest overhead**. The native binary spawn adds 10-50ms per cold-start request; subsequent requests reuse the process pool. Circuit-breaker state and proxy chaining ([`tlsClientProxy.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tlsClientProxy.ts)) add minimal latency. For high-throughput scenarios, monitor [`open-sse/utils/tlsClient.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/tlsClient.ts) metrics and tune connection pooling—native client maintains persistent TLS sessions where possible.