How to Run Cloakserve CDP Multiplexer with Per-Connection Fingerprint Seeds

Cloakserve rewrites Chrome DevTools Protocol URLs to embed unique fingerprint seeds per connection, enabling deterministic browser fingerprinting by accepting a fingerprint query parameter that injects the seed into WebSocket paths.

Cloakserve is the CDP multiplexer that ships with CloakBrowser, acting as a transparent proxy between automation clients and Chrome instances. By parsing per-connection fingerprint seeds from incoming requests, it allows each WebSocket connection to receive a deterministic, unique browser identity without spawning separate Chrome processes.

Understanding Fingerprint Seed Architecture

The multiplexer intercepts standard Chrome debugging endpoints (e.g., ws://127.0.0.1:9222/devtools/browser/…) and modifies the returned JSON to include connection-specific identifiers. According to the CloakHQ/CloakBrowser source code, this transformation happens at the WebSocket level, where a seed value drives the human-interaction layer (mouse movements, keyboard timing, hardware concurrency) to produce reproducible fingerprints.

The system operates through two primary mechanisms:

  • Per-connection seeds: Extracted from HTTP query parameters (?fingerprint=<seed>) via parse_connection_params
  • Default global seeds: Set via command-line arguments (--fingerprint=<seed>) parsed by parse_cli_args

Parsing Connection Parameters

The parse_connection_params function in tests/test_cloakserve.py (lines 31-66) handles the extraction of query-string parameters from client requests. When a client connects to http://localhost:9222?fingerprint=12345, this function:

  1. Parses the query string for a fingerprint key
  2. Stores the value as a seed for URL rewriting
  3. Builds additional Chrome flags from other fingerprint-related parameters (proxy, timezone, locale)

Without an explicit seed parameter, the system falls back to the global default configured at startup.

Starting the Multiplexer

Launch Cloakserve using the cloakserve binary found in bin/cloakserve. The executable wires together parse_cli_args, initializes an aiohttp server, and forwards filtered arguments to Chrome.


# Start with default port 9222 and visible Chrome window

cloakserve --port=9222 --headless=false

The parse_cli_args function (defined in tests/test_cloakserve.py, lines 84-112) consumes the --fingerprint=<seed> flag as a default seed. This guarantees that connections omitting query parameters still receive deterministic fingerprints:


# Apply seed 9999 to all connections without explicit query params

cloakserve --port=9222 --fingerprint=9999

Connecting Clients with Unique Seeds

Each client identifies itself by appending ?fingerprint=<seed> to the HTTP endpoint. The multiplexer rewrites the returned DevTools URLs to embed the seed in the path structure:

  • Without seed: ws://host:9222/devtools/browser/<guid>
  • With seed: ws://host:9222/fingerprint/12345/devtools/browser/<guid>

Request distinct fingerprints by varying the query string:


# Session A with seed 111

curl http://localhost:9222?fingerprint=111

# Session B with seed 222  

curl http://localhost:9222?fingerprint=222

Separate browser tabs or automation scripts can therefore request different platform signatures, GPU vendors, and hardware concurrency values simply by changing the seed value, while sharing a single Chrome binary instance managed by the ChromePool in cloakbrowser/browser.py.

Configuring Per-Connection Chrome Flags

Beyond seeds, Cloakserve accepts additional fingerprint-modifying parameters via query string. As implemented in cloakbrowser/human/config.py, these parameters translate into Chrome command-line flags at connection time:


# Combine fingerprint seed with proxy and locale settings

curl "http://localhost:9222?fingerprint=123&proxy=http://myproxy:8080&locale=fr-FR"

The parse_connection_params function aggregates these options alongside the seed value, ensuring each connection receives a tailored Chrome launch configuration without affecting other active sessions.

Key Implementation Files

Path Role
bin/cloakserve Executable entry point that initializes the aiohttp server and wires argument parsing
tests/test_cloakserve.py Contains parse_connection_params (lines 31-66) and parse_cli_args (lines 84-112) logic
cloakbrowser/config.py Global configuration schema including default_seed entries
cloakbrowser/human/config.py Per-connection fingerprint options mapped to Chrome flags
cloakbrowser/browser.py ChromePool implementation for spawning Chrome instances

Summary

  • Cloakserve acts as a CDP multiplexer that injects fingerprint seeds into WebSocket URLs returned to clients
  • Use ?fingerprint=<seed> in HTTP requests to assign specific seeds to individual connections
  • Set global defaults with --fingerprint=<seed> when launching the multiplexer to handle connections without explicit parameters
  • The parse_connection_params function in tests/test_cloakserve.py extracts seeds and builds Chrome flag lists from query strings
  • URL rewriting transforms standard DevTools endpoints to include /fingerprint/<seed>/ paths, enabling deterministic fingerprinting per connection

Frequently Asked Questions

How does Cloakserve handle connections without a fingerprint parameter?

If a client connects without specifying ?fingerprint=<seed>, Cloakserve falls back to the default seed provided via the --fingerprint command-line argument parsed by parse_cli_args. If no default is configured, the system assigns seeds according to the logic defined in cloakbrowser/config.py, ensuring every connection maintains deterministic fingerprinting behavior.

Can different connections use different proxy or locale settings simultaneously?

Yes. The parse_connection_params function processes multiple query parameters concurrently. Each connection can specify unique combinations of fingerprint, proxy, locale, and timezone parameters, with the multiplexer translating these into isolated Chrome command-line flags for that specific WebSocket session without affecting other active connections.

Where does the URL rewriting logic reside?

The URL transformation logic that converts ws://host:9222/devtools/browser/<guid> to ws://host:9222/fingerprint/<seed>/devtools/browser/<guid> is exercised in tests/test_cloakserve.py under the TestURLRewriting test cases. The production implementation handles this rewrite when returning the JSON list of available DevTools pages to the client.

What is the relationship between fingerprint seeds and the ChromePool?

The ChromePool class in cloakbrowser/browser.py manages Chrome instance spawning. When a client connects with a specific fingerprint seed, the multiplexer communicates that seed and associated flags to the pool, which launches or reuses a Chrome process configured with those specific parameters. This allows multiple connections with different seeds to share Chrome infrastructure while maintaining isolated fingerprint identities.

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 →