v1.8.0
jo-inc/camofox-browserv1.8.0Apr 27, 2026by skyfallsin
AI Summary
Adds a global access key for route-level authentication and fixes a critical native memory leak causing orphaned processes.
Key Highlights
- New `CAMOFOX_ACCESS_KEY` environment variable requires authentication on every route except specific exempted endpoints.
- Fixed race condition in `browser.close()` that caused orphaned Firefox child processes to survive.
- Implemented `_forceKillProcessTree()` to clean up orphaned children that escaped the process group.
- Renamed crash reporter to telemetry with improved deduplication and Cloudflare Worker relay.
New Features
- Global access key authentication
- Native memory leak fix
- Crash reporter renamed to telemetry
Full Release Notes
## Global Access Key `CAMOFOX_ACCESS_KEY` env var — by @trader-payne (#586) If you expose camofox beyond loopback — on a VPS, in a Docker network, behind a reverse proxy — you've needed to rely on network-level controls or `CAMOFOX_API_KEY` (which only gates cookie import). There was no single switch to require auth on every route. Set `CAMOFOX_ACCESS_KEY` and every request must carry `Authorization: Bearer <key>`. Three routes are conditionally exempt: - `GET /health` — always open (Docker/Fly healthchecks need it) - `POST /sessions/:userId/cookies` — exempt only when `CAMOFOX_API_KEY` is also set (has its own gate) - `POST /stop` — exempt only when `CAMOFOX_ADMIN_KEY` is also set (has its own gate) If the dedicated key for an exempted route is *not* configured, the access key still gates it — defense-in-depth, no accidentally unprotected endpoints. The access key also works as a superkey on `requireAuth()` routes, so you don't need two tokens in a single request. 401 responses include `WWW-Authenticate: Bearer realm="camofox"` per RFC 7235. Env var values are whitespace-trimmed to prevent copy-paste mistakes. Fully opt-in. If you don't set the env var, nothing changes. ## Native Memory Leak Fix `browser.close()` had a race condition that could lose the browser PID, leaving orphaned Firefox child processes alive after the context was torn down. On long-running servers this compounded — ~930MB leaked per orphaned browser tree. Three fixes: `closeBrowserFully()` serializes concurrent close calls with a shared promise so the PID is never lost, `_forceKillProcessTree()` walks `/proc` to find and SIGKILL orphaned children that escaped the process group, and `cleanupStaleFirefoxProfiles()` sweeps leftover temp directories from `enable_cache: true` sessions on startup. ## Fixes & Improvements - Crash reporter noise reduction: stable dedup signatures, active-tab gate, per-type rate limits, sleep/suspend false-positive suppression - npm publishing via OIDC trusted publishing — provenance attestations on every release, no `NPM_TOKEN` secret - Docker images published to GHCR on release: `docker pull ghcr.io/jo-inc/camofox-browser:1.8.0` ## Thank You Thanks to @trader-payne for the access key feature.