pi-minimal-permission-system
Minimal permission enforcement extension for the Pi coding agent.
Package details
Install pi-minimal-permission-system from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-minimal-permission-system- Package
pi-minimal-permission-system- Version
1.4.0- Published
- Oct 2, 2026
- Downloads
- 693/mo · 57/wk
- Author
- milanglacier
- License
- unknown
- Types
- extension
- Size
- 79.8 KB
- Dependencies
- 4 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-minimal-permission-system
A minimal permission enforcement extension for the Pi coding agent.
This extension checks read, edit, write, and bash calls against rules
you configure. These tools require approval when no rule matches. You can also
restrict JavaScript syntax in Pi's codemode tool (Pi 0.99.1+).
Codemode calls other tools, and those calls still go through their usual permission checks. Allowing codemode by default avoids asking twice. You can add rules to restrict the script itself.
Philosophy
- Policies cover
read,edit,write, andbashcalls, plus optional codemode syntax checks. They do not cover MCP tools or other extension tools. - Rules have two layers: global and project-local. There are no separate subagent policies.
- File tools have independent rules, so you can allow reads while blocking edits and writes.
Installation
Install from npm with Pi:
pi install npm:pi-minimal-permission-system
To pin a specific release:
pi install npm:pi-minimal-permission-system@1.0.0
For local development, clone the repository and install its dependencies:
cd ~/.pi/agent/extensions
git clone https://github.com/milanglacier/pi-minimal-permission-system.git
cd pi-minimal-permission-system
npm install
Configuration
Define permissions in JSONC files (JSON with comments). Use allow to permit a
call, deny to block it, or ask to request approval. Calls that require
approval are blocked when no interactive UI is available.
Global config
~/.pi/agent/permissions.jsonc
Applies to every Pi session. If PI_CODING_AGENT_DIR is set, the global file
is $PI_CODING_AGENT_DIR/permissions.jsonc.
Project-local config
<cwd>/.pi/agent/permissions.jsonc
Pi reads this file relative to its current working directory. It does not search parent directories for project policies. Project rules are combined with global rules using the precedence described below.
Format
{
"read": {
"**": "allow",
"/etc/**": "deny",
"**/.env*": "deny",
"**/secrets/**": "ask",
},
"edit": {
"**": "allow",
"**/.env*": "deny",
"**/package-lock.json": "deny",
},
"write": {
"**": "allow",
"/etc/**": "deny",
"**/.ssh/**": "deny",
},
"bash": {
".*": "allow",
"rm\\s+-rf\\s+/.*": "deny",
"sudo\\b.*": "ask",
},
"codemode": {
"DebuggerStatement": "deny",
},
}
Pattern matching
| Tool | Pattern type | Notes |
|---|---|---|
read, edit, write |
picomatch glob | Matches absolute path, relative path (from cwd), raw input, and basename. dot: true is enabled. |
bash |
JavaScript RegExp | Matched against the full command string. Must be a valid regex (the pattern string is passed to new RegExp(pattern, "u")). |
codemode |
esquery AST selector | Matched against the submitted JavaScript parsed with Acorn. Matching is syntactic; aliases and runtime behavior are not resolved. |
Precedence
For bash, read, edit, and write:
- Evaluate rules in declaration order, global first and then project-local.
- Use the last matching rule. If none matches, require approval (
ask). - If the last matching global rule is
deny, block the call regardless of project rules. A later global rule can override an earlier global rule.
For codemode, combine all matching selectors from both layers with
deny > ask > allow, regardless of declaration order. A valid policy allows
scripts when rules are absent or no selector matches. An allow rule cannot
create an exception to a matching ask or deny rule.
See the Codemode permissions guide for syntax selectors, validation errors, and limitations. Syntax checks are not a sandbox.
YOLO mode
Start Pi with --yolo or run /yolo during an interactive session to bypass
all permission checks enforced by this extension. /yolo is a toggle; running
it again restores normal permission enforcement.
YOLO bypasses policy loading, rule checks, and approval prompts for all covered tools, including codemode. It also bypasses global denials and codemode policy validation.
Example workflows
Read-only mode for sensitive directories
{
"read": {
"**": "allow",
},
"edit": {
"**": "allow",
"**/.ssh/**": "deny",
"**/.gnupg/**": "deny",
},
"write": {
"**": "allow",
"**/.ssh/**": "deny",
"**/.gnupg/**": "deny",
},
}
Interactive gate for destructive commands
{
"bash": {
".*": "allow",
"rm\\s+-rf\\s+/.*": "deny",
"dropdb\\b.*": "ask",
"sudo\\b.*": "ask",
},
}
Allow rm -r/rm -f in temp paths, ask elsewhere
Bash rules inspect the command string, not the shell's parsed arguments or
expanded variables. This example asks about rm flags, allows matching temp
paths, then asks again for extra targets or ..:
{
"bash": {
".*": "allow",
// Ask for any rm with -r/-R/-f style flags.
"rm\\s+-[rRf]+": "ask",
// Allow it on a single temp target: /tmp/<name>, or a shell variable whose
// name contains tmp/temp, e.g. "$tmp" or "${tempdir}".
"rm\\s+-[rRf]+\\s+(\"?/tmp/[\\w.-][\\w./-]*\"?|\"?\\$\\{?\\w*(tmp|TMP|temp|TEMP)\\w*\\}?\"?)": "allow",
// Ask again if such an rm has a target that is not a single temp path.
"rm\\s+-[rRf]+\\s+(?!(\"?/tmp/[\\w.-][\\w./-]*\"?|\"?\\$\\{?\\w*(tmp|TMP|temp|TEMP)\\w*\\}?\"?)\\s*([;&|)'\\n]|$))": "ask",
// Ask ".." targets, even under /tmp.
"rm\\s+-[rRf]+\\s+.*\\.\\.": "ask",
},
}
rm -rf /tmp/build, rm -f /tmp/x.log, and rm -rf "$tmp" run without
prompting. rm -rf ./build, rm -rf /tmp/a /tmp/b, and rm -rf /tmp/../etc
ask for confirmation. These regexes are convenience rules, not a guarantee
that a command only affects temporary files.
Per-project override
Global ~/.pi/agent/permissions.jsonc:
{
"edit": {
"**": "allow",
},
}
Project my-app/.pi/agent/permissions.jsonc:
{
"edit": {
"**": "allow",
"**/package.json": "ask",
},
}
With my-app as Pi's working directory, edits to package.json require
approval. Other edits are allowed.
Comparison with pi-permission-system
| Feature | pi-minimal-permission-system (this project) |
pi-permission-system |
|---|---|---|
| Philosophy | Minimal, aligned with Pi's design | More feature-rich |
| Permission layers | Global + project-local only | Global + project-local + granular subagent permissions |
| Subagent permissions | ❌ Not supported (intentionally) | ✅ Supported |
| Filesystem tool granularity | ✅ read, edit, write controlled independently |
❌ Not currently supported |
| Command filtering | ✅ Regex-based bash rules | ✅ Supported |
| MCP / extension tools | ❌ Not supported (intentionally) | ✅ Supported |
| Config format | JSONC | JSONC/YAML |
When to choose this extension:
- You want a minimal permission system that stays out of your way.
- You do not need per-subagent or MCP tool permission overrides.
- You want granular filesystem control — for example, allowing the agent to
readsecrets but nevereditorwritethem.
When to choose pi-permission-system:
- You need subagent-level permission granularity (e.g. different policies for different agent roles or chains).
Development
Run npm run check to type-check the code and run all tests. Use
npm run typecheck or npm test to run either check separately.
Integration tests use Pi's real codemode tool with isolated configuration and a deterministic provider. They require Pi 0.99.1 or a compatible release and make no external model requests.