Rules / CFG134
CFG134 a pi project folder loads code or changes the commands pi runs
Severity: warn (a package with no fixed version, an extension, a package outside the repository, a shell or npm command override, an MCP ! command) · info (a pinned package, SYSTEM.md, an inert defaultProjectTrust)
OWASP: LLM03:2026 – Excessive Agency
Agents: pi
What cfgaudit checks
The pi coding agent reads a project .pi/ folder (#1055). The source and docs of v1.5.0 (packages/coding-agent) say:
- Trust. When
.pi/holdssettings.json,mcp.json,extensions,skills,prompts,themes,SYSTEM.mdorAPPEND_SYSTEM.md, pi asks once whether to trust the project (trust-manager.ts). Print, JSON and RPC modes skip the project resources unless--approveis passed. - After trust. Packages are installed at startup, extensions run in the pi process, and no tool call asks again. One "trust", or one
--approvein CI, covers all of it.
CFG134 reports what a committed .pi/ adds to that single decision:
| Source | Finding | Severity |
|---|---|---|
.pi/settings.json packages: an npm: spec without an exact version, or a git: or URL source without a ref |
pi installs it at startup and runs its extensions, so the code follows the registry or branch. warn, like an unpinned npx MCP server (CFG010) |
warn |
packages: a pinned npm or git source |
third-party code that runs in the pi process | info |
packages: a local path outside the repository (~, absolute, or .. that climbs out of the repository; relative paths resolve from .pi/, so ../packages/x is the repository's packages/x) |
a package from the reader's machine | warn |
extensions entries, and every .pi/extensions/*.ts, *.js or <dir>/index.ts, index.js |
a TypeScript module in the pi process that can run commands and block or rewrite tool calls | warn |
shellPath, shellCommandPrefix ("Prefix prepended to every shell command"), npmCommand |
each changes every bash tool call or package install | warn |
a .pi/mcp.json env or headers value starting with ! |
pi runs the rest as a shell command when the server loads (resolve-config-value.ts) |
warn |
.pi/SYSTEM.md |
replaces pi's built-in system prompt | info |
defaultProjectTrust in the project file |
honoured only in the user's own settings, so it has no effect | info |
Command checks. shellCommandPrefix, npmCommand and the ! commands are also command sites, so the command-content rules (CFG014, CFG015, …) judge them. The shared MCP rules read .pi/mcp.json without its ! values, which are commands and not literal secrets.
Instruction content. These files go to the instruction-content rules:
.pi/SYSTEM.md,.pi/APPEND_SYSTEM.mdand.pi/prompts/*.md;.pi/skills/**/SKILL.md;AGENTS.override.md, which pi loads without trust, first among its context files.
Read from the source, not measured against a running pi.
Example
{
"packages": ["npm:@example/pi-tools", "git:github.com/example/pi-ext"],
"shellCommandPrefix": "source ./scripts/env.sh;"
}
Remediation
- Pin project packages to an exact npm version or a git tag or commit, and review them before trusting the project.
- Keep shell and npm overrides, and MCP values that run commands, in the user's own
~/.pi/agent/settings.
Documentation for cfgaudit 1.21.0. Source of this page · Rule implementation