pi-permissions
v1.0.4
Published
Configurable allow/deny permission rules for pi tool calls — control which bash commands, file reads, writes, and edits the agent can perform.
Downloads
166
Maintainers
Readme
pi-permissions

A pi extension that provides configurable allow/deny permission rules for tool calls — control which bash commands, file reads, writes, and edits the agent can perform.
- Define allow rules to whitelist specific commands
- Define deny rules to block dangerous operations
- Deny always wins — block
git pusheven ifgit *is allowed - Supports glob patterns with
*wildcards - Project-local or global configuration
Install
pi install npm:pi-permissionsFrom the public git repo:
pi install git:github.com/NicoAvanzDev/pi-permissionsFrom a local clone:
pi install .Load without installing:
pi --no-extensions -e npm:pi-permissionsQuick start
Create .pi/permissions.json in your project (or ~/.pi/agent/permissions.json for global rules):
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(npm test *)",
"Bash(git commit *)",
"Bash(git diff *)",
"Bash(git status)",
"Bash(git log *)"
],
"deny": [
"Bash(git push *)",
"Bash(rm -rf *)",
"Write(*.env)",
"Edit(*.env)"
]
}
}On session start, the extension loads your rules and reports how many were found. Any tool call that matches a deny rule is blocked before execution.
Example session
> pi
Permissions loaded: 6 allow, 4 deny rules
> (agent tries to run `git push origin main`)
⛔ Blocked: Bash command matches deny rule "Bash(git push *)"After editing permissions.json, type /reload in pi to apply the changes.
How it works
Rule format
Rules use the format Tool(pattern) where:
- Tool — the pi tool name:
Bash,Write,Edit,Read - pattern — a glob pattern where
*matches any characters
Supported tools
| Tool | What the pattern matches against |
|------|----------------------------------|
| Bash(pattern) | The bash command string |
| Write(pattern) | The file path being written |
| Edit(pattern) | The file path being edited |
| Read(pattern) | The file path being read |
Evaluation logic
For every tool call the extension:
- checks deny rules first — if any deny rule matches, the call is blocked
- checks allow rules next — if allow rules exist for that tool, the call must match at least one
- passes through — if no allow rules exist for the tool, all calls are permitted (unless denied)
This means:
- Use deny to block specific dangerous commands
- Use allow to whitelist only approved commands (everything else is blocked)
- Deny always wins over allow
Pattern examples
| Pattern | Matches | Doesn't match |
|---------|---------|---------------|
| Bash(git push *) | git push origin main | git pull |
| Bash(npm run *) | npm run build, npm run test | npm install |
| Bash(* --version) | node --version, npm --version | node index.js |
| Write(*.env) | .env, app.env | .env.example |
| Write(secrets/*) | secrets/key.pem | src/secrets.ts |
Configuration
| Location | Scope |
|----------|-------|
| .pi/permissions.json | Project-local (checked first) |
| ~/.pi/agent/permissions.json | Global fallback |
The extension checks the project-local path first. If not found, it falls back to the global config.
Notes
- rules are loaded once on session start
- use
/reloadto pick up changes without restarting - deny rules are always evaluated before allow rules
- if no allow rules exist for a tool type, all calls for that tool are permitted
- glob
*matches any sequence of characters (including path separators in file patterns)
License
MIT
