How to Use Fixed Fingerprint Seeds for Persistent Browser Identity in CloakBrowser
Pass a deterministic --fingerprint=<seed> flag via the args array when calling launchPersistentContext(), and reuse the same userDataDir path across sessions to ensure the browser fingerprint remains identical.
CloakBrowser, the stealth automation library maintained by CloakHQ, generates a random hardware fingerprint for every Chromium launch by default. For workflows requiring consistent browser identity—such as account management or multi-session automation—you must override this randomization with a fixed seed and maintain a persistent profile directory.
How Fingerprint Seeds Work in CloakBrowser
CloakBrowser derives hardware-related fingerprint attributes—including CPU cores, device memory, screen dimensions, and GPU blocklist entries—from a numeric seed passed to the Chromium binary. By default, this seed is randomized on every launch, but the library provides an override mechanism through its argument builder.
Default Random Seed Generation
In js/src/config.ts, the getDefaultStealthArgs() function (lines 8-15) generates a random 5-digit number between 10000 and 99999 using the expression Math.floor(Math.random() * 90000) + 10000. This value is automatically injected into the launch arguments as --fingerprint=<random>, ensuring each browser instance appears distinct unless explicitly overridden.
Overriding Seeds Via CLI Flags
The buildArgs() function in js/src/args.ts (lines 15-22) merges default stealth arguments with user-provided options. It stores arguments in a Map keyed by the flag name (e.g., --fingerprint). Because the loop processes options.args after the default set, any --fingerprint=<num> value you supply replaces the random default. This Map-based deduplication gives user-provided seeds priority, allowing you to enforce deterministic fingerprinting.
Implementing Persistent Browser Identity
To maintain a stable identity across restarts, combine a fixed seed with a persistent profile directory. The launchPersistentContext() function in js/src/playwright.ts (lines 84-100) creates a regular (non-incognito) Chromium profile at the specified userDataDir. When you launch this context repeatedly with the same --fingerprint flag and directory path, the binary receives identical hardware parameters every time, creating a persistent browser identity.
Minimal Fixed-Seed Example
import { launchPersistentContext } from "cloakbrowser";
const PROFILE_DIR = "./my-profile";
const FIXED_SEED = 12345; // Must be between 10000-99999
async function run() {
// Session 1
const ctx1 = await launchPersistentContext({
userDataDir: PROFILE_DIR,
headless: false,
args: [`--fingerprint=${FIXED_SEED}`],
});
const page1 = ctx1.pages()[0] ?? (await ctx1.newPage());
await page1.goto("https://example.com");
await ctx1.close();
// Session 2 - same fingerprint guaranteed
const ctx2 = await launchPersistentContext({
userDataDir: PROFILE_DIR,
headless: false,
args: [`--fingerprint=${FIXED_SEED}`],
});
const page2 = ctx2.pages()[0] ?? (await ctx2.newPage());
await page2.goto("https://example.com");
await ctx2.close();
}
run().catch(console.error);
The same PROFILE_DIR and --fingerprint=12345 combination ensures hardware-related fingerprint values stay constant across both sessions.
Full Persistence with State and Cookies
Adapted from the repository's js/examples/persistent-context.ts, this example demonstrates that cookies, localStorage, and the hardware fingerprint all persist when using a fixed seed:
import { launchPersistentContext } from "../src/index.js";
const PROFILE_DIR = "./my-profile";
const FIXED_SEED = 98765;
// Session 1: Establish state
let ctx = await launchPersistentContext({
userDataDir: PROFILE_DIR,
headless: false,
args: [`--fingerprint=${FIXED_SEED}`],
});
let page = ctx.pages()[0] ?? (await ctx.newPage());
await page.goto("https://example.com");
// Store data
await page.evaluate(() => {
document.cookie = "session=abc123; path=/; max-age=3600";
localStorage.setItem("user", "returning");
});
console.log(`Cookie after Session 1: ${await page.evaluate(() => document.cookie)}`);
await ctx.close();
// Session 2: Verify persistence
ctx = await launchPersistentContext({
userDataDir: PROFILE_DIR,
headless: false,
args: [`--fingerprint=${FIXED_SEED}`],
});
page = ctx.pages()[0] ?? (await ctx.newPage());
await page.goto("https://example.com");
console.log(`Cookie after Session 2: ${await page.evaluate(() => document.cookie)}`);
await ctx.close();
Running both blocks shows identical cookies and localStorage values, confirming that the profile data and fingerprint remained stable across separate launches.
Summary
- Default behavior:
getDefaultStealthArgs()injs/src/config.tsgenerates a random seed between 10000-99999 on every launch. - Fixed seed override: Supply
--fingerprint=<seed>in theargsarray;buildArgs()injs/src/args.tsprioritizes your value over the random default. - Persistence requirement: Use
launchPersistentContext()fromjs/src/playwright.tswith a consistentuserDataDirto store both profile data and the fixed hardware identity. - Optional platform pinning: Add
--fingerprint-platform=windowsor--fingerprint-platform=macosto enforce OS-specific fingerprint consistency across different host machines.
Frequently Asked Questions
What is the valid range for fingerprint seeds?
CloakBrowser expects seeds in the range 10000–99999, matching the 5-digit integer format generated by the default randomizer in js/src/config.ts. While the underlying binary may accept other values, staying within this range ensures compatibility with the internal stealth argument validation.
Can I use fixed seeds with temporary browser contexts?
Fixed seeds work technically with temporary contexts, but they provide limited practical value since temporary sessions discard all data upon closure. To achieve true persistent browser identity, you must combine a fixed seed with launchPersistentContext() and a reusable userDataDir.
How does the fingerprint seed affect hardware properties?
The seed acts as a deterministic input for calculating hardware-related values including CPU core count, device memory, screen size, and GPU configuration. According to the CloakHQ source code, the bundled Chromium binary uses this seed to derive consistent fingerprint parameters that remain identical across every launch using that seed value.
Why does my fingerprint change despite using the same seed?
If the fingerprint varies while using the same --fingerprint flag, verify that you are not inadvertently randomizing platform-specific parameters. Pin the platform explicitly using --fingerprint-platform=windows or --fingerprint-platform=macos in your args array, and ensure no other code is regenerating stealth arguments after your override.
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 →