Skip to content

Device profile templates

Setting 105 individual Camoufox config keys by hand is tedious and error-prone — a single inconsistency (macOS reporting an NVIDIA GPU, a phone screen on a desktop OS, a desktop reporting a battery) is an instant bot tell.

Device profiles solve this. Each profile is a pre-built bundle of ~15 internally consistent config keys describing a specific real-world device: a MacBook Pro M2, a ThinkPad X1 Carbon, a Linux workstation, etc. Pick one and Ghostvault fills in screen size, GPU vendor/renderer, media-device counts, battery level, and audio sample rate all at once.

Profiles live in src/ghostvault/browser/device_profiles.py as the DEVICE_PROFILES dict. The values are drawn from public hardware specs and BrowserForge's fingerprint distribution — meant to be plausible, not a perfect clone of any one serial number.

The 10 profiles

Profile Recommended OS Screen (W×H) DPR GPU Cores Touch Mic/Cam/Speaker
macbook-pro-14-m2 macos 1512×982 2.0 Apple M2 Pro 8 0 3 / 1 / 2
macbook-air-13-m1 macos 1440×900 2.0 Apple M1 8 0 3 / 1 / 2
imac-24 macos 2240×1260 2.0 Apple M3 8 0 3 / 1 / 6
windows-desktop-rtx windows 2560×1440 1.0 NVIDIA RTX 4070 16 0 1 / 1 / 2
thinkpad-x1-carbon windows 1920×1200 1.25 Intel Iris Xe 12 0 2 / 1 / 2
surface-laptop-5 windows 2256×1504 1.5 Intel Iris Xe 8 10 1 / 1 / 2
linux-workstation linux 2560×1440 1.0 AMD Radeon RX 7800 XT 16 0 1 / 0 / 2
dell-xps-13-ubuntu linux 1920×1200 1.25 Mesa Intel Xe (TGL GT2) 8 0 1 / 1 / 2
generic-laptop windows 1366×768 1.0 (unset) 4 0 1 / 1 / 2
headless-server linux 1920×1080 1.0 (unset) 4 0 0 / 0 / 0

Notes on the table:

  • DPR = window.devicePixelRatio. Retina panels are 2.0, scaled Windows laptops are 1.25 / 1.5, unscaled desktops are 1.0.
  • Touch = navigator.maxTouchPoints. The Surface Laptop 5 is the only profile with a touchscreen (10 points).
  • Desktops / all-in-ones (imac-24, windows-desktop-rtx, linux-workstation, headless-server) omit battery keys — reporting a battery on desktop hardware is a tell.
  • The generic-laptop and headless-server profiles leave GPU vendor/renderer unset so BrowserForge/Camoufox fills in something plausible from the OS defaults.

How to use a profile

Pass device_profile=<name> to gv_create_account. When you do, three things happen:

  1. The profile's recommended OS is applied automatically (unless you pass an explicit os= argument).
  2. The profile's config keys are merged into the account's fingerprint bundle.
  3. The consistency checker runs over the result and surfaces any warnings in the consistency_warnings field of the response.
{
  "name": "Work",
  "device_profile": "macbook-pro-14-m2",
  "locale": "en-US",
  "timezone": "America/New_York"
}
await gv.create_account(
    name="Work",
    device_profile="macbook-pro-14-m2",
    locale="en-US",
    timezone="America/New_York",
)
{
  "id": "a913fd57244a",
  "name": "Work",
  "os": "macos",
  "device_profile": "macbook-pro-14-m2",
  "device_config": {
    "screen.width": 1512,
    "screen.height": 982,
    "webGl:vendor": "Apple Inc.",
    "webGl:renderer": "Apple M2 Pro",
    "mediaDevices:micros": 3,
    "...": "..."
  },
  "consistency_warnings": []
}

Notice the os defaulted to macos because that's the recommended OS for the profile.

Overriding individual keys

Profiles are starting points, not straitjackets. Use device_config={...} to override individual keys on top of the profile — your values always win.

This is the recommended pattern for: pinning a specific GPU, customizing the battery level, or adding battery keys to a profile that omits them.

await gv.create_account(
    name="Work",
    device_profile="macbook-pro-14-m2",
    device_config={
        # Pin a different battery state.
        "battery:level": 0.42,
        "battery:charging": True,
        # Report 12 cores instead of the profile's 8.
        "navigator.hardwareConcurrency": 12,
    },
)

Resolution order (highest wins):

device_config override  >  device_profile value  >  BrowserForge/Camoufox default

Switching profiles later

Use gv_update_account_config to switch an existing account to a different profile. The browser must be closed — the launcher only re-reads the bundle on the next open.

await gv.update_account_config(
    account_id,
    device_profile="thinkpad-x1-carbon",
)

Switching the profile replaces the entire device_config section of the bundle with the new profile's values. To preserve a key you previously overrode, pass it again in device_config alongside the new profile.

Which profile should I pick?

Goal Recommended profile
Realistic macOS account (Google / SSO work) macbook-pro-14-m2 or macbook-air-13-m1
Touchscreen / hybrid device surface-laptop-5 (only profile with touch)
Corporate Windows laptop thinkpad-x1-carbon
Gaming / high-end Windows desktop windows-desktop-rtx
Linux developer machine linux-workstation or dell-xps-13-ubuntu
Anonymous scraping (gv_open_ephemeral) headless-server (no media devices, no battery)
Lowest common denominator generic-laptop (most common panel size globally)

Profiles do NOT set locale, timezone, or fonts

Those are intentionally left out of profiles because they're location-dependent and should be set per-account via the locale / timezone advanced flags. See Environment variables for GHOSTVAULT_DEFAULT_LOCALE / GHOSTVAULT_DEFAULT_TIMEZONE to default them globally.