@the-forge-flow/security-harness-pi
Security harness for the PI coding agent — forbids dangerous commands and gates sensitive ones behind user approval
Package details
Install @the-forge-flow/security-harness-pi from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@the-forge-flow/security-harness-pi- Package
@the-forge-flow/security-harness-pi- Version
0.1.2- Published
- May 14, 2026
- Downloads
- 70/mo · 27/wk
- Author
- the-forge-flow-ai
- License
- MIT
- Types
- extension
- Size
- 1.5 MB
- Dependencies
- 2 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
What it does
PI extension that intercepts every tool call from the pi coding agent and classifies it against a policy: hard-forbid the obviously dangerous, ask-first on the sensitive, allow everything else. Commands are parsed into an AST and every simple-command inside pipes, $(...), eval, and bash -c is classified independently. Parse errors fail closed.
Features
- Hard-forbid —
sudo,rm -rf /,curl | sh, reverse shells, system-path writes, credential reads — blocked with no prompt - Ask-first —
git pushto the default branch, force-push,git merge, package installs across ecosystems (npm/yarn/pnpm/bun/cargo/brew/go/gem/composer/poetry/uv/deno),rm -rf <any>, writes/reads of.env/ secrets / CI files, dynamic interpreter calls (python -c,node -e), any command piped into a shell - Allow — anything not matched by a rule
- AST-based parsing — pipes, subshells,
eval,bash -cclassified independently; argv0 must be a literal (no$RM -rf /) - Two-tier config — global can tighten and relax, project can only tighten; an agent with project write access cannot weaken global rules
- 329 tests including a dedicated adversarial bypass suite
Requirements
- Node.js >= 22.5.0
- PI (
piCLI) installed
Installation
# Global (all projects)
pi install npm:@the-forge-flow/security-harness-pi
# Project-local
pi install -l npm:@the-forge-flow/security-harness-pi
# From GitHub (tracks main)
pi install git:github.com/MonsieurBarti/security-harness-pi
# Pin a version
pi install npm:@the-forge-flow/security-harness-pi@0.1.1
Then reload PI with /reload (or restart it).
Commands
/security-status— active rules, config sources, recent decisions/security-reload— reload config without restarting PI
Configuration
Configuration files (both optional):
- Global (can tighten and relax):
~/.pi/agent/security-harness.json - Project (tighten only):
<project>/.pi/security-harness.json
Minimal config (use all defaults)
{ "enabled": true }
Tighten a project
{
"forbid": [
"Bash(./scripts/deploy-prod.sh)",
"Write(.env.production)"
],
"ask": [
"Bash(docker system prune:*)"
]
}
Opt out of a baked-in rule (global only)
{
"disable": ["default:forbid.eval"],
"mode": "enforce"
}
Project-level disable, enabled, and mode are ignored with a warning — an agent with project write access cannot relax global settings.
See docs/rules.md for the full pattern grammar and handler catalogue.
Pattern grammar (quick reference)
[!]<Tool>(<inner>)[@<handler>[(<args>)]][|<piped-into>]
| Pattern | Matches |
|---|---|
Bash(rm:*) |
rm with any args |
Bash(rm -rf:*) |
rm with first arg -rf |
Bash(git push) |
exact git push (no args) |
Bash(npm install:+) |
npm install with a package name |
Bash(curl:*)|sh |
curl piped into sh |
Bash(git push)@default-branch |
push targeting the repo's default branch |
Write(.env*) |
writes matching a glob |
Read(~/.ssh/id_*) |
reads of a home-rooted glob |
!Bash(rm:-i*) |
negation (exclude interactive rm) |
Modes
enforce(default) — block per policywarn— never block; log what would have been blocked (for dry runs / rule development)
Limitations
Static analysis can't cover everything. What this does NOT protect against:
- Variable expansion —
RM=/bin/rm; $RM -rf /— mitigated by forbidding any simple-command whose argv0 is not a literal - Dynamic interpreter contents —
python -c "..."— routed to ask-first, human inspects - Race conditions — agent writes a script then executes it — only the
bash ./script.shcall is visible - Side-channels — agent reads a file and embeds content in response — not a command, can't intercept
See docs/threat-model.md for the full list and the recommended layering strategy.
Development
bun install
bun run test # vitest
bun run lint # biome check
bun run typecheck # tsc --noEmit
bun run build # tsc → dist/
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing) - Commit with conventional commits (
git commit -m "feat: add something") - Push to the branch (
git push origin feature/amazing) - Open a Pull Request
License
MIT © 2026 MonsieurBarti