browse -> parse in isolation -> analyze pipeline built from two boxes.
Level: intermediate · Time: ~20 minutes · Pattern: the agent lives in the box.
When to use this
An agent that browses the open web faces two problems at once. The content is untrusted. Page scripts can be hostile, downloads can be malicious, and trackers pollute whatever profile they touch. Callingplaywright.launch() on your host runs arbitrary remote code next to your process. Parsing the HTML afterwards with a heavyweight parser widens the surface further.
The work does not fit one machine. Large-scale scraping and cross-browser checks want many browser instances at once, and installing Chromium, Firefox, and WebKit locally is both heavy and messy.
The layered answer: a BrowserBox runs the real browser inside a microVM and exposes only a control endpoint; your automation script stays in your trusted process and drives it remotely. The HTML that comes back then goes into a CodeBox for parsing, so even the parser runs isolated. Only structured data crosses back.
Architecture
The automation logic stays on the host; only the browser and the parser are sandboxed. Two separate boxes means a hostile page cannot influence the parsing step either.Prerequisites
- BoxLite installed and a working virtualization host — see Installation.
- A Playwright client pinned to the version inside the box — a mismatch fails the connection with
428 Precondition Required. You do not needplaywright install; the browsers live in the box. - An OpenAI-compatible LLM endpoint for the analysis step.
- The first run pulls a multi-gigabyte Playwright image.
Build it
Step 1: fetch the page with a real browser
Connect over CDP withendpoint(). That path drives the Chromium already baked into the image, so nothing has to be fetched at runtime.
browser="firefox" and connect with playwright.firefox.connect(ws) — Firefox speaks WebDriver BiDi rather than CDP. WebKit has no CDP endpoint; it needs the Playwright Server mode described on Browser automation.
Step 2: parse the untrusted HTML in a second sandbox
The scraped HTML is never parsed on the host. It is copied into aCodeBox, extracted there with the standard library only, and comes back as JSON.
BrowserBoxOptions fields and both connection modes are documented on Browser automation.
Run it
Trust and limits
- What the boundary covers. Page scripts, downloads, and any parser weakness are confined to their box. Your process holds only the Playwright client and the extracted data. Both boxes are destroyed on exit.
- Two boxes is the point. Parsing hostile HTML is itself risky. Keeping it in a separate
CodeBoxmeans a page that defeats your extraction logic still has not reached the host. - The client version must match the box. A Playwright client that disagrees with the in-box server fails with
428 Precondition Required. Pin both. - CDP does not cover every browser.
endpoint()serves Chromium and Firefox. WebKit requires the Playwright Server mode. - Egress is open by default. Scraping needs that. If the target set should be fixed, add an egress allowlist — see Run untrusted tools safely.
Troubleshooting
Next steps
- Scrape in parallel. One box per target URL, run with
asyncio.gather, and bound the fan-out with a semaphore so you do not start dozens of VMs at once. - Cross-browser checks. The same script against
chromiumandfirefoxboxes, in parallel, with no local browser installs. - Turn the data into a chart — Build a data analysis agent picks up where the JSON lands.
- Interact rather than read. Filling forms and taking screenshots is on Browser automation.

