Agent-readable docs index: /llms.txt. Download /docs.zip to grep all markdown files locally.

Security Model and Sandboxed Execution

Everything runs on your machine. The relay binds to localhost:19988 and only accepts connections from the extension. No remote server, no account, no telemetry.

Architecture

┌──────────────────────────────────────────────────────────────────────────────────────────┐ │ YOUR MACHINE │ │ │ │ ┌─────────────┐ ┌──────────────────┐ ┌──────────────┐ │ │ │ Extension │◄────────► Relay Server │◄────────► CLI / MCP │ │ │ │ (Chrome) │ WS │ localhost:19988 │ WS │ (Agent) │ │ │ └─────────────┘ └──────────────────┘ └──────────────┘ │ │ │ │ Nothing leaves localhost unless you explicitly set up remote access │ └──────────────────────────────────────────────────────────────────────────────────────────┘

Security guarantees

Local only. The WebSocket server binds to localhost. Nothing leaves your machine unless you explicitly configure remote access with a tunnel and auth token.
Origin validation. The extension WebSocket endpoint only accepts the Playwriter extension origin. Browsers cannot spoof the Origin header, so malicious websites cannot connect and control your browser. CLI and MCP connect as local Node.js clients on localhost; for remote access, always use token authentication.
Explicit consent. Only tabs where you clicked the extension icon are controlled. No background access to other tabs. Chrome shows an automation banner on controlled tabs so you always know which tabs are being automated.
Visible automation. The Chrome debugger banner is always visible on controlled tabs. You can see everything the agent does in real time.

Sandboxed filesystem

The require('node:fs') module in the execution sandbox is scoped. Write operations only succeed in:
Allowed pathDescription
Session cwdThe directory where playwriter CLI was invoked
/tmpSystem temp directory
os.tmpdir()OS-specific temp (e.g. /var/folders/.../T/ on macOS)
Writing to any other path throws EPERM: operation not permitted, access outside allowed directories. To save files elsewhere, write to a temp path first, then move the file using a shell command outside the sandbox.

Sandbox restrictions

The execution sandbox runs in a controlled environment:
  • No import statements. Use require() for Node.js modules.
  • No __dirname or __filename. Use process.cwd() or absolute paths.
  • Scoped require. Only safe Node.js built-in modules are available: path, url, querystring, crypto, buffer, util, assert, events, timers, stream, zlib, http, https, os, and scoped fs.
  • No process.chdir(). Use a new session with a different cwd.
  • No browser.close() or context.close(). These would disconnect all agents.

Remote access security

When using remote access via Traforo tunnels:
  • Token authentication is required. The --token flag on playwriter serve enforces auth on all connections.
  • Encrypted transport. Traforo tunnels use Cloudflare's TLS infrastructure.
  • No port forwarding. No firewall rules or VPN needed; the tunnel handles everything.
# Host machine: serve with auth token npx traforo -p 19988 -- playwriter serve --token MY_SECRET # Remote machine: connect with token export PLAYWRITER_HOST=https://my-tunnel.traforo.dev export PLAYWRITER_TOKEN=MY_SECRET playwriter session new

Cookie safety

Never use Network.clearBrowserCookies via CDP. It's a profile-wide destructive operation that wipes ALL cookies across every domain in the user's Chrome profile; Gmail, GitHub, and every authenticated session.
Use scoped cookie operations instead:
const cdp = await getCDPSession({ page: state.page }) const { cookies } = await cdp.send('Network.getCookies', { urls: ['https://example.com'] }) // Delete individually for (const cookie of cookies) { await cdp.send('Network.deleteCookies', { name: cookie.name, domain: cookie.domain }) }