Files
my-pi/pi-permission-system
云服务部-叶林立 879fc5d37f docs(upstream): 将 UPSTREAM.md 来源记录统一改为中文维护
把 12 份 UPSTREAM.md 来源记录全部翻译为中文,并把中文定为这份仓库自有
维护文档的强制语言。

- 翻译 hippo-memory-pi、pi-ask-user、pi-chrome、pi-compaction、
  pi-extension-codex-fast-mode、pi-minimal-footer、pi-notify、
  pi-permission-system/docs/auto-review、pi-ssh、pi-subagents 与
  pi-tool-search 的来源记录。
- 在 AGENTS.md 增加纪律:每个自维护扩展目录必须保留中文 UPSTREAM.md,
  内容涵盖官方仓库、tag/commit、导入版本、导入日期、许可证归属、本地
  改动清单与同步上游时的约束。
- 明确边界:UPSTREAM.md 属于仓库自有的维护文档,因此使用中文;上游自带
  的源码、测试、文档、README、CHANGELOG 与 LICENSE 一律保持原文,不翻
  译、不改写,避免同步上游时产生无意义 diff 并破坏许可证原文完整性。
- 所有 40 位 commit、tag/版本号、仓库 URL 与许可证路径原样保留,仅翻译
  叙述性文字。

验证:12 份文件均无残留英文正文;逐份复核了 commit、版本、URL 与
LICENSES/ 路径未发生改变。
2026-10-13 23:19:01 -07:00
..
2026-08-19 14:35:19 +08:00

pi-permission-system logo

@gotgenes/pi-permission-system

npm version CI License: MIT TypeScript pnpm Pi Package

Permission enforcement extension for the Pi coding agent that provides centralized, deterministic permission gates over tool, bash, MCP, skill, and special operations.

Fork notice: This package is a full fork of MasuRii/pi-permission-system, published to npm as @gotgenes/pi-permission-system. It has diverged substantially from upstream in config format, internal architecture, and permission model.

my-pi maintenance note: This directory was imported from upstream tag pi-permission-system-v26.2.1 at commit ec4fdb11343dc94f7185b113e559a4cf9f8dc035. It is loaded from source and maintained directly by my-pi; npm dist output is not used. my-pi uses one global ordinary policy and a separate non-overridable hard-guard file; explicitly configured authorizers may approve any ordinary-policy ask, including path.

What It Does

  • Enforces allow / ask / deny at tool-call time with UI confirmation dialogs
  • Uses one global ordinary policy file; project policy.jsonc files are not loaded
  • Chooses the most specific matching pattern, so a specific deny wins over a broad "*": "allow" regardless of declaration order
  • Applies a separate hard-guard policy first so session grants, per-agent rules, and model review cannot override high-risk denies
  • Controls Bash, paths, MCP, skills, and tool surfaces while leaving active-tool ownership entirely to Tool Search
  • Reviews ordinary ask requests automatically with integrated AutoReview; its allow / deny verdict is final for ordinary tools and path, while defer reaches the next authorizer or human terminal
  • Forwards subagent ask decisions to the parent authority and keeps structured audit logs

Install

pi install npm:@gotgenes/pi-permission-system

Quick Start

  1. Create ordinary policy at ~/.pi/agent/extensions/pi-permission-system/policy.jsonc:

    {
      "authorizerChain": ["auto-review"],
      "permission": {
        "*": "ask",
        "read": "allow",
        "bash": {
          "*": "ask",
          "git status*": "allow"
        }
      }
    }
    
  2. Create independent hard guards at ~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc:

    {
      "version": 1,
      "permission": {
        "*": "allow",
        "*.env": "deny",
        "*.env.*": "deny",
        "*.env.example": "allow",
        "~/.ssh/**": "deny"
      }
    }
    
  3. Restart Pi or run /reload. Ordinary ask requests now reach AutoReview first; only defer opens the human dialog.

The path surface is a cross-cutting gate that applies to all file access — Pi tools, bash commands, MCP calls, and extension tools alike. Extension and MCP tools that operate on paths (via input.path, MCP's input.arguments.path, or a registered access extractor) are gated by default, so a path deny cannot be overridden by a per-tool allow — making it the right place to protect sensitive files like .env or ~/.ssh/* from every tool at once. A path pattern matches both the path as the agent references it and its canonical (symlink-resolved) form, so a deny still fires when a symlink aliases a sensitive target.

For per-tool path patterns (read, write, edit, find, grep, ls), patterns are matched against the file path from input.path. This lets you express rules like "allow reads but deny .env files" at the individual tool level. Like the cross-cutting path surface, per-tool patterns match both the referenced path and its canonical (symlink-resolved) form, so a per-tool deny resists symlink-alias evasion. When Pi's current working directory is known, relative path inputs also match their cwd-normalized absolute form, so src/App.jsx can match both src/* and /workspace/project/*.

Paths outside the working tree have no separate boundary gate. Configure them with the same path, per-tool, and Bash patterns used for in-project paths. These layers still compose with most-restrictive-wins. See docs/configuration.md for the full recipe.

Configuration

The integrated extension uses two independent global JSONC files:

Purpose Scope Path
Ordinary policy, runtime knobs, AutoReview Global only ~/.pi/agent/extensions/pi-permission-system/policy.jsonc
Non-overridable hard guards Global only ~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc

Project-level policy.jsonc files are ignored. Project agent Markdown remains a separate per-agent restriction mechanism.

The bundle seeds missing files with mode 0600. During update.sh, only the exact known legacy default policy is backed up and replaced by the current bundled seed. Any customized or invalid policy is preserved and reported instead of being guessed or overwritten.

Within a pattern map, the most specific match wins: exact patterns, then more literal characters, fewer wildcards, and longer patterns. Declaration order is only a tie-breaker.

There is no external_directory gate. Outside-CWD paths use the same configured tool, path, and Bash rules as other paths.

Tool Search alone owns Pi's active tool list. Permission System only decides whether an invoked tool call is allowed, denied, or requires confirmation.

See docs/configuration.md for the complete reference and docs/hard-guards.md for the independent hard-guard format.

Documentation

Document Contents
docs/configuration.md Full policy reference, runtime knobs, per-agent overrides, recipes
docs/session-approvals.md Session-scoped rules, pattern suggestions, bash arity table
docs/cross-extension-api.md Cross-extension service accessor, event bus integration, prompt and decision broadcasts
docs/subagent-integration.md Permission forwarding, coexistence with subagent extensions
docs/guides/permission-frontmatter-for-subagent-extensions.md Convention guide for subagent extension authors
docs/opencode-compatibility.md OpenCode compatibility — shared concepts, divergences, porting guide
docs/troubleshooting.md Common issues, diagnostic logging, threat model
docs/migration/legacy-to-flat.md Migration from pre-v2 config layout
docs/migration/strict-config-validation.md Strict config validation (breaking) — rejected configs, and the cross-scope fail-closed clamp
docs/migration/0644-project-trust-gating.md Project-trust gating (breaking) — project config loads only after project trust
docs/migration/0745-prompt-payload-contracts.md Prompt payload contracts (breaking) — the forwarded wire, the ui_prompt broadcast, and the deprecated preview caps
docs/migration/0746-review-log-fields.md Review-log fields (breaking) — message replaced by request facts, and the reviewLogFieldMaxWidth bound

Development

pnpm run check       # Type-check TypeScript (no emit)
pnpm run lint        # Biome + ESLint + lint:md
pnpm run lint:md     # rumdl on README and docs
pnpm run test        # Run tests from ./test
pnpm run test:watch  # Run tests in watch mode

Pre-commit hooks

This project uses prek to run Biome, ESLint, and rumdl on staged files before each commit. Run pnpm install to set up hooks automatically.

Acknowledgments

This project began as a fork of MasuRii/pi-permission-system. Thank you to MasuRii for the original work that made this possible.

Thank you to the OpenCode team for the permission model design that inspired the flat config format and evaluation semantics used in this extension.

License

MIT