mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 18:55:22 +00:00
142 lines
11 KiB
Markdown
142 lines
11 KiB
Markdown
<p align="center">
|
|
<img src="docs/assets/logo.png" alt="pi-permission-system logo">
|
|
</p>
|
|
|
|
# @gotgenes/pi-permission-system
|
|
|
|
[](https://www.npmjs.com/package/@gotgenes/pi-permission-system) [](https://github.com/gotgenes/pi-packages/actions/workflows/ci.yml) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/) [](https://pnpm.io/) [](https://pi.mariozechner.at/)
|
|
|
|
Permission enforcement extension for the [Pi](https://pi.mariozechner.at/) 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](https://github.com/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
|
|
|
|
```bash
|
|
pi install npm:@gotgenes/pi-permission-system
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
1. Create ordinary policy at `~/.pi/agent/extensions/pi-permission-system/policy.jsonc`:
|
|
|
|
```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`:
|
|
|
|
```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](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](docs/configuration.md) for the complete reference and [docs/hard-guards.md](docs/hard-guards.md) for the independent hard-guard format.
|
|
|
|
## Documentation
|
|
|
|
| Document | Contents |
|
|
| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
| [docs/configuration.md](docs/configuration.md) | Full policy reference, runtime knobs, per-agent overrides, recipes |
|
|
| [docs/session-approvals.md](docs/session-approvals.md) | Session-scoped rules, pattern suggestions, bash arity table |
|
|
| [docs/cross-extension-api.md](docs/cross-extension-api.md) | Cross-extension service accessor, event bus integration, prompt and decision broadcasts |
|
|
| [docs/subagent-integration.md](docs/subagent-integration.md) | Permission forwarding, coexistence with subagent extensions |
|
|
| [docs/guides/permission-frontmatter-for-subagent-extensions.md](docs/guides/permission-frontmatter-for-subagent-extensions.md) | Convention guide for subagent extension authors |
|
|
| [docs/opencode-compatibility.md](docs/opencode-compatibility.md) | OpenCode compatibility — shared concepts, divergences, porting guide |
|
|
| [docs/troubleshooting.md](docs/troubleshooting.md) | Common issues, diagnostic logging, threat model |
|
|
| [docs/migration/legacy-to-flat.md](docs/migration/legacy-to-flat.md) | Migration from pre-v2 config layout |
|
|
| [docs/migration/strict-config-validation.md](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](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](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](docs/migration/0746-review-log-fields.md) | Review-log fields (breaking) — `message` replaced by request facts, and the `reviewLogFieldMaxWidth` bound |
|
|
|
|
## Development
|
|
|
|
```bash
|
|
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](https://prek.j178.dev/) 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](https://github.com/MasuRii/pi-permission-system).
|
|
Thank you to [MasuRii](https://github.com/MasuRii) for the original work that made this possible.
|
|
|
|
Thank you to the [OpenCode](https://opencode.ai) team for the permission model design that inspired the flat config format and evaluation semantics used in this extension.
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|