Summary
tools.playwright.mode: cli currently installs @playwright/cli and runs playwright-cli install --skills, but that is not sufficient for secure, portable Playwright use inside AWF. The browser binary, native libraries, agent-visible paths, in-sandbox server lifecycle, and egress guarantees differ across Docker/runc, gVisor, Docker sbx, and Cloud Hypervisor.
The smoke work in github/gh-aw-firewall#7938 demonstrated a working model across all four runtimes, but required repository scripts and generated .lock.yml post-processing. The compiler should make this model first-class.
Required security model
AWF agent sandbox
├── application server bound to 127.0.0.1:<dynamic-port>
├── Playwright CLI and Chromium in the same sandbox
├── browser loopback traffic -> local application directly
└── all non-loopback browser traffic -> Squid -> domain ACL
The API proxy must remain limited to model-provider/API credential injection. Browser web traffic must not use the API proxy or bypass Squid.
A skill can teach the agent the correct workflow, but it is not a security boundary. The compiler and runtime must enforce the topology even if agent code ignores proxy environment variables.
Compiler requirements
1. Secure Playwright CLI and browser staging
When tools.playwright.mode: cli is enabled, the compiler should:
- Install a pinned
@playwright/cli version during deterministic setup, before entering the AWF sandbox.
- Support an explicitly configured npm registry and preserve repository/organization registry policy. Do not silently fall back to public npm.
- Download a pinned Chromium revision during deterministic setup rather than allowing lazy browser downloads from inside the agent sandbox.
- Verify package/browser provenance or checksums according to existing gh-aw dependency policies.
- Stage the CLI, browser, and required Linux shared libraries under a compiler-owned path such as
${RUNNER_TEMP}/gh-aw/playwright.
- Mount the staged assets read-only into the AWF sandbox.
- Set
PATH, PLAYWRIGHT_BROWSERS_PATH, and any required runtime library path inside the sandbox.
- Avoid adding browser-download CDNs such as
storage.googleapis.com to the agent's runtime domain allowlist merely to make installation work.
- Ensure failed or unavailable staging fails closed with a clear diagnostic.
The current behavior of installing the CLI globally on the runner is not portable: runner-global binaries are not necessarily visible inside Docker sbx or Cloud Hypervisor. The browser also needs an explicit native-library closure in minimal microVM guests.
2. Cross-runtime path and dependency support
The generated workflow must work without lockfile rewriting for:
- Default Docker/runc
- gVisor
- Docker sbx
- Cloud Hypervisor
The compiler should use each runtime's supported read-only mount/tool-cache mechanism. Cloud Hypervisor must expose the required tool cache and staged Playwright assets without broadening guest filesystem access. Docker sbx must use a browser-compatible host gateway address for Squid rather than relying on an address Chromium treats as invalid or bypassable.
Chromium launch defaults should be compatible with an enclosing sandbox, including the established headless/container flags where required, without weakening the outer AWF boundary.
3. In-sandbox pre-agent lifecycle hook
steps: and pre-agent-steps: execute on the runner outside AWF, so they cannot launch a server that remains colocated with the browser and agent inside the sandbox.
Add a declarative hook for deterministic setup commands that execute:
- after the AWF runtime is created,
- inside the same agent sandbox/microVM,
- before the agent harness starts,
- with the same loopback namespace, mounts, and Squid configuration as the agent, and
- with cleanup guaranteed when the agent exits or startup fails.
Possible shape (name subject to design):
sandbox:
agent:
runtime: gvisor
setup-steps:
- name: Start local application
run: ./scripts/start-test-server.sh
This hook must not become a way to run untrusted agent-generated code outside AWF. It should have explicit timeout, failure propagation, logging, and cleanup semantics.
4. AWF-aware Playwright skill
Keep the upstream playwright-cli command skill, but install an additional gh-aw/AWF policy skill whenever Playwright CLI mode and the AWF firewall are enabled.
The skill should instruct agents to:
- Start the application server inside the agent sandbox.
- Bind only to
127.0.0.1, preferably on an ephemeral port.
- Wait for a loopback health/readiness check before opening the browser.
- Navigate to the loopback URL with
playwright-cli.
- Keep localhost/127.0.0.1 in the browser proxy bypass list while routing all other HTTP/HTTPS traffic through the provided Squid proxy.
- Treat the API proxy as model-provider infrastructure, never as a browser proxy.
- Never bind development servers to
0.0.0.0, publish host ports, or use an external preview service unless explicitly requested and narrowly allowlisted.
- Never install packages, browsers, or system dependencies at agent runtime; use the compiler-staged assets.
- Never broaden egress to browser download or package registry domains to work around missing staging.
- Use readiness polling, deterministic result checks, and reliable browser/server cleanup.
- Respect the workflow's external-domain allowlist and avoid examples that navigate to arbitrary public sites.
The generated policy guidance must take precedence over unsafe generic suggestions in the upstream Playwright skill, including runtime npm install, npx fallback installation, or navigation to arbitrary example domains.
5. Enforced Docker sbx egress
Proxy-aware browser configuration alone is not sufficient. The compiler's Docker sbx provisioning owns daemon startup and should coordinate with AWF so the microVM cannot directly reach external networks.
The sbx setup should establish an enforceable path such as:
- pre-pull/authenticate required sbx templates before lockdown,
- restart the sbx daemon with
DOCKER_SANDBOXES_PROXY targeting AWF's published Squid endpoint before agent execution, or
- apply equivalent host/VMM policy that permits external HTTP/HTTPS only through Squid.
If the installed sbx version cannot provide enforceable egress, compilation or runtime startup should fail closed rather than presenting proxy environment variables as equivalent security.
This likely needs a documented gh-aw/AWF handoff contract because Squid becomes available when AWF starts, while gh-aw provisions the sbx daemon earlier.
6. Generated workflow behavior
A workflow author should only need declarative configuration, for example:
tools:
playwright:
mode: cli
browser: chromium
sandbox:
agent:
id: awf
runtime: docker-sbx
The generated .lock.yml should contain all required setup, verified staging, read-only mounts, proxy configuration, runtime-specific support, and skill installation. Recompiling must not require a repository-specific post-processing script that edits the AWF command or injects commands immediately before the agent harness.
Validation and acceptance criteria
Add compiler golden/unit coverage plus end-to-end smoke workflows for all four runtimes. Each smoke must prove:
- The CLI and Chromium are available inside the agent sandbox without runtime installation.
- A server bound to
127.0.0.1 is reachable from Chromium in the same sandbox.
- Browser JavaScript executes successfully.
- A non-allowlisted external navigation is blocked by Squid.
- Direct non-proxy browser egress is also blocked, especially for Docker sbx.
- Playwright, browser, and server processes are cleaned up.
- The generated workflow uses only configured package registries and does not broaden runtime egress for browser downloads.
- Recompilation produces the working lockfiles without post-processing.
Reference implementation
Those workflows passed across all four runtimes and provide concrete fixtures for compiler integration, but their current repository-specific staging and lockfile injection should be replaced by first-class compiler output.
Summary
tools.playwright.mode: clicurrently installs@playwright/cliand runsplaywright-cli install --skills, but that is not sufficient for secure, portable Playwright use inside AWF. The browser binary, native libraries, agent-visible paths, in-sandbox server lifecycle, and egress guarantees differ across Docker/runc, gVisor, Docker sbx, and Cloud Hypervisor.The smoke work in github/gh-aw-firewall#7938 demonstrated a working model across all four runtimes, but required repository scripts and generated
.lock.ymlpost-processing. The compiler should make this model first-class.Required security model
The API proxy must remain limited to model-provider/API credential injection. Browser web traffic must not use the API proxy or bypass Squid.
A skill can teach the agent the correct workflow, but it is not a security boundary. The compiler and runtime must enforce the topology even if agent code ignores proxy environment variables.
Compiler requirements
1. Secure Playwright CLI and browser staging
When
tools.playwright.mode: cliis enabled, the compiler should:@playwright/cliversion during deterministic setup, before entering the AWF sandbox.${RUNNER_TEMP}/gh-aw/playwright.PATH,PLAYWRIGHT_BROWSERS_PATH, and any required runtime library path inside the sandbox.storage.googleapis.comto the agent's runtime domain allowlist merely to make installation work.The current behavior of installing the CLI globally on the runner is not portable: runner-global binaries are not necessarily visible inside Docker sbx or Cloud Hypervisor. The browser also needs an explicit native-library closure in minimal microVM guests.
2. Cross-runtime path and dependency support
The generated workflow must work without lockfile rewriting for:
The compiler should use each runtime's supported read-only mount/tool-cache mechanism. Cloud Hypervisor must expose the required tool cache and staged Playwright assets without broadening guest filesystem access. Docker sbx must use a browser-compatible host gateway address for Squid rather than relying on an address Chromium treats as invalid or bypassable.
Chromium launch defaults should be compatible with an enclosing sandbox, including the established headless/container flags where required, without weakening the outer AWF boundary.
3. In-sandbox pre-agent lifecycle hook
steps:andpre-agent-steps:execute on the runner outside AWF, so they cannot launch a server that remains colocated with the browser and agent inside the sandbox.Add a declarative hook for deterministic setup commands that execute:
Possible shape (name subject to design):
This hook must not become a way to run untrusted agent-generated code outside AWF. It should have explicit timeout, failure propagation, logging, and cleanup semantics.
4. AWF-aware Playwright skill
Keep the upstream
playwright-clicommand skill, but install an additional gh-aw/AWF policy skill whenever Playwright CLI mode and the AWF firewall are enabled.The skill should instruct agents to:
127.0.0.1, preferably on an ephemeral port.playwright-cli.0.0.0.0, publish host ports, or use an external preview service unless explicitly requested and narrowly allowlisted.The generated policy guidance must take precedence over unsafe generic suggestions in the upstream Playwright skill, including runtime
npm install,npxfallback installation, or navigation to arbitrary example domains.5. Enforced Docker sbx egress
Proxy-aware browser configuration alone is not sufficient. The compiler's Docker sbx provisioning owns daemon startup and should coordinate with AWF so the microVM cannot directly reach external networks.
The sbx setup should establish an enforceable path such as:
DOCKER_SANDBOXES_PROXYtargeting AWF's published Squid endpoint before agent execution, orIf the installed sbx version cannot provide enforceable egress, compilation or runtime startup should fail closed rather than presenting proxy environment variables as equivalent security.
This likely needs a documented gh-aw/AWF handoff contract because Squid becomes available when AWF starts, while gh-aw provisions the sbx daemon earlier.
6. Generated workflow behavior
A workflow author should only need declarative configuration, for example:
The generated
.lock.ymlshould contain all required setup, verified staging, read-only mounts, proxy configuration, runtime-specific support, and skill installation. Recompiling must not require a repository-specific post-processing script that edits the AWF command or injects commands immediately before the agent harness.Validation and acceptance criteria
Add compiler golden/unit coverage plus end-to-end smoke workflows for all four runtimes. Each smoke must prove:
127.0.0.1is reachable from Chromium in the same sandbox.Reference implementation
scripts/ci/stage-playwright-loopback-smoke.shscripts/ci/run-playwright-loopback-smoke.sh.github/workflows/smoke-playwright-{runc,gvisor,docker-sbx,cloud-hypervisor}.lock.ymlThose workflows passed across all four runtimes and provide concrete fixtures for compiler integration, but their current repository-specific staging and lockfile injection should be replaced by first-class compiler output.