@gotgenes/pi-permission-system 20.4.1 → 20.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/docs/configuration.md +101 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [20.4.2](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v20.4.1...pi-permission-system-v20.4.2) (2026-07-13)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* **pi-permission-system:** add read-only bash command allowlist recipe ([#521](https://github.com/gotgenes/pi-packages/issues/521)) ([6e9710f](https://github.com/gotgenes/pi-packages/commit/6e9710fb4564d99721a8e077839d567af326f3cc))
|
|
14
|
+
|
|
8
15
|
## [20.4.1](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v20.4.0...pi-permission-system-v20.4.1) (2026-07-12)
|
|
9
16
|
|
|
10
17
|
|
package/docs/configuration.md
CHANGED
|
@@ -639,6 +639,107 @@ Avoid arrays, multi-line scalars, and YAML anchors.
|
|
|
639
639
|
}
|
|
640
640
|
```
|
|
641
641
|
|
|
642
|
+
### Read-Only Bash Command Allowlist
|
|
643
|
+
|
|
644
|
+
The [Read-Only Mode](#read-only-mode) recipe above gates *tools*; this one gates the *bash* surface.
|
|
645
|
+
It allows a curated set of commands whose only effect is to read or report — none can create or modify a file, register, or system state by itself — while every other command falls through to `ask`.
|
|
646
|
+
|
|
647
|
+
```jsonc
|
|
648
|
+
{
|
|
649
|
+
"permission": {
|
|
650
|
+
"*": "ask",
|
|
651
|
+
"write": "deny",
|
|
652
|
+
"edit": "deny",
|
|
653
|
+
"path": {
|
|
654
|
+
"*": "allow",
|
|
655
|
+
"*.env": "deny",
|
|
656
|
+
"*.env.*": "deny",
|
|
657
|
+
"~/.ssh/*": "deny"
|
|
658
|
+
},
|
|
659
|
+
"bash": {
|
|
660
|
+
"*": "ask",
|
|
661
|
+
|
|
662
|
+
// File inspection
|
|
663
|
+
"cat *": "allow",
|
|
664
|
+
"head *": "allow",
|
|
665
|
+
"tail *": "allow",
|
|
666
|
+
"less *": "allow",
|
|
667
|
+
"more *": "allow",
|
|
668
|
+
|
|
669
|
+
// Listing and metadata
|
|
670
|
+
"ls *": "allow",
|
|
671
|
+
"tree *": "allow",
|
|
672
|
+
"stat *": "allow",
|
|
673
|
+
"file *": "allow",
|
|
674
|
+
"wc *": "allow",
|
|
675
|
+
"du *": "allow",
|
|
676
|
+
"df *": "allow",
|
|
677
|
+
|
|
678
|
+
// Search (find/fd with -exec are auto-floored to ask)
|
|
679
|
+
"grep *": "allow",
|
|
680
|
+
"egrep *": "allow",
|
|
681
|
+
"fgrep *": "allow",
|
|
682
|
+
"rg *": "allow",
|
|
683
|
+
"find *": "allow",
|
|
684
|
+
"fd *": "allow",
|
|
685
|
+
|
|
686
|
+
// Comparison and hashing
|
|
687
|
+
"diff *": "allow",
|
|
688
|
+
"cmp *": "allow",
|
|
689
|
+
"comm *": "allow",
|
|
690
|
+
"md5sum *": "allow",
|
|
691
|
+
"sha1sum *": "allow",
|
|
692
|
+
"sha256sum *": "allow",
|
|
693
|
+
"cksum *": "allow",
|
|
694
|
+
|
|
695
|
+
// System info
|
|
696
|
+
"pwd": "allow",
|
|
697
|
+
"whoami": "allow",
|
|
698
|
+
"id": "allow",
|
|
699
|
+
"hostname": "allow",
|
|
700
|
+
"uname *": "allow",
|
|
701
|
+
"date": "allow",
|
|
702
|
+
"uptime": "allow",
|
|
703
|
+
"ps *": "allow",
|
|
704
|
+
"printenv *": "allow",
|
|
705
|
+
"which *": "allow",
|
|
706
|
+
"type *": "allow",
|
|
707
|
+
|
|
708
|
+
// Git read-only subcommands (never a broad "git *")
|
|
709
|
+
"git status": "allow",
|
|
710
|
+
"git diff *": "allow",
|
|
711
|
+
"git log *": "allow",
|
|
712
|
+
"git show *": "allow",
|
|
713
|
+
"git blame *": "allow",
|
|
714
|
+
"git ls-files *": "allow",
|
|
715
|
+
"git branch": "allow",
|
|
716
|
+
"git remote -v": "allow"
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
Four existing behaviors keep this allowlist safe — you do not have to enumerate the destructive commands to block them:
|
|
723
|
+
|
|
724
|
+
1. **Redirects are gated by the `path` surface, not `bash`.**
|
|
725
|
+
Allowing `cat *` allows the `cat` command, not a redirect it carries: `cat secret > out.txt` writes `out.txt` through the `path`/`external_directory` gate.
|
|
726
|
+
That is why this recipe ships with `write` and `edit` denied and a `path` deny block for sensitive files.
|
|
727
|
+
Keep the `path` surface locked down for anything you would not want an allowed read command to overwrite via `>`.
|
|
728
|
+
2. **`find`/`fd` with an exec flag are floored to `ask`.**
|
|
729
|
+
A bare `find *` search is read-only, so it is safe to allow; the moment an exec flag appears (`find -exec`/`-execdir`/`-ok`/`-okdir`, `fd -x`/`-X`), the [indirection-wrapper floor](#fail-closed-behavior) clamps the decision back to `ask`.
|
|
730
|
+
So `find . -type f -exec rm {} +` still prompts even under `find *: allow`.
|
|
731
|
+
3. **Chained commands resolve most-restrictive.**
|
|
732
|
+
`find . -name '*.log' && rm -f found.log` decomposes into `find …` and `rm …`; `rm` matches only `"*": "ask"`, and the most restrictive result governs the whole invocation, so the chain prompts.
|
|
733
|
+
4. **Wrappers cannot ride the allowlist.**
|
|
734
|
+
`sudo grep …`, `env X=1 cat …`, `sh -c "…"`, and `eval "…"` are floored to `ask` (the [wrapper floors](#fail-closed-behavior)), so an allowed command cannot be smuggled past through a wrapper.
|
|
735
|
+
|
|
736
|
+
`git` is enumerated by read subcommand rather than a broad `git *`, because `git` has mutating subcommands (`commit`, `push`, `branch -D`, `remote add`, `config <key> <value>`).
|
|
737
|
+
Exact patterns like `git status` and `git branch` match only their literal form, so `git branch -D feature` falls through to `"*": "ask"`.
|
|
738
|
+
The `*`-suffixed git patterns (`git diff *`, `git log *`) are safe because those subcommands are read-only regardless of their arguments.
|
|
739
|
+
|
|
740
|
+
Commands that can originate a write are deliberately omitted: `echo` and `printf` are the usual content source for a `>` redirect, `tee` writes its input to a file, and `sort -o`, `sed -i`, and in-place `awk` redirects modify files directly.
|
|
741
|
+
Add them only if you understand that pairing them with `write: deny` and a strict `path` surface is what keeps them from writing.
|
|
742
|
+
|
|
642
743
|
### MCP Discovery Only
|
|
643
744
|
|
|
644
745
|
```jsonc
|