How to Enable TLS Fingerprint Stealth in OmniRoute to Bypass AI Provider Detection

Enable TLS fingerprint stealth in OmniRoute by setting ENABLE_TLS_FINGERPRINT=true, which swaps the default HTTP client for a wreq-js powered client that generates browser-like JA3/JA4 fingerprints.

OmniRoute provides a dedicated TLS fingerprint layer that disguises the TLS handshake of its internal HTTP clients. AI providers increasingly block non-browser traffic by inspecting JA3/JA4 fingerprints—this feature makes OmniRoute appear as a genuine Chrome browser. The implementation resides in open-sse/utils/ and integrates directly into provider-specific services for ChatGPT, Claude, Perplexity, and others.

How TLS Fingerprint Stealth Works in OmniRoute

When ENABLE_TLS_FINGERPRINT is activated, OmniRoute replaces the default undici-based fetcher with a native wreq-js-powered TLS client defined in tlsClient.ts. According to the OmniRoute source code, this client performs several critical impersonation techniques:

  • Chrome 124 JA3/JA4 fingerprints — Generates authentic browser fingerprints matching current Chrome behavior
  • Randomized TLS extension ordering — Uses withRandomTLSExtensionOrder: true to prevent static fingerprint detection
  • Fetch-compatible interface — Returns standard responses that downstream executors consume without modification
  • Configurable proxy chaining — Supports OMNIROUTE_TLS_PROXY_URL with fallback to standard proxy environment variables

The underlying native binding comes from bogdanfinn/tls-client via Koffi, instantiated through provider-specific helpers like chatgptTlsClient.ts and claudeTlsClient.ts in open-sse/services/.

Environment Variables for TLS Stealth Configuration

Variable Purpose Default
ENABLE_TLS_FINGERPRINT Master toggle to enable TLS fingerprint spoofing false
TLS_CLIENT_TIMEOUT_MS Request timeout for TLS client operations FETCH_TIMEOUT_MS (600000ms)
OMNIROUTE_TLS_PROXY_URL Dedicated proxy for TLS client traffic

Important proxy behavior: The native binding does not read HTTPS_PROXY, HTTP_PROXY, or ALL_PROXY directly. These must be explicitly forwarded via OMNIROUTE_TLS_PROXY_URL when using TLS fingerprint mode.

Step-by-Step Setup Instructions

1. Enable the Feature Flag


# .env file or shell export

ENABLE_TLS_FINGERPRINT=true

2. (Optional) Adjust Timeout Settings

The default 600-second timeout accommodates slow providers. Reduce for faster failure detection:

TLS_CLIENT_TIMEOUT_MS=300000   # 5 minutes

3. (Optional) Configure TLS-Specific Proxy

OMNIROUTE_TLS_PROXY_URL=http://my-tls-proxy:3128

4. Restart and Verify


# Using the built-in CLI

omniroute serve --env ENABLE_TLS_FINGERPRINT=true

Once restarted, all provider requests route through the TLS impersonator. Verify by checking logs for tlsClient initialization messages.

Complete Configuration Example


# Core TLS fingerprint configuration

ENABLE_TLS_FINGERPRINT=true
TLS_CLIENT_TIMEOUT_MS=600000

# Optional: dedicated TLS side-car proxy

# OMNIROUTE_TLS_PROXY_URL=https://my-tls-proxy.local:8080

# Standard OmniRoute settings

FETCH_TIMEOUT_MS=600000
LOG_LEVEL=info

Programmatic TLS Client Usage

For custom scripts or extensions, import the TLS client directly from tlsClient.ts:

import { createNativeTlsClient } from '@/open-sse/utils/tlsClient';

const tlsOpts = {
  withRandomTLSExtensionOrder: true,
  proxyUrl: process.env.OMNIROUTE_TLS_PROXY_URL,
  timeoutMs: Number(process.env.TLS_CLIENT_TIMEOUT_MS) || 600000,
};

const fetchWithTls = createNativeTlsClient(tlsOpts);

const resp = await fetchWithTls('https://chat.openai.com/api/auth/session', {
  method: 'GET',
  headers: { 
    Cookie: 'cf_clearance=…; _u=…' 
  },
});

const data = await resp.json();

This pattern mirrors how OmniRoute's internal services—chatgptTlsClient.ts, claudeTlsClient.ts, and perplexityTlsClient.ts—instantiate provider-specific TLS clients.

Key Implementation Files

The TLS fingerprint system spans multiple layers in the OmniRoute codebase:

When to Enable vs. Disable TLS Fingerprinting

Scenario Recommendation
Provider blocks undici with JA3/JA4 detection Enable ENABLE_TLS_FINGERPRINT=true
Maximum performance, trusted network Disableundici is faster with lower overhead
Debugging provider issues Disable temporarily to isolate TLS-related problems
Corporate proxy requiring custom TLS inspection Enable with OMNIROUTE_TLS_PROXY_URL configured

Summary

  • Set ENABLE_TLS_FINGERPRINT=true to activate Chrome-imitating JA3/JA4 fingerprints
  • The TLS client in open-sse/utils/tlsClient.ts replaces undici with wreq-js native bindings
  • Randomized extension ordering and Chrome 124 fingerprints defeat static detection
  • Configure TLS_CLIENT_TIMEOUT_MS and OMNIROUTE_TLS_PROXY_URL for production deployments
  • Provider-specific clients in open-sse/services/ inherit this behavior automatically

Frequently Asked Questions

How do I know if TLS fingerprint stealth is working?

Check OmniRoute startup logs for initialization of tlsClient or wreq-js. Successful requests to protected endpoints (ChatGPT web API, Claude web interface) without 403/429 errors indicate proper fingerprint impersonation. You can also inspect outgoing traffic with Wireshark to verify JA3 hashes match Chrome 124 signatures.

Does TLS fingerprint mode affect request performance?

Yes—native TLS client initialization adds 50-150ms startup overhead per connection pool. However, this cost is negligible compared to provider API latency. For high-throughput scenarios, keep undici (ENABLE_TLS_FINGERPRINT=false) if your providers don't enforce JA3/JA4 checks.

Can I use different proxies for TLS and standard requests?

Absolutely. Set OMNIROUTE_TLS_PROXY_URL for TLS fingerprinted traffic while keeping standard HTTPS_PROXY for other operations. The TLS client only reads its dedicated variable; standard environment proxies are ignored by the native binding.

What happens if the TLS client binary is missing?

OmniRoute downloads the appropriate bogdanfinn/tls-client binary at runtime via tlsClientDownloadDir.ts. If downloads fail, the system falls back to undici with a warning. Ensure your runtime allows outbound HTTPS to GitHub releases or pre-bundle binaries in container images.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →