8.6 KiB
Runtime
OBSCURA_ALLOW_PRIVATE_NETWORK
Allow fetches to loopback (127.0.0.0/8), RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), and link-local (169.254.0.0/16, including the 169.254.169.254 cloud-metadata endpoint) addresses. The deny-set also covers the unspecified address (0.0.0.0 / ::), IPv6 unique-local (fc00::/7), and any IPv4-mapped form of the above. Off by default to block SSRF.
The guard validates at DNS-resolution time as well as on literal hosts, so a public hostname that resolves to a forbidden address is rejected at connect time (DNS-rebinding safe), not just hosts written as raw IPs.
Truthy values: 1, true, yes, on.
OBSCURA_ALLOW_PRIVATE_NETWORK=1 obscura fetch http://localhost:8080
Per-process equivalent: --allow-private-network on any subcommand.
OBSCURA_NAV_TIMEOUT_MS
Hard ceiling on a single navigation. Default 30000 (30 seconds). Applies to Page.navigate and the CLI fetch command.
OBSCURA_NAV_TIMEOUT_MS=60000 obscura serve
OBSCURA_NAV_CHAIN_LIMIT
How many documents a navigation chain may load, the first navigation included. Default 10, which allows the requested document and nine navigations the page itself triggers via location assignments or form submissions. Raise the value for an endpoint that chains longer for good reasons, such as an SSO handover across several providers. The low default is what stops a page that resets location on every load.
A zero is raised to 1. This loads the requested document. If the page wants to chain further afterwards, the call reports an error, as at any other limit. A value the engine does not read as a number is replaced by the default. This also applies to a negative value and to a value with a trailing space.
The time budget is not tied to this limit. A longer chain usually also needs a higher OBSCURA_NAV_TIMEOUT_MS, because its default of 30 seconds applies to the whole chain and not to the individual document.
OBSCURA_NAV_CHAIN_LIMIT=20 obscura serve
OBSCURA_SCRIPT_DEADLINE_MS
Soft deadline for the complete page script-execution phase, including classic scripts and ES modules. Default 30000 (30 seconds). Raise it for a heavy SPA whose initial module is responsible for mounting an otherwise empty document. The engine also uses this value as a hard V8 watchdog budget, with a one-second grace period, so a synchronous script cannot run forever.
OBSCURA_SCRIPT_DEADLINE_MS=60000 obscura serve
OBSCURA_MODULE_BUDGET_MS
Per-module graph-loading and evaluation budget for modules that enhance an already-rendered page. Default 3000 (3 seconds). Raise it when a module such as the Vite HMR client legitimately needs longer to evaluate:
OBSCURA_MODULE_BUDGET_MS=10000 obscura serve
This shorter budget applies when the document body already contains more than 50 descendant nodes, where modules are normally progressive enhancement and should not delay navigation indefinitely. For an unmounted SPA shell, Obscura instead gives each module the full OBSCURA_SCRIPT_DEADLINE_MS budget so the app has time to mount. Module network requests remain independently bounded by OBSCURA_FETCH_TIMEOUT_MS.
OBSCURA_CDP_COMMAND_TIMEOUT_MS
Per-command deadline for the CDP server. A hung page (a runaway Runtime.evaluate, a synchronous DOM op) is terminated after this budget so one bad session cannot hold the shared V8 lock and stall the others. Default 60000 (60 seconds); 0 disables it. Navigation self-bounds via OBSCURA_NAV_TIMEOUT_MS well under this.
OBSCURA_CDP_COMMAND_TIMEOUT_MS=30000 obscura serve
OBSCURA_CDP_TOKEN
Bearer token for the CDP discovery and WebSocket endpoints. It is optional on
loopback. A non-loopback bind is refused unless this is set to at least 32
bytes. Pass it as Authorization: Bearer <token> in the CDP client's headers.
OBSCURA_CDP_TOKEN="$(openssl rand -hex 32)" obscura serve --host 0.0.0.0
OBSCURA_FETCH_TIMEOUT_MS
Request timeout for scripted fetch(), XMLHttpRequest, and ES-module loads. Without it a request to a server that accepts the connection but never responds (including a CORS preflight) hangs forever and the XHR is stuck with no completion event. Default 30000 (30 seconds).
OBSCURA_FETCH_TIMEOUT_MS=15000 obscura serve
OBSCURA_PROXY
Default proxy URL used by obscura-worker for the parallel scrape command when no --proxy flag is set.
OBSCURA_PROXY=http://proxy.example.com:8080 obscura scrape - < urls.txt
Stealth and identity
These tune the browser identity the engine presents so it stays internally consistent. See Configure stealth and proxies for the full picture.
OBSCURA_BLOCK_TRACKERS
Controls the tracker blocklist used by the stealth HTTP transport. It is on by
default so --stealth retains its current privacy-first behavior. Set it to
0, false, no, or off to keep the stealth TLS/browser fingerprint while
allowing tracker requests.
The setting is read when a stealth client is created. Values are case-insensitive and surrounding whitespace is ignored; unset, empty, and unrecognized values keep blocking enabled. Non-stealth transport settings and SSRF protection are unchanged.
OBSCURA_BLOCK_TRACKERS=0 obscura --stealth fetch https://example.com
OBSCURA_TIMEZONE
Pins the process timezone before V8/ICU reads it, so Date (getTimezoneOffset, toString) and Intl.DateTimeFormat report one consistent zone. Default Europe/Berlin. Set it to match the exit IP's region.
OBSCURA_TIMEZONE=America/New_York obscura serve
OBSCURA_GEOLOCATION
Override the coordinates the navigator.geolocation shim reports, as lat,lon. Without it the shim reports a fixed default. Keep it consistent with OBSCURA_TIMEZONE and the proxy region.
OBSCURA_GEOLOCATION="40.7128,-74.0060" obscura serve
OBSCURA_PROFILE
Pin a specific browser profile from the built-in pool by index (0-based). Each profile keeps navigator.platform, userAgentData, the UA string, and the GPU renderer internally consistent. Without it a single stable profile is used.
OBSCURA_PROFILE=2 obscura serve
OBSCURA_ROTATE_PROFILE
Opt into picking a random profile per browser context instead of the stable default. Leave it off when you pin a TLS fingerprint, proxy region, or timezone, since a rotated profile would no longer match those.
OBSCURA_ROTATE_PROFILE=1 obscura serve
MCP
OBSCURA_MCP_ALLOWED_ORIGINS
Comma-separated Origin allowlist for the HTTP MCP transport (obscura mcp --http). Browser requests are refused by default; when set, only listed origins are accepted. Native, non-browser MCP clients (which send no Origin) are always allowed.
OBSCURA_MCP_ALLOWED_ORIGINS="https://app.example.com" obscura mcp --http --host 0.0.0.0
OBSCURA_MCP_TOKEN
Bearer token for MCP HTTP requests. It is optional on loopback. A non-loopback bind is refused unless this is set to at least 32 bytes.
OBSCURA_MCP_TOKEN="$(openssl rand -hex 32)" obscura mcp --http --host 0.0.0.0
Logging
RUST_LOG
Standard tracing filter. Common settings:
RUST_LOG=obscura=info obscura serve
RUST_LOG=obscura=debug obscura serve
RUST_LOG=obscura_cdp=trace,obscura_browser=debug obscura serve
--verbose on the CLI is equivalent to RUST_LOG=obscura=info.
Build
OPENSSL_NO_VENDOR
Forces cargo build to use the system OpenSSL instead of compiling the vendored copy. Set to 1 on hosts where the vendored OpenSSL fails (older VPS with AVX-512 issues).
OPENSSL_NO_VENDOR=1 cargo build --release --features render
V8
V8 flags are passed via --v8-flags, not environment variables:
obscura --v8-flags "--max-old-space-size=2048 --expose-gc" serve
Defaults are --max-old-space-size=4096 --max-semi-space-size=4 --optimize-for-size on 64-bit systems. In the current V8, --optimize-for-size overrides the requested semi-space cap to 1 MiB, not 4 MiB. The old-generation ceiling remains 4 GB.
User flags are appended after the defaults, but V8 applies flag implications afterwards. To change the young-generation cap, also disable size optimization, for example obscura --v8-flags "--no-optimize-for-size --max-semi-space-size=8" serve. This can reduce GC CPU at the cost of more memory; measure the complete workload before adopting it. Use --v8-flags "--print-flag-values" to inspect the effective settings after V8 initialization.
HTTP proxy environment
Obscura does not honor HTTP_PROXY / HTTPS_PROXY / NO_PROXY. Use --proxy or OBSCURA_PROXY.