7 Security
7.1 Project Trust
Project trust controls whether Pi loads project-local settings, resources, packages, and extensions. It is not a sandbox and it does not restrict what the model can ask tools to do after you start working in a directory.
7.1.1 What Requires Trust
Pi considers a project to have resources that require trust when it finds any of these from the current working directory:
.pi/settings.json.pi/extensions,.pi/skills,.pi/prompts, or.pi/themes.pi/SYSTEM.mdor.pi/APPEND_SYSTEM.md- Project
.agents/skillsin the current directory or an ancestor directory
A bare .pi directory does not count as a project resource that requires trust.
7.1.2 Trust Mechanism
When an interactive session starts in a project with resources that require trust and no saved decision exists, Pi follows defaultProjectTrust from global settings. The default value is "ask", which prompts the user.
Saved decisions are stored by canonical directory in ~/.pi/agent/trust.json. The closest saved decision on the current or parent path applies before the global default.
Trusting a project allows Pi to load:
.pi/settings.json- Pi resources (extensions, skills, prompt templates, themes, system prompt files)
- Missing project packages configured through project settings
- Project-local extensions and project package-managed extensions
Before trust is resolved, Pi only loads context files, user/global extensions, and CLI -e extensions. User/global extensions can handle the project_trust event; the first extension that returns a yes/no decision owns the decision.
7.1.3 Non-Interactive Modes
Non-interactive modes (-p, --mode json, --mode rpc) do not show a trust prompt. Without a saved trust decision:
"ask"(default) and"never"ignore project resources"always"trusts them
Pass --approve/-a or --no-approve/-na to override project trust for one run.
7.1.4 Managing Trust
Use /trust in interactive mode to save a project trust decision for future sessions, including trust for the immediate parent folder. It writes ~/.pi/agent/trust.json only; the current session is not reloaded, so restart Pi for changes to take effect.
Configure defaultProjectTrust in ~/.pi/agent/settings.json:
{
"defaultProjectTrust": "ask" // "ask", "always", or "never"
}7.2 No Built-in Sandbox
Pi does not include a built-in sandbox. This is an intentional design decision.
Built-in tools can read files, write files, edit files, and run shell commands with the permissions of the Pi process. Extensions are TypeScript modules that run with the same permissions. Package installs, shell commands, language servers, test commands, and other developer tools behave as ordinary local processes.
A partial in-process sandbox would be easy to misunderstand as a security boundary while still depending on the host shell, filesystem, package managers, credentials, and extension code. Real isolation needs to come from the operating system or a virtualization/container boundary.
7.2.1 Why Not a Partial Sandbox?
Pi is designed to operate on local source trees, invoke project toolchains, and integrate with the user’s existing development environment. Key reasons for not including a sandbox:
- False sense of security: A partial sandbox would still depend on host systems
- Complexity: Maintaining sandbox boundaries for every tool path adds significant complexity
- Breaks workflows: Sandboxes interfere with legitimate development tool access
- Already solved: Operating systems and containers provide proven isolation
7.2.2 Project Trust vs. Sandbox
Project trust is only an input-loading guard. It prevents a repository from silently changing Pi’s settings or extensions before you approve it. It does not make untrusted code, untrusted prompts, or untrusted model output safe.
Prompt injection from repository files, comments, documentation, context files, or build output is expected local-agent risk and cannot be reliably prevented by Pi.
7.3 Running Untrusted Work
For untrusted repositories, generated code you do not intend to monitor closely, or unattended automation, run Pi in a contained environment.
7.3.1 Best Practices
- Use a container, VM, micro-VM, remote sandbox, or policy-controlled sandbox with only the files and credentials required for the task
- Run the whole Pi process inside a container/sandbox (see Containerization)
- Run host Pi while routing built-in tool execution into a Gondolin micro-VM
- Mount only the workspace paths the agent should access
- Avoid mounting host
~/.pi/agentunless the container should access host sessions, settings, and credentials - Pass the minimum required API keys or use short-lived credentials
- Restrict network access when the task does not need it
- Review diffs and outputs before copying results back to trusted systems
If you bind-mount a host workspace read/write, writes from inside the container or VM can still modify host files. Use read-only mounts or copy files into and out of the sandbox when you need stronger protection from unintended writes.
7.3.2 Containerization Patterns
Three common patterns are documented in the Containerization chapter:
| Pattern | What Is Isolated | Best For |
|---|---|---|
| Gondolin | Built-in tools and ! commands |
Local micro-VM with host auth |
| Plain Docker | Whole Pi process | Simple local isolation |
| OpenShell | Whole Pi process in policy-controlled sandbox | Local or remote managed sandbox |
7.4 Reporting Security Issues
To report a security issue, follow the repository Security Policy. Do not open a public issue for security-sensitive reports.
7.4.1 What Is Not a Security Issue
The following are generally outside the security boundary unless the report demonstrates a real privilege-boundary bypass:
- Expected local-agent behavior
- Lack of a built-in sandbox
- Prompt injection from untrusted content
- Behavior of user-installed extensions or skills
A valid security report should show how Pi grants access that the local user did not already have.
Do not open public GitHub issues for security-sensitive reports. Use the repository’s Security Policy to report vulnerabilities responsibly.
7.5 Extension Security
Extensions run with your full system permissions and can execute arbitrary code. This means:
- An extension can read, write, or delete any file accessible to your user account
- An extension can execute arbitrary shell commands
- An extension can make network requests to any endpoint
- An extension can access environment variables, credentials, and auth files
7.5.1 Evaluating Extensions
Before installing an extension, consider:
- Source reputation — Is the extension from a trusted author or organization?
- Code review — Can you read and understand the extension’s source code?
- Dependencies — What npm packages does the extension depend on? Are they trustworthy?
- Permissions scope — Does the extension request more access than it needs?
- Maintenance — Is the extension actively maintained and updated?
7.5.2 Extension Sources
| Source | Trust Level | Recommendation |
|---|---|---|
| Official Pi examples | High | Safe to use |
| Your own extensions | High | You control the code |
| Extensions from known authors | Medium | Review before installing |
| Extensions from npm | Medium | Check package and author reputation |
| Extensions from unknown sources | Low | Do not install without code review |
Never install extensions from untrusted sources without reviewing the source code. Extensions have full access to your system.
7.6 Credential Safety
Pi stores credentials in ~/.pi/agent/auth.json with 0600 permissions (user read/write only). Despite this, there are scenarios where credentials can be exposed:
7.6.1 Risks
- Model output — The model could inadvertently print API keys or tokens in its responses
- Tool output — Shell commands that print environment variables or read config files
- Session files — Sessions contain full conversation history, including any secrets that were discussed
- Extension code — Malicious extensions could exfiltrate credentials
- Shared sessions — Exported or shared sessions may contain sensitive information
7.6.2 Best Practices
- Use key resolution — Store keys via
!command(e.g., from a password manager) instead of literals - Minimize stored credentials — Only configure providers you actively use
- Review sessions before sharing — Check
/exportoutput for sensitive data - Use short-lived credentials — When available, prefer tokens that expire
- Restrict extension access — Do not install extensions that handle credentials unless necessary
7.6.3 Key Resolution Best Practices
// ✅ Good: Key retrieved from password manager
{
"type": "api_key",
"key": "!op read 'op://vault/anthropic/credential'"
}
// ✅ Good: Key from environment variable
{
"type": "api_key",
"key": "$ANTHROPIC_API_KEY"
}
// ⚠️ Caution: Literal key stored in file
{
"type": "api_key",
"key": "sk-ant-1234567890..."
}7.7 Network Security
Pi makes outbound network requests to:
- LLM provider APIs (Anthropic, OpenAI, Google, etc.)
- Package registries (npm) during
pi installandpi update - Git repositories during
pi install git:... - OAuth callbacks during
/loginflows
7.7.1 Restricting Network Access
For environments that require network restrictions:
- Use a proxy — Configure
proxyin settings to route through an HTTP proxy - Firewall rules — Restrict outbound traffic to known API endpoints
- Container networking — Use Docker network policies or OpenShell network rules
- VPN — Route Pi traffic through a corporate VPN
// Settings: route through corporate proxy
{
"proxy": "http://corporate-proxy.internal:8080"
}7.8 Security Checklist
Before using Pi in a new environment: