@aliou/pi-guardrails

![banner](https://assets.aliou.me/github/aliou/pi-guardrails/banner.png)

Packages

Package details

extension

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

$ pi install npm:@aliou/pi-guardrails
Package
@aliou/pi-guardrails
Version
0.21.0
Published
Oct 27, 2026
Downloads
4,827/mo · 1,420/wk
Author
aliou
License
MIT
Types
extension
Size
275.1 KB
Dependencies
2 dependencies · 2 peers
Pi manifest JSON
{
  "image": "https://assets.aliou.me/github/aliou/pi-guardrails/banner.png",
  "video": "https://assets.aliou.me/github/aliou/pi-guardrails/demo.mp4",
  "extensions": [
    "./extensions/path-access/index.ts",
    "./extensions/guardrails/index.ts",
    "./extensions/permission-gate/index.ts",
    "./extensions/herdr/index.ts"
  ]
}

Security note

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

README

banner

Guardrails

Guardrails adds safety checks to Pi so agents are less likely to read secrets, write protected files, access paths outside the workspace, or run dangerous shell commands by accident.

This package installs four Pi extensions:

  • guardrails for file protection policies, settings, onboarding, and examples.
  • path-access for controlling access outside the current workspace.
  • permission-gate for confirming or blocking risky shell commands.
  • herdr for reporting Guardrails approval prompts to Herdr.

Install

pi install npm:@aliou/pi-guardrails

First run

After installing, run the onboarding command to choose a starting setup:

/guardrails:onboarding

Guardrails onboarding walkthrough

You can change everything later with:

/guardrails:settings

Included extensions

guardrails

The guardrails extension owns file protection policies and the user-facing commands.

Use it to protect files like .env, private keys, local credentials, generated logs, database dumps, or any project-specific path you do not want Pi to read or modify without clear intent.

Policy rules respect the working directory by default (respectCwd: true): a location-anchored pattern (~- or /-prefixed glob such as ~/work/**) that happens to contain the session's cwd does not neuter the workspace. Name-based patterns (.env), relative path globs, and regex patterns still apply inside the cwd, so secrets stay protected. Set respectCwd: false on a rule to enforce anchored patterns everywhere.

Anchored patterns are matched against every equivalent spelling of a target (cwd-relative, ~/…, and absolute), so a ~/…-anchored rule holds no matter where the session starts or how the tool input spelled the path.

Guardrails policies and settings walkthrough

Useful commands:

/guardrails:settings
/guardrails:onboarding
/guardrails:examples

Herdr integration

The included Herdr adapter reports active Guardrails approval prompts through Herdr's herdr:blocked event. Herdr can then show the Pi pane as blocked while it waits for a permission-gate or path-access decision.

The adapter has no configuration or direct Herdr dependency. Its emitted events have no effect unless Herdr's Pi integration is active.

path-access

The path-access extension checks tool calls that target paths outside the current working directory.

It can allow, block, or ask before Pi accesses files elsewhere on your machine. In ask mode, you can allow one file or a directory once, for the session, or always.

Which operations are gated is controlled by pathAccess.applyTo: "all" (default) gates reads and writes outside the workspace, "write" gates writes only so read-only tools (read, grep, find, ls) can access skill and config files outside the project without a prompt. Bash commands are still gated: a command can write. Configurable through /guardrails:settings (Path Access → Applies to).

Bash commands can always use their own standard streams and terminal — /dev/stdin, /dev/stdout, /dev/stderr, /dev/tty, and /dev/fd/0–/dev/fd/2 — without configuration. Other /dev/* paths and the same devices reached through in-process tools still follow the normal rules.

Where "always" grants are saved is controlled by pathAccess.alwaysScope: "local" (default) writes them to the project config ({project}/.pi/extensions/guardrails.json), "global" writes them to the user-wide config (~/.pi/agent/extensions/guardrails.json) so they apply in every project. Session grants stay in memory and "once" grants are not persisted, regardless of this setting. Configurable through /guardrails:settings (Path Access → Always-grant scope).

Granted paths are stored in pathAccess.allowedPaths as explicit { kind, path } entries: file matches the exact path, directory matches the directory and its descendants. Edit them through /guardrails:settings (Path Access → Allowed paths, Tab toggles file/directory) or directly in the settings file. Paths support ~/ for home. Existing configs using the legacy string form (trailing / for directories) are migrated automatically.

Guardrails path access prompt walkthrough

permission-gate

The permission-gate extension detects dangerous bash commands before they run.

It catches built-in risky patterns like recursive deletes, privileged commands, disk formatting, broad permission changes, and configured custom patterns. You can allow once, allow for the session, deny, decline and stop (which also aborts the current turn), or configure auto-deny rules.

Auto-deny patterns support an optional terminate: true flag (pi >= 0.84.1): after blocking, the agent's turn ends instead of yielding back to the model, so it does not retry the blocked command. The turn only ends when every blocked call in the batch sets terminate. Example:

{
  "permissionGate": {
    "autoDenyPatterns": [
      {
        "pattern": "sleep ",
        "description": "do not sleep-wait; the process tool notifies you on exit",
        "terminate": true
      }
    ]
  }
}

Guardrails permission gate walkthrough

Shell substitution checks

Built-in dangerous-command checks, file policies, and path-access extraction inspect commands inside command substitutions ($(...) and backticks) and process substitutions (<(...) and >(...)), including nested substitutions and expanded redirect targets. For example, echo "$(cat .env)" exposes the inner file access, while echo "$(echo .env)" still treats .env as text.

These checks inspect executable nodes provided by the shell parser; they do not evaluate expansions or reparse literal text. Single-quoted text and heredoc delimiters are not executable substitutions. The current parser leaves some constructs as raw text — heredoc bodies (note an unquoted heredoc body executes $(...) in bash), expansion operands such as ${value:-$(...)}, and extglob patterns such as @($(cmd)) — so substitutions in those locations remain outside this traversal.

Extension events

Guardrails emits paired prompt lifecycle events on Pi's shared event bus:

  • guardrails:prompt:opened when an interactive Guardrails prompt starts waiting for input.
  • guardrails:prompt:closed when that prompt stops waiting, including when the UI throws.

Both events include the same prompt.id for correlation.

Configuration

Most configuration should happen through the interactive settings UI:

/guardrails:settings

Advanced users can edit the settings file directly:

  • Global: ~/.pi/agent/extensions/guardrails.json
  • Project: .pi/extensions/guardrails.json

Guardrails writes a $schema field to saved settings files, so modern editors provide autocomplete and validation. The generated schema is committed at schema.json.

Examples

Use the examples command to add common policy and command presets without replacing your existing config:

/guardrails:examples

Guardrails examples command walkthrough

The available presets live in extensions/guardrails/commands/settings/examples.ts.

Similar but different

Pi is designed to make agent safety extensible. Guardrails focuses on deterministic, configurable file policies, outside-workspace path access, and dangerous-command prompts. Other packages tend to fall into two useful groups.

See pi.dev/packages for the full registry of Pi extensions.

Make one yourself!

If Guardrails or the alternatives below do not fit your needs, you can also make your own. Start from the Pi permission gate example, then ask Pi to customize it for your workflow.

Permission and policy gates

These packages add checks around tool calls before they run. They are closest to Guardrails when you want policy enforcement without changing where Pi executes.

Sandboxes and containment

These packages reduce blast radius by running Pi, subagents, or tool calls inside a constrained environment. They can be a better fit when you want isolation first and prompts second.

Development

pnpm test         # Run tests
pnpm test:watch   # Run tests in watch mode
pnpm typecheck    # Type check
pnpm lint         # Lint
pnpm format       # Format
pnpm gen:schema   # Regenerate schema.json
pnpm check:schema # Verify schema.json is current