A Pi setup with permission, sandbox, and auto-review
Anh Trinh
SubscribeSign in
A Pi setup with permission, sandbox, and auto-review<br>A secure-ish way to run Pi on your host.
Anh Trinh<br>Aug 13, 2026
Share
1. Motivation
Pi is great precisely because it is so customizable. Its core stays small, and extensions let you assemble the tools and workflow that suit your environment.<br>The trade-off is that Pi is intentionally permissive. By default, it runs with the permissions of the user who launched it and does not provide a built-in approval system or OS sandbox. That “YOLO” experience is productive, but an agent capable of reading files and running arbitrary shell commands deserves a clearer security boundary.<br>Thanks for reading! Subscribe for free to receive new posts and support my work.
Subscribe
Thanks for reading! Subscribe for free to receive new posts and support my work.
Subscribe
Running Pi inside a container is one option. However, that becomes awkward when the project itself relies on Docker Compose, the host Docker daemon, or other host-only development services. Giving the container access to the Docker socket also hands it considerable power over the host.<br>What I wanted instead was:<br>normal work inside the current repository;
OS-level isolation for ordinary shell commands;
deterministic blocks for secrets and paths outside the repository;
automatic review of requests that cross selected boundaries; and
a narrow, reviewed way to run specific commands on the host.
Pi’s extensibility makes this possible, but discovering how the pieces fit together is not obvious. Hopefully this article gives you a useful starting point for a more secure host-based Pi setup.<br>2. The setup
The design combines three extensions:<br>@gotgenes/pi-permission-system defines deterministic allow, ask, and deny rules.
@erichll/pi-sandbox runs ordinary Bash commands inside an OS sandbox.
@erichll/pi-auto-review reviews network, permission, and host-execution requests that require a decision.
Each layer has one job. The permission system establishes hard boundaries, the sandbox contains processes, and the reviewer handles contextual exceptions. An LLM decision never replaces a deterministic rule for something that must always be forbidden.<br>How the piece fits together
Install the components
Assuming Node.js is already installed, install Pi and the Linux sandbox dependencies:<br>npm install -g --ignore-scripts @earendil-works/pi-coding-agent<br>sudo apt-get install -y bubblewrap socat ripgrep
Install the extensions globally, not from inside a project:<br>pi install npm:@gotgenes/pi-permission-system<br>pi install npm:@erichll/pi-auto-review<br>pi install npm:@erichll/pi-sandbox<br>pi list # to list the installed extensions
These extensions are trusted host code, so review their source and record the versions used in a reproducible deployment.<br>Define the hard boundaries
Create ~/.pi/agent/extensions/pi-permission-system/config.json:
"authorizerChain": ["pi-auto-review"],<br>"permission": {<br>"*": "allow",<br>"path": {<br>"*": "allow",<br>"*.env": "deny",<br>"*.env.*": "deny",<br>"*.env.example": "allow",<br>"*.pem": "deny",<br>"*.key": "deny",<br>"~/.ssh/*": "deny",<br>"~/.aws/*": "deny"<br>},<br>"external_directory": "deny",<br>"bash": {<br>"*": "allow",<br>"sudo *": "deny"
The policy protects secret-shaped files, blocks access outside the working directory, and denies sudo. The authorizerChain connects permission requests that resolve to ask with the automatic reviewer.<br>The permissive Bash rule is intentional. It allows Bash calls to reach pi-sandbox; it does not run them directly on the host.<br>Sandbox Bash and select host commands
Create ~/.pi/agent/extensions/pi-sandbox/config.json:<br>"subagents": {<br>"provider": "builtin"<br>},<br>"hostIPC": {<br>"mode": "ask",<br>"preflightCommandPrefixes": [<br>"docker compose ps",<br>"docker compose up -d",<br>"docker compose down",<br>"docker compose exec app python manage.py test"<br>],<br>"retryOnUnixSocketError": false<br>},<br>"filesystem": {<br>"additionalAllowRead": []
Commands that do not match a hostIPC prefix run in the OS sandbox. Matching a prefix does not automatically authorize a command; it only makes the complete command eligible for review and one-shot host execution.<br>Prefixes should describe specific operations. For example:<br>docker compose exec app python manage.py test
is safer than:<br>docker compose exec app
The broader prefix would also make an interactive shell eligible for host execution. With retryOnUnixSocketError disabled, unlisted Docker commands remain sandboxed and fail when they try to reach the Docker socket.<br>Network access is handled similarly, with one important difference: approving a destination allows that specific connection while the command remains inside the sandbox.<br>Configure automatic review
Choose a model that is already configured and authenticated in Pi, then create ~/.pi/agent/extensions/pi-auto-review/config.json:<br>"model": "your-provider/your-review-model",<br>"failureMode": "defer",<br>"timeoutMs": 90000
failureMode: "defer" means a...