Extensions and more isolation#76
Conversation
|
Thanks @viktorku for raising these. I'll review shortly. |
|
Nice work! These are meaningful additions to discuss. I'd like to incorporate them while staying true to the current design of pi-less-yolo being a lightweight shim. Extension supportI like the overlay pattern, and I think it can be used to manage the extensions without corrupting host versions. In This avoids the network and performance cost of installing extensions on Mount MaskMost pi-less-yolo features are opt-in via environment variable. Instead of adding a Typescript extension and maintaining it, I think this can be achieved with environment variables. Users can set it in their shell for permanent use across all projects: Or per-invocation when needed: Isolated DirectoriesApplying the same pattern here makes this an opt-in feature based on This can be exported or set for a single invocation when needed. In-container denyI think the in-container deny list is an interesting strategy. However, I think it makes sense for the security Typescript extension to be separate from pi-less-yolo. That keeps this project focused on the container level, allowing users to bring further extensions as needed to make it even more less YOLO. :) I'm curious what your thoughts are on the above modifications. What do you think? |
Hello there! I was looking for some more security/isolation/sandboxing extensions for pi and I liked yours as a starter. Thanks for making this public! 🙏 I made some adjustments in my fork. 😁
So, here goes. We (Qwen, Claude and yours truly) added support for even more isolation and sandboxed security:
~/.pi/agent/extensions(without host corruption wrt cross arch dependencies),.env*via "mount masking" to control what env vars are exposed to your agent (read and bash tool intercept is not exhaustive enough)I decided to have the JSONC provide the single source of truth for configuration, but it can be split. Let me know what you think - I got no pressing need to merge any of this, just starting a discussion 🫡
LLM-generated summary
Adds extension support for pi and ships a first-party
securityextension that enforces read/write/bash rules inside the container, plus host-side mount primitives driven from the same JSONC config.Why this matters
Guardrails without getting in the way. You can block the agent from touching
~/.ssh, your AWS creds,.envfiles, or arbitrarysudo/mkfs-class commands, with visible feedback (🔒 security: 5 read, 6 write, 3 bashin the footer,/securityto inspect the active rules). Secrets like.envare mount-masked with/dev/nullat the container boundary, so bash and child processes can't sneak around the tool-level rules.Run host projects in the container without corrupting either side. The biggest pain with mounting your project into a Linux container from macOS is that
node_modules,.venv, and similar dirs are full of host-built native binaries that don't run on the other arch — and if the container rebuilds them, you've now broken your host toolchain too. This PR introduces per-project overlay dirs: configureisolateDirsand each listed folder is shadowed by a dedicated Linux tree under~/.pi/agent/overlays/<project-hash>/. The container gets a clean, persistent workspace; your host tree stays untouched. It just works across architectures.One config, two enforcement layers. In-container rules (what the agent's tools can do) and host-side rules (what Docker will even mount) live in the same
security.jsonc, so there's one place to reason about trust.Also included
~/.pi/agent/extensions/, pi installs and loads it at startup.LLM-generated detailed commit description:
What's in here
Extension support (
b57ff60)_docker_flags: read-only mount of~/.pi/agent/extensionsat/host-extensions, tmpfs overlay at/pi-agent/extensions, and per-project overlay dirs (node_modules,.venv) under~/.pi/agent/overlays/<hash>/so host-built native binaries don't leak into the Linux container./host-extensionsand runsnpm installper extension.tasks/pi/build: fixes empty build-flag handling on macOS.securityextension (dcf1a9f)extensions/security/(security.ts,config.ts,match.ts) wired viapi.extensionsinpackage.json.tool_callfor read-ish (read/grep/find/ls), write-ish (write/edit), andbashtools, blocking when the path or command matches configured rules./securityslash command prints the active config path and rule breakdown; footer shows🔒 security: N read, M write, K bashat session start.~/.pi/agent/extensions/security.jsonc(JSONC with comments); globs andre:<regex>both supported./security, and tool_call hooks.Quiet npm at startup (
d61295a)npm installnow runs with--loglevel=error --no-audit --no-fund. Dropsglobalignorefile/pythonbuiltin-config warnings (from the base image's npmrc), thenode-domexceptiondeprecation (transitive), and the vulnerability/funding summaries.set -estill fails the entrypoint on real install errors.JSONC-driven host enforcement (
a98f30c)filesystem.mountMaskandfilesystem.isolateDirsto the security config schema._docker_flagsreads them via an inlineread_security_configshell function (one-line JSONC stripper using a regex alternation trick — no separate helper file, no new dependency).mountMaskbinds/dev/nullover each listed path (relative to$(pwd)), so bash and child processes can't read secrets like.enveven though the extension'sdenyReadonly guards tool calls.isolateDirsreplaces the ad-hocPI_ISOLATE_DIRSspace-delimited env var.security.jsonc.exampleall updated to reflect the two-tier model (in-container rules vs host-side mounts).Other notes / features
mise run pi:buildpicks up the Dockerfile change; startup is quiet (no npm warn / audit / fund lines)./securityinside pi prints the path to~/.pi/agent/extensions/security.jsoncand correct rule counts.cat .envinside the container returns empty (mount mask) even thoughdenyReadonly blocks thereadtool.node_modulesand.venvinside the container don't shadow the host's macOS builds.npm run checkinextensions/security/should make 59/59 tests pass.