Fail closed by contract
Local control. Bounded output.
Headless exposes no TCP listener, no Chromium debug port, and no arbitrary-JavaScript command. This page separates reportable boundary failures from documented limits.
01 / Security boundaries
What must hold.
| Boundary | Expected behaviour |
|---|---|
| No arbitrary code execution | There is no JavaScript-evaluation verb and no shell verb. Reaching arbitrary in-page or host execution through the protocol is a vulnerability. |
| Navigation | HTTP/HTTPS only. file:, javascript:, data:, credential-bearing URLs, and external application schemes must be refused at every layer. |
| Downloads | Page-initiated downloads are denied. Executables, installers, scripts, libraries, and disk images are blocked by extension. |
| Control plane | A 0600 Unix socket inside a 0700 per-user directory, with a peer-UID check. There is no TCP listener and no Chromium debug port. Any remote reachability is a vulnerability. |
| Artifacts | Bare validated names, O_EXCL creation at 0600 inside a 0700 root, never overwritten. Path traversal or reading outside the store is a vulnerability. |
| Secrets | Cookie and storage values require both --values and HEADLESSALLOWSENSITIVE_DIAGNOSTICS=1. Authorization, cookie, token, and secret headers, plus URL credentials, are always redacted. Flow recordings never contain typed values. |
| Untrusted content | Everything derived from a page is marked untrustedContent and is never executed as a command. A page that induces the host to act on its own text is a vulnerability. |
| Sandbox | The Linux host refuses to run as root and never passes --no-sandbox. Snap Chromium is rejected before launch. |
02 / Known limitations
Documented, not hidden.
- Same-user access. Any process running as your OS user can reach that user's socket, browser profile, and artifacts. Run untrusted agents as separate OS users.
- Shared session state. Sessions are windows (macOS) or tabs (Linux) over one browser profile, so cookies and storage are shared between sessions. Per-session isolation is tracked in the roadmap, not implied today.
- macOS diagnostics are best-effort. WebKit does not expose Chromium's event stream; the macOS QA bridge runs in the page world and is therefore observable by the page. Hardening it is tracked as #28.
- Recording scope. The recorder captures browser frames only — never OS chrome, other applications, or audio.
- Network mocking is Linux-only. macOS returns UNSUPPORTED_CAPABILITY rather than partially emulating traffic control.
- HTTP on macOS. The ATS exception is limited to WKWebView so browser pages can use HTTP when required. Native application networking retains the default ATS protections.
03 / Operator hardening
Reduce the same-user boundary.
- Run agents as a dedicated OS user, not your own account.
- Leave HEADLESSALLOWSENSITIVE_DIAGNOSTICS unset unless you are actively debugging, and never in a shared session.
- Keep the stdio MCP server local, or tunnel it over SSH. Do not bridge it to a network listener.
- Treat every artifact, report, and console line as potentially sensitive page content.