# Stealth and anonymity

Part of the Oya Browser docs. All of it: https://oyabrowser.com/docs.md

## Anonymity

Create and manage browser profiles with unique fingerprints, proxy routing, and isolated cookie stores. Each profile is a complete identity, different canvas hash, WebGL renderer, navigator properties, and session storage. Switch identities with a single MCP call.

Every browser runs as a persona: a fingerprint, cookie jar and proxy bound together and stable for its life. Rotation means choosing a different persona, never re-rolling one.

### Fingerprint Spoofing

Each profile generates a coherent set of browser fingerprints that are internally consistent per platform. A Win32 profile gets Windows GPU strings, Windows fonts, and matching screen resolutions.

- **Canvas**: deterministic pixel noise on `toDataURL` and `toBlob`
- **WebGL**: spoofed vendor/renderer strings from real GPU database
- **AudioContext**: noise on `OfflineAudioContext.startRendering`
- **ClientRects**: sub-pixel noise on `getBoundingClientRect` (bypassed internally for click accuracy)
- **Navigator**: platform, hardwareConcurrency, deviceMemory, languages, vendor
- **Screen**: width, height, colorDepth, devicePixelRatio
- **WebRTC**: ICE candidates stripped to prevent local IP leak
- **Fonts**: platform-consistent font sets

### Proxy Support

A persona can take an HTTP, HTTPS or SOCKS5 proxy, given as one url. Chromium cannot authenticate to a SOCKS5 proxy, so a proxy that needs a username and password must be HTTP or HTTPS. The proxy is applied at the session level, so all traffic routes through it, including DNS for SOCKS5. Timezone and locale are matched to the proxy's location over CDP, and a mismatch is reported rather than silently shipped.

```
const proxy = await oya.proxies.create({
  url: "http://user:pass@1.2.3.4:8080",
  geo: "us",
  kind: "datacenter",
});

const persona = await oya.personas.create({
  name: "us-desktop",
  prefs: { platform: "Win32", timezone: "America/New_York" },
});
await oya.personas.pinProxy(persona.id, proxy.id);
```

### Anti-Detection Stealth

Always active, no configuration needed. The stealth layer removes automation indicators that anti-bot systems check for:

- `navigator.webdriver` removed
- Electron globals (`window.process`, `window.require`) deleted
- `window.chrome` fixed to match real Chrome (app, runtime, csi, loadTimes)
- `navigator.plugins` populated with PDF viewers
- `navigator.permissions.query` patched
- Sec-CH-UA headers rewritten to hide Electron
- Google telemetry domains blocked at the network level

## Choosing a persona

A persona is made through the API and chosen when a browser starts. There is no tool that switches one mid-session: the device, cookie jar and proxy are bound together for the persona's life, so changing them would make the browser a different machine halfway through a run. To vary the device, clone the persona.

```
const personas = await oya.personas.list();
const browser = await oya.browser.start({ persona: personas[0].id });

// A new device, fixed from here on:
const fresh = await oya.personas.create({ prefs: { platform: "MacIntel" } });

// The same device, a second cookie jar:
const twin = await oya.personas.clone(fresh.id);
```

The console calls this workspace **Profiles**; the API and these docs call it a persona. Same thing.
