Browser tool

A real headless browser the agent can drive — but only against hosts you've explicitly allowlisted. Default deny.

Why an allowlist

The browser tool is powerful: full Playwright-class navigation, JavaScript execution, screenshot capture, form interaction. That power is also a liability — a compromised model that's allowed to fetch arbitrary URLs can exfiltrate secrets or attack internal services.

So: default deny. The browser cannot reach any host until you say so.

How to open the allowlist editor

  • Keyboard: Ctrl+Shift+B (Windows/Linux) or ⌘⇧B (Mac).
  • Top bar chip: Browser.

The first time you open it, the status row reads:

> Default deny — no host is reachable.

That's correct. You need to add hosts.

Adding hosts

Type a host pattern in the input. Patterns:

PatternMatches
example.comExact host (no subdomains).
*.example.comAny subdomain (e.g. api.example.com, cdn.example.com).
*Everything. Floodgates open. Confirm-guarded.

There's a hard cap of 256 host rules per workspace.

Presets

Three quick-fill chips:

  • localhost — loopback addresses + common dev ports (5173, 5060, 3000, 8000).
  • preview — your current Vercel/Netlify/Pages.dev preview hosts.
  • floodgates*. Use only for throwaway workspaces.

Pre-flight gating

Every browser request — browser.smoke, browser.marketing, browser.flow — is gated:

  1. The base URL is checked against the allowlist.
  2. Every goto step within a flow is checked again.

Failure mode: HTTP 403 with default-deny: <host> in the body. The agent sees this and reports it.

Backend test

curl -X POST -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}' \
  https://your-workspace.krowforge.com/browser/smoke

If example.com isn't allowlisted: 403 with reason default-deny:example.com. Add example.com in the allowlist UI, retry, and you'll get a 200.

Audit trail

Every change to the allowlist is logged with the actor and the diff:

audit  browser.allowlist.set  user=42  added=[example.com]  removed=[]

You can review the audit log in the workspace settings.

What gets stored

Each workspace has its own allowlist file under the cache dir, written atomically (.tmpreplace). It's per-workspace — sharing a workspace with a teammate shares the allowlist.