@wernerbisschoff/pi-gatekeeper

Permission enforcement extension for Pi/OMP

Packages

Package details

extension

Install @wernerbisschoff/pi-gatekeeper from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@wernerbisschoff/pi-gatekeeper
Package
@wernerbisschoff/pi-gatekeeper
Version
0.1.12
Published
Jul 8, 2026
Downloads
1,852/mo · 105/wk
Author
wernerbisschoff
License
unknown
Types
extension
Size
312.4 KB
Dependencies
2 dependencies · 0 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/gatekeeper.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-gatekeeper

Permission enforcement extension for Pi/OMP.

Gatekeeper replaces pi's bash tool with a mode-aware wrapper that classifies shell commands against configurable allow/deny/ask rules and blocks access to sensitive file paths (.env, ~/.ssh/, crypto keys, etc.). It's designed as a security layer for teams that share pi configurations or want guardrails without leaving the terminal.

Install

# Global (all projects)
pi install npm:@wernerbisschoff/pi-gatekeeper

# Project-local
pi install npm:@wernerbisschoff/pi-gatekeeper -l

# Try once without installing
pi -e npm:@wernerbisschoff/pi-gatekeeper

Quick start

Once installed, gatekeeper runs automatically on every session_start. The default mode is ask.

Permission modes

The currentMode decides what happens to a command that matches no explicit rule. There is one rule file (no per-level cascade) and three runtime modes:

Mode What it does Best for
🟢 ALLOW Unknown commands pass through (no prompt) Trusted environments, sandboxed agents
🟡 ASK Unknown commands trigger a confirmation prompt Day-to-day development (default)
🔴 DENY Unknown commands are blocked (no prompt) Pair-programming observers, auditing
⚫ OFF Gatekeeper disabled — every bash command passes through Debugging the gatekeeper itself, full-trust runs

Headless / non-interactive sessions (no ctx.ui) always deny on a would-be ask — the off and headless cases are the only times the gatekeeper forces a deny.

Switch modes

Use the /gk slash command inside pi:

/gk         → cycle: allow → ask → deny → off → allow
/gk allow   → set explicitly
/gk ask     → set explicitly
/gk deny    → set explicitly
/gk off     → disable the gatekeeper (session-only)
/gk show    → print the resolved settings path and current rules

Or pass a CLI flag on startup:

pi --gk-mode allow
pi --gk-mode ask
pi --gk-mode deny

The CLI flag overrides the persisted mode for the current session only — the next session resumes at the persisted mode. /gk off is session-only by design: the persisted currentMode is always one of allow|ask|deny, and the off state is not written to disk. Cycling out of off advances to allow.

How it works

  1. On session start, gatekeeper bootstraps ~/.pi/agent/perm-rules.json from the bundled defaults (if absent), or loads the existing file.
  2. Every bash tool call is classified by the gatekeeper's classifier against the single deny / allow / ask rule lists. Blocked commands are rejected before execution.
  3. Sensitive paths (read/edit/write to .env, ~/.ssh/, *.pem, etc.) are blocked unconditionally regardless of mode — these are compile-time guards, not user-configurable.
  4. Mode changes persist to perm-rules.json and update the TUI footer indicator immediately.
  5. /gk off sets a session-only kill switch that bypasses the bash classifier (runPermissionGate returns immediately). The sensitive-path guard above stays active — off disables the per-mode rules, not the cross-cutting path guard.

Configuration

Edit ~/.pi/agent/perm-rules.json directly to customise the rule lists:

{
  "version": 3,
  "currentMode": "ask",
  "rules": {
    "deny": ["rm -rf /", "mkfs", "eval", "curl|sh"],
    "allow": ["ls", "ls *", "cat", "cat *", "git status", "git status *"],
    "ask": []
  }
}

Use /gk show inside pi to inspect the current rules and the resolved file path. The file supports three tri-state lists:

  • deny — commands that are always blocked, regardless of currentMode
  • allow — commands allowed without confirmation, regardless of currentMode
  • ask — commands that always trigger a confirmation prompt, regardless of currentMode
  • currentMode (allow | ask | deny) — the default for commands matching no rule

A v1/v2 file (with per-level low/medium/high rules) is migrated on first load: the three levels are unioned into a single flat rule set, the original is backed up as perm-rules.json.v<N>.bak, and the v3 shape is written in its place.

Sensitive paths (always blocked)

Pattern Reason
.env* Environment files (secrets)
~/.ssh/ SSH keys
~/.aws/ AWS credentials
~/.gnupg/ GPG keys
~/.kube/ Kubernetes config
*.pem, *.key, *.crt Crypto material
.netrc Generic credential store
.npmrc npm auth tokens
.pypirc PyPI credentials
.git-credentials Git plaintext credentials
~/.docker/config.json Docker registry auth
~/.config/gh/hosts.yml GitHub CLI tokens

These patterns are compile-time constants — they cannot be overridden by user config (by design).

Development

git clone https://github.com/wernerbisschoff/pi-gatekeeper.git
cd pi-gatekeeper
npm install
npm run build
npm test

Load locally during development

pi -e ./src/gatekeeper.ts

License

MIT