Camoufox config schema¶
Ghostvault is built on Camoufox, a patched Firefox
binary that spoofs browser fingerprints at the C++ level. Camoufox reads its spoofing
configuration from a properties.json schema shipped next to the binary — every key in
that file corresponds to a fingerprint surface the browser can fake.
This page is the authoritative reference for every config key you can pass to a
Ghostvault account via device_config={...} in gv_create_account /
gv_update_account_config. If a key isn't listed here, Camoufox will reject it at launch.
Where the schema comes from¶
Ghostvault loads the schema once at import time in
src/ghostvault/browser/fingerprint_schema.py. The loader:
- First tries to read
properties.jsonfrom the installed Camoufox binary (~/Library/Caches/camoufox/...on macOS,~/.cache/camoufox/...on Linux). - Falls back to an inlined snapshot of 107 keys (Camoufox 0.4.x) if the binary
isn't present — e.g. running unit tests in CI without
camoufox[geoip]installed.
This means a future Camoufox release that adds keys is picked up automatically — no Ghostvault code change required.
The schema is exposed to the rest of Ghostvault as three symbols:
| Symbol | Type | Purpose |
|---|---|---|
ALL_CONFIG_KEYS |
dict[str, str] |
Every key → its Camoufox type tag |
KEY_GROUPS |
dict[str, list[str]] |
Domain (navigator, screen, webgl, …) → list of keys |
validate_config() |
callable |
Type-check a user dict; raises on unknown keys |
Type tags¶
Each key carries one of these type tags. validate_config() checks them when you call
gv_create_account / gv_update_account_config — type mismatches are returned as
warnings (non-fatal, since Camoufox itself does the final enforcement at launch).
| Tag | Python type | Notes |
|---|---|---|
str |
str |
Strings (UA, locale, GPU renderer, …) |
int |
int |
Signed integer |
uint |
int |
Unsigned — negatives are flagged |
double |
float or int |
JSON numbers |
bool |
bool |
True/False |
array |
list or tuple |
e.g. font lists, language arrays |
dict |
dict |
e.g. WebGL parameter maps |
Booleans are ints in Python
Because bool is a subclass of int in Python, validate_config() explicitly
rejects True/False for keys tagged uint or int. Pass a real integer.
How to pass config keys¶
Use the device_config argument on gv_create_account or gv_update_account_config.
The value is a plain dict of {config_key: value} pairs:
The keys you pass override anything from a device_profile template — see
Device profile templates for how the two interact.
Validation behavior¶
- Unknown key →
gv_create_accountreturns an error and the account is not created. - Wrong type → returned in the
consistency_warningslist (non-fatal). Camoufox does the authoritative check at launch and will reject a malformed value then. - Negative
uint→ also a warning (e.g."screen.width: expected uint (non-negative), got -1").
The response from gv_create_account echoes the resolved device_config and lists any
consistency_warnings so you can verify what was applied.
The full key reference¶
The 107 keys below are grouped by domain, exactly as Ghostvault's KEY_GROUPS classifies
them. This is the complete set of fingerprint surfaces Camoufox 0.4.x can spoof.
Navigator — 17 keys¶
The navigator.* surface. Most of these are also auto-generated by BrowserForge from the
account's os, but you can pin them explicitly for full control.
| Key | Type | What it sets |
|---|---|---|
navigator.userAgent |
str | Full User-Agent string |
navigator.doNotTrack |
str | DNT header value ("1", "0", "unspecified") |
navigator.appCodeName |
str | Usually "Mozilla" |
navigator.appName |
str | Usually "Netscape" |
navigator.appVersion |
str | App version string |
navigator.oscpu |
str | OS/CPU string (e.g. "Intel Mac OS X 10.15") |
navigator.language |
str | Primary language (e.g. "en-US") |
navigator.languages |
array | Full language list (e.g. ["en-US", "en"]) |
navigator.platform |
str | Platform string (e.g. "MacIntel") |
navigator.hardwareConcurrency |
uint | Logical CPU core count |
navigator.product |
str | Usually "Gecko" |
navigator.productSub |
str | Usually "20100101" |
navigator.maxTouchPoints |
uint | Touch points (0 = desktop, 10 = touch) |
navigator.cookieEnabled |
bool | Cookies enabled flag |
navigator.globalPrivacyControl |
bool | GPC signal |
navigator.buildID |
str | Browser build id |
navigator.onLine |
bool | navigator.onLine flag |
Screen — 10 keys¶
| Key | Type | What it sets |
|---|---|---|
screen.availHeight |
uint | Available screen height (minus taskbar/dock) |
screen.availWidth |
uint | Available screen width |
screen.availTop |
uint | Top of available area |
screen.availLeft |
uint | Left of available area |
screen.height |
uint | Full screen height |
screen.width |
uint | Full screen width |
screen.colorDepth |
uint | Color depth (24, 30) |
screen.pixelDepth |
uint | Pixel depth (matches colorDepth) |
screen.pageXOffset |
double | Page X scroll offset |
screen.pageYOffset |
double | Page Y scroll offset |
Window — 12 keys¶
| Key | Type | What it sets |
|---|---|---|
window.scrollMinX |
int | Min horizontal scroll |
window.scrollMinY |
int | Min vertical scroll |
window.scrollMaxX |
int | Max horizontal scroll |
window.scrollMaxY |
int | Max vertical scroll |
window.outerHeight |
uint | Outer window height |
window.outerWidth |
uint | Outer window width |
window.innerHeight |
uint | Inner viewport height |
window.innerWidth |
uint | Inner viewport width |
window.screenX |
int | Window X position |
window.screenY |
int | Window Y position |
window.history.length |
uint | History stack length |
window.devicePixelRatio |
double | DPR (1.0, 1.25, 1.5, 2.0) |
Document body — 4 keys¶
| Key | Type | What it sets |
|---|---|---|
document.body.clientWidth |
uint | Body client width |
document.body.clientHeight |
uint | Body client height |
document.body.clientTop |
uint | Body client top |
document.body.clientLeft |
uint | Body client left |
HTTP headers — 3 keys¶
| Key | Type | What it sets |
|---|---|---|
headers.User-Agent |
str | Outgoing UA header |
headers.Accept-Language |
str | Accept-Language header |
headers.Accept-Encoding |
str | Accept-Encoding header |
WebRTC IP — 4 keys¶
Real local/external IPs the browser reports via RTCPeerConnection. Setting these lets
you pin the WebRTC identity (or use fake values when blocking WebRTC entirely isn't an
option).
| Key | Type | What it sets |
|---|---|---|
webrtc:ipv4 |
str | Public IPv4 |
webrtc:ipv6 |
str | Public IPv6 |
webrtc:localipv4 |
str | Local IPv4 |
webrtc:localipv6 |
str | Local IPv6 |
Use the WebRTC gate instead
For most use cases you want the block_webrtc advanced flag (see
Environment variables → GHOSTVAULT_BLOCK_WEBRTC_STRATEGY) rather than
hand-pinning IPs. The gate fully disables WebRTC, eliminating the leak surface.
Battery — 4 keys¶
The Battery Status API surface. Laptops report a battery; desktops should leave these
absent (see Consistency checker).
| Key | Type | What it sets |
|---|---|---|
battery:charging |
bool | Plugged in? |
battery:chargingTime |
double | Seconds until full (0 = full or unknown) |
battery:dischargingTime |
double | Seconds until empty (Infinity when charging) |
battery:level |
double | Charge level, 0.0–1.0 |
Fonts — 2 keys¶
| Key | Type | What it sets |
|---|---|---|
fonts |
array | List of installed font family names |
fonts:spacing_seed |
uint | Seed for font metric noise (anti-canvas-font fingerprint) |
Geolocation — 3 keys¶
| Key | Type | What it sets |
|---|---|---|
geolocation:latitude |
double | Latitude |
geolocation:longitude |
double | Longitude |
geolocation:accuracy |
double | Accuracy in meters |
Timezone + locale — 5 keys¶
These are usually easier to set via the locale / timezone advanced flags (which feed
the right keys under the hood), but you can pin them directly too.
| Key | Type | What it sets |
|---|---|---|
timezone |
str | IANA timezone (e.g. "America/New_York") |
locale:language |
str | ISO language |
locale:region |
str | ISO region |
locale:script |
str | ISO script (e.g. "Latn") |
locale:all |
str | Full locale tag |
Humanize + cursor — 4 keys¶
Prefer the humanize policy
Ghostvault exposes its own 3-layer humanize policy for managing these per-account. Only set the raw Camoufox keys when you know what you're doing.
| Key | Type | What it sets |
|---|---|---|
humanize |
bool | Camoufox's own cursor humanization |
humanize:maxTime |
double | Max seconds for a cursor move |
humanize:minTime |
double | Min seconds for a cursor move |
showcursor |
bool | Whether the cursor is rendered |
AudioContext — 3 keys¶
The AudioContext fingerprint surface — sample rate is one of the strongest
audio fingerprint signals.
| Key | Type | What it sets |
|---|---|---|
AudioContext:sampleRate |
uint | Sample rate (44100 or 48000 are most common) |
AudioContext:outputLatency |
double | Output latency |
AudioContext:maxChannelCount |
uint | Max audio channels |
WebGL / WebGL2 — 15 keys¶
The WebGL surface is one of the most probed by bot detectors. Vendor + renderer are the keys you'll touch most; the parameter dicts let you spoof the full GL capability table.
| Key | Type | What it sets |
|---|---|---|
webGl:renderer |
str | GPU renderer string (e.g. "Apple M2 Pro") |
webGl:vendor |
str | GPU vendor (e.g. "Apple Inc.") |
webGl:supportedExtensions |
array | List of supported GL extensions |
webGl2:supportedExtensions |
array | WebGL2 extensions |
webGl:parameters |
dict | GL parameter overrides |
webGl:parameters:blockIfNotDefined |
bool | Block parameters not in the dict |
webGl2:parameters |
dict | WebGL2 parameter overrides |
webGl2:parameters:blockIfNotDefined |
bool | Block undefined WebGL2 parameters |
webGl:shaderPrecisionFormats |
dict | Shader precision overrides |
webGl:shaderPrecisionFormats:blockIfNotDefined |
bool | Block undefined formats |
webGl2:shaderPrecisionFormats |
dict | WebGL2 shader precision overrides |
webGl2:shaderPrecisionFormats:blockIfNotDefined |
bool | Block undefined formats |
webGl:contextAttributes |
dict | Context attributes |
webGl2:contextAttributes |
dict | WebGL2 context attributes |
Canvas — 2 keys¶
| Key | Type | What it sets |
|---|---|---|
canvas:aaOffset |
int | Anti-alias offset (-50..50) |
canvas:aaCapOffset |
bool | Cap the AA offset |
Speech voices — 4 keys¶
| Key | Type | What it sets |
|---|---|---|
voices |
array | List of SpeechSynthesisVoice names |
voices:blockIfNotDefined |
bool | Block voices not in the list |
voices:fakeCompletion |
bool | Fake voice synthesis completion |
voices:fakeCompletion:charsPerSecond |
double | Fake synthesis speed |
Media devices — 4 keys¶
Counts reported by navigator.mediaDevices.enumerateDevices(). These are a strong
hardware tell — a real MacBook reports 3 mics / 1 webcam / 2 speakers.
| Key | Type | What it sets |
|---|---|---|
mediaDevices:micros |
uint | Microphone count |
mediaDevices:webcams |
uint | Webcam count |
mediaDevices:speakers |
uint | Speaker count |
mediaDevices:enabled |
bool | Whether media devices are exposed at all |
Binary behavior flags — 6 keys¶
These change Camoufox's launch behavior rather than a JS-visible surface. Most users won't need them.
| Key | Type | What it sets |
|---|---|---|
allowMainWorld |
bool | Allow main-world script access |
forceScopeAccess |
bool | Force scoped access mode |
enableRemoteSubframes |
bool | Enable remote subframes |
disableTheming |
bool | Disable browser theming |
memorysaver |
bool | Memory-saver mode |
addons |
array | Paths to extracted Firefox addon dirs |
Certificates — 2 keys¶
| Key | Type | What it sets |
|---|---|---|
certificatePaths |
array | Paths to certificate files |
certificates |
array | Inline certificate data |
Other — 1 key¶
| Key | Type | What it sets |
|---|---|---|
pdfViewerEnabled |
bool | navigator.pdfViewerEnabled flag |
debug |
bool | Camoufox debug logging (counts as the 107th key) |
Removing keys later¶
To undo a key you previously set, pass reset_device_keys to
gv_update_account_config. The browser must be closed — the launcher only re-reads
the fingerprint bundle on the next gv_open_account.
Related pages¶
- Device profile templates — pre-built bundles of these keys for real hardware (MacBook, ThinkPad, …)
- Fingerprint consistency — how Ghostvault flags impossible combinations
- All environment variables — the global
GHOSTVAULT_*config