omp packages

@khimaros/pi-sandbox0.1.0

pi extension that runs built-in tools inside a local micro-VM with deny-by-default network egress

khimaros Published 25 days ago GPL-3.0-or-later ~121 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-sandbox

a pi extension that runs pi's built-in tools inside a local micro-VM instead of on the host, with a deny-by-default outbound network policy.

the host working directory is mounted at /workspace in the guest. writes under /workspace pass through to the host; every other guest filesystem change stays inside the VM and is discarded when the session ends.

requirements

host software:

  • linux or macOS
  • node >= 23.6.0 (required by @earendil-works/gondolin)
  • QEMU (brew install qemu on macOS, apt install qemu-system-x86 on debian)

hardware and resources for the micro-VM:

  • x86_64 or arm64. the guest is built for the host architecture; a mismatch forces software emulation
  • CPU virtualization, strongly recommended. on linux this means read and write access to /dev/kvm, normally by joining the kvm group: sudo usermod -aG kvm $USER (log out and back in). macOS uses the hypervisor framework and needs no setup
  • without it the VM still boots, under QEMU's tcg software emulation, which is slow enough to be painful for real work
  • ~1GB RAM per VM (the guest default) plus host overhead, and 2 vCPUs
  • ~300MB disk for the cached guest image, plus a copy-on-write overlay per running VM

the guest image is fetched on first run and cached in ~/.cache/gondolin/images/.

install

install from npm:

pi install npm:@khimaros/pi-sandbox

pi install also accepts a git source, and -l writes to project settings rather than user settings:

pi install git:github.com/khimaros/pi-sandbox

installing from npm or git runs npm install for you.

to work from a checkout instead, note that the extension has a runtime dependency on @earendil-works/gondolin, so the package needs its node_modules before pi can load it:

git clone https://github.com/khimaros/pi-sandbox
cd pi-sandbox
npm install --ignore-scripts
pi install /path/to/pi-sandbox

--ignore-scripts skips native build steps that the QEMU backend does not need. a local path is added to settings without copying and without installing, which is why npm install has to be run by hand.

for a one-off test without registering anything:

cd /path/to/project
pi -e /path/to/pi-sandbox

pi -e also does no dependency installation.

what gets routed

these tools execute in the guest rather than on the host:

read write edit bash ls find grep

user bash (the ! prefix) also runs in the guest, and the system prompt is rewritten so the model is told its working directory is /workspace.

network egress

outbound HTTP and HTTPS are intercepted host-side and checked against an allowlist. the allowlist starts empty, which denies everything -- no package installs, no API calls, no git over HTTPS -- until you permit a host.

/sandbox allow api.github.com
/sandbox allow *.npmjs.org

patterns support * as a wildcard, so *.npmjs.org matches any subdomain. changes apply to the next request; the VM is not restarted.

two things hold regardless of the allowlist:

  • private and loopback IP ranges are always blocked, even if the hostname that resolves to them is allowed
  • SSH and raw TCP have no default path out of the guest; neither is configured by this extension

secrets are supported by the underlying library but are not wired up here yet.

commands

command effect
/sandbox open a picker with the subcommands below
/sandbox status VM id, workspaces, shell, allowlist, config path
/sandbox enable run tools in the VM (starting it if needed)
/sandbox disable run tools directly on the host, stop the VM
/sandbox allow <pattern> add a host pattern to the allowlist
/sandbox deny <pattern> remove a host pattern
/sandbox hosts list the current patterns

allow and deny prompt for a pattern when called with no argument. current state is shown in the footer as sandbox: <id> (/workspace, N host(s)), or sandbox: disabled (host).

disabling

/sandbox disable is a full bypass: tools run on the host with no VM and no egress filtering. the setting persists, so a repo left disabled stays disabled on the next session.

configuration

state is stored per repository in ~/.pi/agent/sandbox.json, keyed by absolute repo path, in the same shape as the agent dir's own trust.json:

{
  "/home/you/src/my-project": {
    "enabled": true,
    "allowedHosts": ["dl-cdn.alpinelinux.org"]
  }
}

the repo key is the nearest ancestor directory containing .git, falling back to the working directory. PI_CODING_AGENT_DIR is honoured, so the file follows a relocated agent dir.

this file lives outside the repository on purpose. an allowlist committed into a project would travel with a clone and silently widen the sandbox of whoever opened it, and pi does not prompt for trust on arbitrary extension config. a malformed or unreadable file falls back to deny-all rather than to anything more permissive.

to change the built-in default for new repositories, edit ALLOWED_HOSTS in src/extension/index.ts.

guest image

alpine linux 3.23, preinstalled with bash, curl, nodejs, npm, python3, uv, openssh, and ca-certificates.

apk add works, with two caveats:

  • it needs /sandbox allow dl-cdn.alpinelinux.org, since that is where the configured repositories live
  • the root filesystem is a copy-on-write overlay that is deleted when the VM stops, so installed packages do not survive the session

put anything that must persist under /workspace.

releasing

pushing a v* tag runs .github/workflows/release.yml, which publishes @khimaros/pi-sandbox to npm. the job fails if the tag does not match version in package.json.

npm version patch    # bumps package.json and package-lock.json, commits, tags
git push --follow-tags

the workflow authenticates with npm trusted publishing (OIDC) and stores no token. this needs a one time setup on npmjs.com: publish the first version by hand with npm login && make publish, then under the package's settings add a trusted publisher for repository khimaros/pi-sandbox and workflow release.yml.