wirenboard-agent-vm/images
Evgeny Boger f40e6df2bc fix(phase7): run chrome-devtools MCP under a dedicated user with scoped CA trust
The Phase 7 chrome-devtools MCP entry (npx ... --headless --isolated)
reported `✓ Connected` to `claude mcp list` but every tool call
returned either `Protocol error (Target.setDiscoverTargets): Target
closed` or `net::ERR_CERT_AUTHORITY_INVALID`. Two distinct causes:

1. Chromium's user-namespace sandbox refuses to initialize as root
   (the guest's only user), so the browser dies before the CDP pipe
   is read.
2. Chromium on Linux ignores `/etc/ssl/certs/ca-certificates.crt`
   and only honours its built-in root store + the per-user NSS DB,
   so the microsandbox MITM CA isn't trusted by chromium even though
   curl/openssl trust it via the bundle.

Both of these had naïve fixes (`--no-sandbox` and `--acceptInsecureCerts`)
but we'd rather keep chromium's nested sandbox active (defence in depth
against untrusted content the agent navigates to) and only trust *our*
one CA (not every untrusted cert).

Approach:

- **Dedicated `chrome` user (UID 9999)** baked into the image via
  direct /etc/passwd + /etc/shadow + /etc/group edits (debian-slim
  has no `useradd`; the shadow entry is needed because `su` calls
  PAM and rejects users without one). Sudoers rule grants password-
  less `root -> chrome`.

- **Wrapper `/usr/local/bin/agent-vm-chrome-mcp`** that re-execs the
  MCP under chrome via `sudo -u chrome -H -n`. The env allow-list
  preserves agentd-set NODE_EXTRA_CA_CERTS / SSL_CERT_FILE /
  CURL_CA_BUNDLE / REQUESTS_CA_BUNDLE / PATH; without these, sudo's
  default env_reset strips them and node fails `npx -y` with
  SELF_SIGNED_CERT_IN_CHAIN fetching from registry.npmjs.org.

- **Pre-initialized empty NSS DB** at /home/chrome/.pki/nssdb (built
  at image time with `certutil -N --empty-password`) plus
  `libnss3-tools` package so the launcher's runtime `certutil -A`
  has something to add to.

- **Launcher prelude (run.rs)** runs `certutil -A -t TC -n
  microsandbox -i /usr/local/share/ca-certificates/microsandbox-ca.crt`
  on every boot. Can't bake the CA into the image — agentd writes it
  into the guest at boot time, and the cert is per-boot. Add-by-name
  is idempotent so re-running on every launch is fine.

- **MCP config (secrets.rs)** swaps `command: npx` for `command:
  /usr/local/bin/agent-vm-chrome-mcp` with the original npx + args
  passed through. No more `--no-sandbox`, `--disable-dev-shm-usage`,
  or `--acceptInsecureCerts`.

Verified e2e inside a fresh sandbox: `take_snapshot` after
`navigate_page https://example.com` returns the real "Example
Domain" heading text; `ps -ef | grep chrome` shows chromium running
as `chrome`, not root; NSS DB lists only `microsandbox` with `CT,,`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 20:39:55 +03:00
..
build.sh fix(setup): robust registry-state detection on Docker 29.x 2026-05-21 21:33:32 +03:00
Dockerfile fix(phase7): run chrome-devtools MCP under a dedicated user with scoped CA trust 2026-05-24 20:39:55 +03:00