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: trueto prevent static fingerprint detection - Fetch-compatible interface — Returns standard responses that downstream executors consume without modification
- Configurable proxy chaining — Supports
OMNIROUTE_TLS_PROXY_URLwith 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:
- [
open-sse/utils/tlsClient.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/tlsClient.ts) — Core wrapper selecting wreq-js and building native options - [
open-sse/services/tlsClientProxy.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/tlsClientProxy.ts) — Service exposing TLS client as internal proxy endpoint - [
open-sse/services/tlsClientDownloadDir.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/tlsClientDownloadDir.ts) — Native binary download management - [
docs/security/STEALTH_GUIDE.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/docs/security/STEALTH_GUIDE.md) — Design documentation for fingerprinting architecture - [
docs/reference/ENVIRONMENT.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/docs/reference/ENVIRONMENT.md) — Complete environment variable reference
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 | Disable — undici 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=trueto activate Chrome-imitating JA3/JA4 fingerprints - The TLS client in
open-sse/utils/tlsClient.tsreplacesundiciwith wreq-js native bindings - Randomized extension ordering and Chrome 124 fingerprints defeat static detection
- Configure
TLS_CLIENT_TIMEOUT_MSandOMNIROUTE_TLS_PROXY_URLfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →