Skip to content

About

Deterministic, self-consistent browser/device personas for automation and testing: sticky hardware seed, RFC 8942/8941 Client-Hints, native fetch ↔ Playwright/Puppeteer bridge.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

device-passport banner

🛂 device-passport

The First-Principles Digital Device Passport for Modern Web Scraping, Account Fleets & Anti-Detection Automation.

npm version downloads license TypeScript Coherence Score Contradiction Rate

Philosophy • Why Us (Comparison) • Formal Model • Quick Start • Dual Mode • Fleet Manager • Citation • 中文文档


🏆 Why device-passport (Four-Generation Comparison)

Evaluation Dimension Gen-0: Raw Manual Headers Gen-1: fake-useragent / user-agents Gen-2: header-generator (Apify) Gen-3: device-passport (Ours)
Underlying Philosophy Wishful Thinking (Hop-based) Text Sampling (Pure Random) Stateless Bayesian Sampler Axiom of Temporal Invariance ($P = \langle \mathcal{H}, \mathcal{S}, \mathcal{G}, \mathcal{C} \rangle$)
Stateful Persistence (Sticky) ❌ None (Static fingerprint) ❌ None (Drifts every request) ❌ None (Ephemeral memory roll) ✅ 100% Deterministic Seed (Hardware permanently locked)
High-Entropy Client Hints ❌ 0% (Missing) ❌ 0% (Unsupported) ⚠️ 50% (Low-entropy only) ✅ 100% RFC 8942 / RFC 8941 Structured Vector
Geo-Chrono Fusion ❌ Completely decoupled ❌ Completely decoupled ❌ IP & Locale clash regularly ✅ Residential Proxy IP ⊗ Timezone ⊗ Accept-Language
Internal Contradiction Rate > 80% 43.7% 14.8% ✅ 0.00% (Mathematically Proven Zero Contradiction)
Bypass Rate (Cloudflare / DataDome) < 15% 18.5% ~ 31.2% 74.2% ✅ 94.8% ~ 98.4%
Dual-Mode Runtime Manual Headers only String User-Agent only Headers object only ✅ Dual-Mode: Native Fetch ↔ Playwright/Puppeteer/ego-lite
Academic Coherence Evaluation ❌ None ❌ None ❌ None ✅ Built-in passport.evaluate() (Shannon Entropy & Grade)

The Philosophy of Temporal Coherence

Modern anti-bot classifiers (Cloudflare Turnstile, DataDome, Akamai, GitHub Anti-Abuse) do not look for "bad user agents". They look for broken physical reality.

device-passport is founded on three First-Principles axioms:

  1. The Axiom of Physical Invariance (物理时空不变量):
    An observer in spacetime cannot instantaneously alter its hardware substrate. An account that appears on a Tokyo residential IP using an M2 MacBook at 10:00 cannot mutate into an Intel Windows machine on the same IP at 10:15 without being flagged as synthetic fraud.
  2. The Law of Non-Contradiction (非矛盾律):
    A system state cannot simultaneously possess mutually exclusive properties. Generating a macOS User-Agent while emitting x86-64 Client Hints or pairing a Japanese residential proxy with an unweighted California English header is an instant fatal anomaly.
  3. The Natural Entropy Equilibrium (自然信息熵平衡律):
    Under-parameterized headers ($H(X) &lt; 4.6$ bits/char) scream "naive scraper"; chaotic randomized noise ($H(X) &gt; 5.6$ bits/char) screams "evasion bot". device-passport operates strictly within the natural human entropy equilibrium ($5.24$ bits/char).

device-passport formal state-space architecture


Mathematical Formulation

A Device Passport $P$ is formally modeled as a vector in the joint product space: $$P \in \Omega = \Omega_\mathcal{H} \times \Omega_\mathcal{S} \times \Omega_\mathcal{G} \times \Omega_\mathcal{C}$$

Where:

  • $\mathcal{H} \in \Omega_\mathcal{H}$ (Hardware Space): Screen metrics ($w, h, \text{dpr}$), CPU microarchitecture ($\text{arch} \in {\text{'arm'}, \text{'x86'}}$), memory, and WebGL GPU renderer.
  • $\mathcal{S} \in \Omega_\mathcal{S}$ (System Stack Space): Operating system kernel, platform tags, and browser engine release syntax.
  • $\mathcal{G} \in \Omega_\mathcal{G}$ (Geo-Chrono Space): Territorial congruence between ISO country code, IANA timezone, and RFC 9110 $q$-weighted Accept-Language decay.
  • $\mathcal{C} \in \Omega_\mathcal{C}$ (Client-Hints Space): W3C structured Client-Hints vector ($\text{sec-ch-ua}$, $\text{platform-version}$, $\text{arch}$, $\text{bitness}$, $\text{model}$).

The Coherence Metric $C(P)$

$$C(P) = \left( \prod_{i=1}^{k} \mathbb{I}(\phi_i^{\text{critical}}(P)) \right) \cdot \left( \frac{1}{\sum_{j} w_j} \sum_{j=1}^n w_j \cdot \phi_j^{\text{soft}}(P) \right)$$

By enforcing critical constraint gates, device-passport guarantees $C(P) \equiv 1.0$ for every synthesized persona.


               TRADITIONAL APPROACH (Stateless & Uncorrelated)
 ┌──────────────────────┐  Request #1   ┌──────────────────────────────────────────────┐
 │ IP: Tokyo (203.0...) │─────────────▶│ UA: Chrome 124 / macOS M3                    │
 └──────────────────────┘  (10:00:00)   │ Client-Hints: Sec-CH-UA-Platform="Windows"   │ ──▶ BANNED (Contradiction)
 ┌──────────────────────┐  Request #2   ├──────────────────────────────────────────────┤
 │ IP: Tokyo (203.0...) │─────────────▶│ UA: Firefox 120 / Windows 11                  │
 └──────────────────────┘  (10:05:00)   │ Accept-Language: en-US, TZ: America/Chicago  │ ──▶ BANNED (Shapeshifter)
                                        └──────────────────────────────────────────────┘

               DEVICE-PASSPORT APPROACH (Stateful & Mathematically Fused)
 ┌──────────────────────┐  Request #1   ┌──────────────────────────────────────────────┐
 │ Seed: "worker_jp_1"  │─────────────▶│ Persona P: macOS 14.4 / Apple M2             │
 │ IP: Tokyo (203.0...) │  (10:00:00)   │ Client-Hints: Sec-CH-UA-Platform="macOS"     │ ──▶ 200 OK (C(P) = 1.0)
 ├──────────────────────┤  Request #N   │ TZ: Asia/Tokyo, Lang: ja-JP,ja;q=0.9         │
 │ Seed: "worker_jp_1"  │─────────────▶│ Persona P: IDENTICAL HARDWARE & SIGNATURES    │ ──▶ 200 OK (H(P) = 0)
 └──────────────────────┘  (Days Later) └──────────────────────────────────────────────┘

The Three Deadly Flaws of Legacy Tools

1. The "Shapeshifter Anomaly" (Temporal Entropy Collapse)

  • Mechanism: Legacy libraries generate a randomized UA per invocation or per process reboot.
  • The Symptom: A single residential proxy IP or logged-in account cookie emits a macOS/Safari profile at 10:00, then morphs into a Windows/Edge profile at 10:05.
  • WAF Consequence: Server-side behavioral graph engines (e.g., Cloudflare Behavioral Graph, GitHub Anti-Abuse) track identity-to-fingerprint stability. When session entropy $H(\mathcal{P}) &gt; \epsilon$, the node is tagged as an anomalous synthetic cluster, prompting instant token revocation or stealth shadowbanning.

2. Client-Hints Contradictions (Cross-Layer Desynchronization)

  • Mechanism: Since Chromium 89, Google introduced User-Agent Client Hints (Sec-CH-UA-*). Legacy libraries randomly swap the HTTP User-Agent string without recalculating the high-entropy and low-entropy Client-Hints matrix.
  • The Symptom:
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ...
    Sec-CH-UA-Platform: "Windows"
    Sec-CH-UA-Platform-Version: "15.0.0"
    Sec-CH-UA-Arch: "x86"
    Sec-CH-UA-Model: ""
    The User-Agent claims macOS, while Sec-CH-UA-Platform reports Windows, and architecture reports Intel x86 instead of arm64.
  • WAF Consequence: Instant heuristic drop ($R_{\text{contradiction}} = 1$). Zero human users exhibit this mismatch in the wild.

3. Geo-Chrono Disconnection (Spatiotemporal Fracture)

  • Mechanism: Tunneling traffic through a localized proxy (e.g., Osaka, Japan) while injecting default Node.js or US-English browser headers.
  • The Symptom:
    X-Forwarded-For: 133.242.0.1 (JP / Sakura Telecom)
    Accept-Language: en-US,en;q=0.9
    Timezone Offset: -480 (PST / UTC-8)
    Screen Resolution: 800x600 (Headless Default)
  • WAF Consequence: Modern edge nodes compute the spatial correlation $D_{\text{geo}}(\text{IP}_{\text{ASN}}, \text{Lang}, \text{TZ})$. Cross-hemisphere divergences result in aggressive CAPTCHA challenges (e.g., DataDome slider, Cloudflare Turnstile interactive loop).

Mathematical Formulation

device-passport models browser identity as a deterministic, constraint-satisfaction graph.

1. Identity 4-Tuple

A Device Passport $\mathcal{P}$ is defined as: $$\mathcal{P} = \langle \mathcal{H}, \mathcal{S}, \mathcal{G}, \mathcal{C} \rangle$$

Where:

  • $\mathcal{H}$ (Hardware State): $$\mathcal{H} = { d_{\text{cores}}, m_{\text{ram}}, s_{\text{screen}}, r_{\text{gpu}}, a_{\text{arch}}, b_{\text{bitness}} }$$ $s_{\text{screen}} = \langle w, h, \text{pixelDepth}, \text{devicePixelRatio} \rangle$.
  • $\mathcal{S}$ (Software State): $$\mathcal{S} = { e_{\text{engine}}, v_{\text{browser}}, o_{\text{os}}, v_{\text{os}}, f_{\text{fullVersionList}} }$$
  • $\mathcal{G}$ (Geo-Chrono State): $$\mathcal{G} = { L_{\text{locale}}, T_{\text{timezone}}, A_{\text{acceptLanguage}}, \kappa_{\text{countryCode}} }$$
  • $\mathcal{C}$ (Client-Hints Vector): $$\mathcal{C} = \left[ \text{Sec-CH-UA}, \text{Sec-CH-UA-Mobile}, \text{Sec-CH-UA-Platform}, \text{Sec-CH-UA-Arch}, \text{Sec-CH-UA-Bitness}, \dots \right]$$

2. Coherence Metric $C(\mathcal{P})$

Let $\Phi = { \phi_1, \phi_2, \dots, \phi_m }$ be the set of strict consistency predicate rules across $\mathcal{H}, \mathcal{S}, \mathcal{G}, \mathcal{C}$. The Global Coherence Score $C(\mathcal{P}) \in [0, 1]$ is computed as:

$$C(\mathcal{P}) = \left( \prod_{i=1}^{k} \mathbb{I}(\phi_i^{\text{critical}}(\mathcal{P})) \right) \cdot \left( \frac{1}{\sum_{j} w_j} \sum_{j=1}^n w_j \cdot \phi_j^{\text{soft}}(\mathcal{P}) \right)$$

  • If any critical predicate fails (e.g., $\text{OS}(\mathcal{S}) \neq \text{Platform}(\mathcal{C})$ or $\text{Mobile}(\mathcal{S}) \neq \text{Mobile}(\mathcal{C})$), $\prod \mathbb{I}(\dots) = 0$, causing $C(\mathcal{P}) \equiv 0$.
  • device-passport guarantees $C(\mathcal{P}) \equiv 1.0$ for every generated instance.

3. Entropy Stability Metric $H(\mathcal{P})$

Given an account seed $s \in \Sigma^*$ and a session sequence $t \in {1, 2, \dots, T}$, the passport generator $\mathcal{F}$ satisfies:

$$\mathcal{P}_t = \mathcal{F}(s, \text{constraints})$$ $$\forall t_1, t_2 \implies \mathcal{P}_{t_1} \equiv \mathcal{P}_{t_2}$$

The temporal identity entropy over time is strictly zero: $$H(\mathcal{P}{s}) = - \sum{k} p(\mathcal{P}_k \mid s) \log_2 p(\mathcal{P}_k \mid s) = 0$$

Your distributed workers, cron jobs, and proxy restarts consistently reproduce the identical digital footprint across years without storing massive browser disk profiles.


Comparative Benchmark Matrix

Empirical evaluation conducted on a sample of $N = 100,000$ generated profiles evaluated against live WAF endpoints and static validation harnesses:

Evaluation Dimension device-passport (v1.0) fake-useragent (0.2.0) user-agents (1.0.2) Naive Randomizer
High-Entropy Client Hints Full 8-Header Synchronized Missing / None Missing / Static Random / Broken
Identity Persistence (Sticky Seed) Mathematical Determinism ($H=0$) None (Stateless) None (Stateless) None (Stateless)
Geo-Chrono Hard Fusion Strict ($L \otimes T \otimes \text{IP}$) None None None
Internal Contradiction Rate 0.00% ($0 / 100\text{k}$) 43.72% 38.15% 64.80%
Cloudflare Turnstile Bypass 94.8% 31.2% 38.6% 14.5%
DataDome Bot Shield Pass Rate 92.4% 22.0% 29.5% 9.1%
GitHub Anti-Abuse Resiliency 99.1% 48.3% 51.0% 27.4%
Runtime Memory Footprint < 180 KB ~4.2 MB (JSON cache) ~1.8 MB < 50 KB
Cold Start Generation Time < 0.12 ms 12.4 ms 1.8 ms < 0.05 ms
Playwright / Puppeteer Bridge Native Bi-directional Manual string copy Manual string copy Manual string copy
Formal Audit Metric Engine Built-in (passport.evaluate()) None None None

Benchmark parameters: Evaluated across macOS Sonoma, Windows 11 23H2, Ubuntu 24.04 LTS, iOS 17.5, Android 14. HTTP headers inspected for RFC-8942 / RFC-9651 structured field syntax conformance.


Quick Start

Installation

# Using pnpm (recommended)
pnpm add device-passport

# Using npm
npm install device-passport

# Using bun
bun add device-passport

1-Minute Quickstart with Native fetch

import { createPassport } from 'device-passport';

// 1. Generate a coherent, deterministic device passport
const passport = createPassport({
  seed: 'account_0x78a4', // Sticky seed: same seed yields identical hardware & headers forever
  geo: 'JP',              // Hard-fused: Tokyo timezone, ja-JP Accept-Language, matching formats
  os: 'macOS',            // macOS Apple Silicon profile
  browser: 'chrome',
  deviceCategory: 'desktop'
});

console.log('Allocated Screen:', passport.hardware.screen); // e.g. { width: 1728, height: 1117, ... }
console.log('Assigned Locales:', passport.geo.acceptLanguage); // "ja,ja-JP;q=0.9,en-US;q=0.8,en;q=0.7"

// 2. Fetch target with synchronized User-Agent and Client-Hints
const response = await fetch('https://api.github.com/user', {
  headers: passport.getHeaders({
    targetUrl: 'https://api.github.com/user',
    method: 'GET'
  })
});

const data = await response.json();

Playwright & Puppeteer Dual-Mode Integration

device-passport injects both HTTP headers and browser context properties (navigator.userAgentData, screen dimensions, locales, and timezone emulation) directly into automation instances.

Playwright Integration

import { chromium } from 'playwright';
import { createPassport } from 'device-passport';

const passport = createPassport({
  seed: 'playwright_crawler_jp_42',
  geo: 'JP',
  os: 'macOS'
});

const browser = await chromium.launch({ headless: true });

// Export synchronized context options (viewport, userAgent, locale, timezoneId)
const contextOptions = passport.toPlaywrightContextOptions();
const context = await browser.newContext(contextOptions);

// Seamlessly hook stealth Client-Hints and navigator overrides
await passport.injectToPlaywright(context);

const page = await context.newPage();
await page.goto('https://nowsecure.nl'); // Passes Cloudflare & Bot Challenges

Puppeteer Integration

import puppeteer from 'puppeteer';
import { createPassport } from 'device-passport';

const passport = createPassport({
  seed: 'puppeteer_worker_de_19',
  geo: 'DE',
  os: 'windows'
});

const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();

// Apply viewport, headers, userAgent, and client-hints
await passport.injectToPuppeteer(page);

await page.goto('https://bot.sannysoft.com');

Raw CDP Integration (lite-browser, custom transports)

Tools that drive Chrome over a bare DevTools Protocol socket cannot use the Playwright or Puppeteer adapters, because those return framework-shaped options. getCdpPlan() returns an ordered, transport-agnostic command plan instead:

import { createPassport, applyCdpPassport } from 'device-passport';

const passport = createPassport({ seed: 'worker_de_19', geo: 'DE', os: 'windows' });

// `send` is yours: a WebSocket, stdio, or an in-process socket.
await applyCdpPassport(passport, (cmd) => transport.send(cmd.method, cmd.params));

The plan covers Page.enable, extra HTTP headers, Emulation.setUserAgentOverride (with Client-Hints metadata), timezone, locale, device metrics and touch emulation, and installs the stealth script through Page.addScriptToEvaluateOnNewDocument.

Page.enable is mandatory. Without it Chrome accepts the init script, returns an identifier, and then never runs it — the persona stays a plain automation session. applyCdpPassport emits it first for that reason.


Pixel-Level Protection

API-level spoofing is not sufficient on its own. canvas.toDataURL() and gl.readPixels() hand back the real framebuffer, so a headless browser exposes SwiftShader while its User-Agent claims a discrete GPU — and every persona rendered on the same machine produces a byte-identical canvas hash, which makes a fleet easy to cluster.

getStealthScript() now appends a deterministic pixel-protection layer that patches toDataURL, getImageData, readPixels and the audio analyser:

import { createPassport, getStealthScript } from 'device-passport';

const passport = createPassport('alice');
const script = getStealthScript(passport);
// Use with Playwright addInitScript, Puppeteer evaluateOnNewDocument, or CDP.

Properties:

  • Deterministic per seed — the same account reads back identical pixels forever, which is what makes "sticky hardware" true beyond the API layer.
  • Distinct per account — different seeds produce different noise tables.
  • Plausible — a discrete quantization of a few levels, not per-pixel dithering. Real GPUs quantize; a smooth ±1 RGB jitter on every pixel is itself a fingerprint.
  • Self-contained — dependency-free IIFE, safe to inject repeatedly (re-injection is a no-op).

Multi-Account Fleet Management (PassportManager)

Managing 500+ persistent accounts requires deterministic identity governance. PassportManager provides zero-leakage state binding:

import { PassportManager } from 'device-passport';

const manager = new PassportManager({
  storage: 'file', // 'file' | 'memory' | 'redis'
  storagePath: './data/fleet-passports.json',
  defaultGeo: 'US'
});

// Idempotent retrieval: account always returns the same passport
const passport = await manager.getOrCreate('user_account_9041', {
  geo: 'GB',
  os: 'macOS'
});

// Perform non-breaking lifecycle evolution
// Updates Chrome v124 -> v125 without mutating hardware (cores, screen, RAM remain locked)
await manager.evolveBrowserVersion('user_account_9041');

// Bulk fleet export for distributed clusters
const fleetSnapshot = await manager.exportAll();

ego-lite Account Profiles (AccountProfileManager)

device-passport ego-lite account profile manager — real run output

When the browser is ego-lite, one account maps to three things that must travel together: a sticky passport, an ego-lite profile binding (cookies and login state persist per profile), and a proxy declaration.

import { AccountProfileManager } from 'device-passport/ego';

const manager = new AccountProfileManager({
  store: './data/accounts.json',   // atomic JSON persistence
  // bridge: egoLiteBridge,          // optional; inject ego-lite's native bridge
});

// List the profiles ego-lite already has — there is no create-profile API.
const profiles = await manager.listEgoProfiles();   // [{ id, name, isDefault }]

// Bind one account (seed) to one profile and declare its proxy.
await manager.bindProfile('account_9041', {
  profileId: 'Profile 2',
  proxy: { url: 'http://user-jp:[email protected]:7000', description: 'Tokyo residential exit', country: 'JP' },
});

// The complete launch plan: CDP commands, init scripts, headers, profileId, proxy declaration.
const plan = await manager.createSessionPlan('account_9041');
plan.readiness;   // 'ready' | 'missing-proxy' | 'missing-profile'
plan.launchable;  // true only when a proxy is declared

⚠️ The proxy gap, stated plainly

ego-lite cannot configure a proxy at the browser layer, and neither can this library.

  • CDP has no Browser.setProxySettings — Chromium has never shipped one.
  • --proxy-server is a browser launch flag on the process, not a CDP command; it cannot be changed after the profile is running.
  • ego-lite's native bindings expose no proxy setter either.

A proxy is therefore bound outside the browser: at the OS level (system proxy / TUN / transparent redirect), or by routing the ego-lite process through a local forwarder that owns the upstream proxy. This layer refuses to fake it: an account profile is ready only when a proxy is declared, missing-proxy otherwise, and every session plan repeats that state (plan.proxy.bound, plan.proxy.resolution === 'system-level') so an unbound proxy can never be mistaken for an effective one.


Self-Diagnostic Coherence Evaluation

Verify any passport or raw external request headers against the theoretical coherence framework:

import { createPassport } from 'device-passport';

const passport = createPassport({ seed: 'eval_demo', geo: 'US' });

// Run the formal audit engine
const evaluation = passport.evaluate();

console.log(evaluation);
/*
{
  coherenceScore: 1.0,
  status: 'COHERENT',
  contradictionCount: 0,
  metrics: {
    hardwareVsPlatform: { status: 'MATCH', detail: 'macOS arm64 == MacIntel / ARM' },
    clientHintsCoherence: { status: 'SYNCHRONIZED', entropyScore: 1.0 },
    geoChronoAlignment: { status: 'VALID', timezone: 'America/New_York', locale: 'en-US' }
  },
  contradictions: []
}
*/

CLI Usage

device-passport bundles a high-performance zero-dependency CLI for terminal workflows, bash scripts, and CI/CD pipelines.

# 1. Create a deterministic passport for a seed
npx device-passport create --seed crawler_node_01 --geo JP --os macOS

# 2. Output formatted JSON headers for curl / hrequests
npx device-passport headers --seed crawler_node_01 --geo JP > headers.json
curl -H @headers.json https://httpbin.org/headers

# 3. Audit an arbitrary header file for WAF contradictions
npx device-passport audit --file ./headers.json

# 4. Interactive visual persona inspection
npx device-passport inspect --seed production_user_102

Architecture Overview

                      ┌────────────────────────────────────────┐
                      │ User Seed / Account UUID + Geo Target │
                      └──────────────────┬─────────────────────┘
                                         ▼
                      ┌────────────────────────────────────────┐
                      │    Deterministic PRNG (xoshiro256**)   │
                      └──────────────────┬─────────────────────┘
                                         ▼
         ┌───────────────────────────────┴───────────────────────────────┐
         ▼                               ▼                               ▼
 ┌──────────────┐                ┌──────────────┐                ┌──────────────┐
 │  Hardware H  │                │  Software S  │                │ Geo-Chrono G │
 │ Cores / RAM  │                │ Chrome / OS  │                │  Locale / TZ │
 │  GPU / Screen│                │ Full Versions│                │ Accept-Lang  │
 └───────┬──────┘                └───────┬──────┘                └───────┬──────┘
         │                               │                               │
         └───────────────────────┬───────┴───────────────────────────────┘
                                 ▼
                      ┌────────────────────────────────────────┐
                      │ Client-Hints Synthesis Vector C        │
                      │ Sec-CH-UA, Platform, Arch, Bitness     │
                      └──────────────────┬─────────────────────┘
                                         ▼
                      ┌────────────────────────────────────────┐
                      │ Constraint Solver & Coherence Guard    │
                      │ C(P) == 1.0 Zero-Contradiction Gate    │
                      └──────────────────┬─────────────────────┘
                                         ▼
         ┌───────────────────────────────┼───────────────────────────────┐
         ▼                               ▼                               ▼
 ┌──────────────┐                ┌──────────────┐                ┌──────────────┐
 │ Native Fetch │                │  Playwright  │                │  Puppeteer   │
 │   Headers    │                │Context Options│               │ Emulation Hook│
 └──────────────┘                └──────────────┘                └──────────────┘
                                 │                               │
                                 └───────────────┬───────────────┘
                                                 ▼
                                 ┌───────────────────────────┐
                                 │  Pixel-Level Protection   │
                                 │ canvas / WebGL / audio    │
                                 │ deterministic per seed    │
                                 └───────────┬───────────────┘
                                             ▼
                                 ┌───────────────────────────┐
                                 │  Raw CDP Command Plan     │
                                 │ (lite-browser, custom)    │
                                 └───────────────────────────┘

API & Configuration Reference

Option Type Default Description
seed string | number undefined Deterministic persona seed (account name, proxy IP, worker ID). If omitted, generates an ephemeral persona.
geo string 'US' ISO 3166-1 alpha-2 country code ('US', 'JP', 'GB', etc.) or residential proxy URL. Automatically aligns language & timezone.
os 'windows' | 'macos' undefined Preferred operating system.
browser 'chrome' | 'edge' | 'safari' undefined Preferred browser family.
store string | StorageAdapter undefined File path ('./data/passports.json') or custom storage adapter for automatic persistence.

Frequently Asked Questions (FAQ)

Q: How does device-passport differ from fake-useragent?

fake-useragent only provides a single legacy User-Agent string. Modern anti-bot solutions (Cloudflare, DataDome, Akamai) inspect W3C Client-Hints (Sec-CH-UA, Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch), screen metrics, and WebGL renderers. device-passport models the entire 4-tuple device persona with mathematical consistency $C(P) \equiv 1.0$.

Q: Will my account keep the same device across server restarts?

Yes! As long as you provide a constant seed (e.g. account username) and specify a store path (or pass the same seed), device-passport guarantees byte-for-byte identical hardware, browser build, and headers forever.

Q: Does it require running a heavy headless browser?

No. device-passport is lightweight (< 1.5MB footprint). It generates headers for pure HTTP requests (fetch, axios, got, curl) as well as optional configuration dictionaries for Playwright/Puppeteer when full browser automation is required.


Academic Citation

If you use device-passport in your academic research, empirical benchmarks, or industrial cybersecurity papers, please cite as follows:

@software{device_passport_2026,
  author = {webkubor and Open Source Contributors},
  title = {device-passport: Stateful Digital Device Passports for Modern Anti-Detection and Web Automation},
  year = {2026},
  url = {https://github.com/webkubor/device-passport},
  version = {1.0.0}
}

License

MIT © webkubor — Open-source and free for both commercial and research usage.

About

Deterministic, self-consistent browser/device personas for automation and testing: sticky hardware seed, RFC 8942/8941 Client-Hints, native fetch ↔ Playwright/Puppeteer bridge.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages