PiG Documentation

Guides and references for configuring, using, and extending PiG.

Security

PiG runs with the permissions of the user who starts it. PiG is not a security sandbox for model output, tools, extensions, skills, hooks, or shell commands.

Use a container, virtual machine, or another operating-system boundary when you need isolation.

Project trust

A repository can contain project settings and Resources that change PiG behavior. PiG requires a trust decision before it loads project-controlled executable or configuration input.

Project trust is not a complete startup boundary. As in Pi, PiG reads the project sessionDir setting while it selects or creates a session, before it resolves project trust. Project trust also does not limit what tool calls can access: enabled tools use the operating-system permissions of the PiG process.

Trust-sensitive project paths include:

.pig/settings.json
.pig/mcp.json
.pig/extensions/
.pig/skills/
.pig/prompts/
.pig/themes/
.pig/SYSTEM.md
.pig/APPEND_SYSTEM.md
.agents/skills/

A bare .pig directory does not require project trust. Context files such as AGENTS.override.md, AGENTS.md and CLAUDE.md load whatever the trust decision is, unless you disable context loading. Treat instructions in a folder as untrusted input even when you decline project trust.

A Piglet in .pig/piglets/ is also project input. --piglet <name> uses it only with a saved trust decision, defaultProjectTrust: "always" or --approve, and a bare name is never read from the working directory.

PiG chooses a trust decision as Pi does:

  1. A command-line --approve or --no-approve applies first.
  2. User-level and command-line extensions can handle the project_trust event. The first extension that returns yes or no owns the decision.
  3. Otherwise PiG uses the saved decision for the current directory or its closest parent. Decisions are stored by canonical directory in ~/.pig/agent/trust.json.
  4. Otherwise PiG follows the global defaultProjectTrust setting, whose default is "ask".

Print, JSON and RPC modes cannot show the trust prompt. Without an override, extension or saved decision, defaultProjectTrust: "always" loads the protected project files, and "ask" or "never" skips them.

Use /trust to manage the current project decision. The selector shows the saved decision and the current session's trust state separately. A checkmark stays on the saved choice while you browse. Select Trust parent folder to trust the parent and clear the current project's override. Restart PiG after changing trust so startup discovery runs under the new decision.

Project trust explains each step of the decision and compares it with Pi.

Sessions and credentials

Sessions can contain prompts, tool arguments, command output, file contents and credentials that appeared in the conversation. Review a session before you export or share it.

PiG creates the agent directory, the sessions directory and each project's session directory with mode 0700 when it creates them. Pi creates them with the umask default, usually 0755 (D132, Pi #10770). A directory that already exists keeps its mode. auth.json is created owner-only (mode 0600 on POSIX, an owner-only DACL on Windows, D68).

The mode 0700 protects only a directory that PiG creates. Session files are created with mode 0644, and trust.json is written with mode 0644. On a shared machine, rely on the mode of the parent directory or on a separate account.

Extensions

Extensions execute code. A subprocess boundary can isolate crashes and support cancellation, but it is not a permission sandbox.

Before you load an extension:

  • verify its source and origin;
  • review its dependencies;
  • inspect required commands and network access;
  • understand which files and secrets it can read;
  • prefer a constrained operating-system environment for untrusted code.

A fused extension shares the PiG process. Review fused code more strictly because a panic, deadlock, or resource leak can affect the whole agent application.

Packages

A Package can distribute executable extensions and instruction Resources. Installing a Package can make those Resources available to normal discovery.

Review Package membership before installation:

pig package validate ./package

Validate extension behavior without changing settings:

pig install ./extension --validate-only --json

Package installation never activates a Piglet. A Piglet separately selects an agent application.

Piglets

Stock PiG has the same security boundary as Pi. It runs as the user, and it has no sandbox. A Piglet does not change that. A Piglet is a declaration, and stock PiG applies it as a narrowing of tools and discovery.

Use exact tool lists and empty discovery lists when an application must not inherit ambient Resources:

tools: [read, grep, find]
discovery:
  extensions: []
  skills: []

Command-line options can narrow a Piglet. They cannot widen it. An overlay that widens tools, discovery, agentEnv, the tools of an extension it names again, or removes a strip entry needs extends.allowWiden: true. An overlay can add a new extension without it.

A Piglet Binary adds guarantees that stock PiG does not give. The next section lists them. It also lists what a Piglet Binary does not guarantee.

What a Piglet Binary guarantees

The guarantees below hold for a Piglet Binary built with build.closed: true. A Binary is open by default. It behaves as stock PiG started with its Piglet: it accepts an overlay Piglet, --system-prompt and ambient Resources that its effective Piglet's discovery allows. Organizations opt in to the closed Binary. Build a controlled deployment with build.closed: true.

Fused extensions. A fused extension is compiled into the executable. The Binary starts it in the PiG process. It does not build, download, or run a subprocess for it. A fused extension that fails to load is reported and is not replaced by a subprocess. At startup the Binary checks that the fused extensions equal the component plan it was built with. It exits when they differ.

No Piglet or ambient Resource selection at run time. A closed Binary refuses --piglet, PIG_PIGLET_PATH, PIG_PIGLET_NAME and --system-prompt, and each refusal names build.closed. It loads no ambient extension or skill, even when its Piglet lists a discovery scope.

No extension or MCP server added at run time. A closed Binary refuses -e/--extension (a path, npm: or git: source), pig install, pig remove, pig update --extensions and pig mcp add, and each refusal names the option, the Binary and build.closed. It ignores settings.extensions and the servers of the user and project mcp.json, and reports a notice. Only what its signed closure lists runs; an extension in the closure can still register MCP servers.

A fixed set of fused and packed extensions. At startup the Binary checks that the fused and packed extensions that start have the names its component plan lists, no more and no fewer. This is a check of names. It does not pin PATH for tools or runtimes. Startup does not install a Package or download a component.

Tool ceilings. The tools list of a Piglet, and the tools list of an extension entry, are a ceiling. The session tool registry admits a tool only when the ceiling, --tools and --exclude-tools all admit it. A tool outside the ceiling is not listed, is not active, and is not reachable by codemode or tool_search. A later setActiveTools call, a late registration, or a reload cannot bring it back. The ceiling does not filter the arguments, paths or output of a tool that it admits. A Piglet with no extensions: section keeps every MCP tool, and a tool of an extension that the Piglet does not name is kept.

Strips that overlays cannot undo. A strip entry marked stripped(binary) names code that a build tag left out of the executable. An overlay cannot re-enable it, with or without extends.allowWiden. The strip list is part of the Binary record digest.

Signed Binaries. A Binary built with --sign-key carries an Ed25519 signature in a DSSE envelope. At every start the Binary verifies the signature offline. It refuses to run when the executable, the manifest, or the signature changed. With pig piglet trust require on, a Binary without a signature from a locally trusted key does not run, and pig piglet pull does not install it. pig piglet pull also verifies the DSSE release index and pins the first signer of each Piglet.

A container for the agent, when the Piglet declares one. A source Piglet with agentEnv.image and pigRuntime.mode: image runs pig in a container. The container runs as the invoking user with all capabilities dropped, no-new-privileges, a read-only root file system and limits on memory, CPU and processes. It does not receive the host environment. It receives only the secrets that agentEnv.secrets binds with a declared secretRef, and the fixed PIG_* variables that the launch sets. If the environment cannot start, PiG does not fall back to the host.

What a Piglet Binary does not guarantee

  • It is not a sandbox. A Binary runs as the user. The fused code shares the PiG process. The model can still run the tools that the ceiling leaves.
  • An open Binary does not stop -e, pig install or MCP configuration. An open Binary loads an extension that the user names with -e (a path, npm: or git: source), accepts the package commands, and loads the MCP servers of the user configuration and of a trusted project, as stock PiG does. Only a closed Binary (build.closed: true) refuses them. Strip mcp to remove MCP from a Binary of either kind.
  • It does not pin PATH or runtimes. The bash tool, MCP servers and extensions find programs through the inherited PATH. A Node extension runs the node found on PATH. A Python or Lisp source extension finds uv, Python or SBCL on PATH.
  • The signature is a self-check. A signature proves that the file is unchanged since a key signed it. A person who can rewrite the Binary and the trust store can sign a replacement. An unsigned Binary runs unless trust require is on.
  • Revocation is local. pig piglet trust revoke changes a file on one machine. There is no revocation list, no key expiry and no online check. Distribute the revoked file with your configuration tool.
  • Builds are not locked. pig piglet build --locked and --record fail with "not implemented". A Binary record holds digests, and pig piglet verify --source checks them.
  • The agentEnv container is not available for a Binary. pig piglet build refuses a Piglet with agentEnv. The container runs only for a source Piglet that names an image. The --unsafe-host option skips the container and prints a warning. The container network is the default bridge network, and no setting limits it. A command that the bash tool runs inherits the container environment, including the bound secrets.

What needs the planned Piglet Image

A Piglet Image is planned and is not built today. pig piglet build --format image fails with Piglet Image build is not implemented. These need it:

  • a Binary that carries its own agentEnv and starts inside it;
  • the Dev Container and materialized source forms of agentEnv;
  • pigRuntime modes other than image, and agentEnv together with extends;
  • secret file targets;
  • an environment that one signed artifact fixes, so that the host cannot swap the image.

Until then, a container or virtual machine around the Binary, a network policy and a pinned image stay your job.

Secrets

Keep secret values outside portable Piglet source, Package metadata, records, sessions, logs, command arguments, and image layers.

Use environment, owner-only files, or contributed secret resolvers. PiG validates declarations and fails before startup when a required value is missing or unauthorized.

Do not put credentials in:

  • a Piglet YAML file;
  • an extension source archive;
  • a prompt or skill;
  • a website example;
  • a generated Binary record.

Model providers

Provider credentials can grant access to paid services and private data. Use the provider's documented environment variable or PiG login store. Do not copy tokens into repository settings.

Treat model output as untrusted input. A model can propose a harmful command even when the provider connection is trusted.

Connection failure

PiG detects extension transport and heartbeat failures within bounded lifecycle rules. It cancels owned pending calls, closes connection-owned UI state, and isolates or quarantines the affected extension or cell.

PiG does not replay an interrupted operation automatically. Automatic replay could duplicate file, shell, network, message, or transaction effects.

See Extensions.

Distrusted certificate authorities

PiG's own HTTPS and WebSocket connections (model providers, OAuth, MCP, package and tool downloads, self-update) refuse a certificate chain that includes one of eight eMudhra intermediate CAs or one of three roots. The private keys of the eight intermediates can be recovered by anyone from their public certificates (Mozilla bug 2083449, October 2026); Sectigo cross-signed the same keys, and Apple and Microsoft still trust that root. The three roots are the ones Mozilla removed from NSS 3.131.1: emSign ECC Root CA - G3, emSign Root CA - C1 and emSign ECC Root CA - C3.

The check compares public-key digests, so it also refuses the cross-signed certificates, and it runs on top of the operating system's trust store, which can keep trusting these CAs until its vendor updates. When PiG's check refuses a chain, the error names the server and the CA. Go 1.27.3's own verifier, which PiG's pinned toolchain carries, already refuses the eight intermediates with x509: no valid chains built; PiG's check adds the three roots and covers a build with an older Go. No setting turns it off; a connection made with a provider's opt-in insecure option skips verification altogether, so it has no verified chain to check. The connections that extension processes open themselves use that runtime's trust store: run Node.js 22.23.4, 24.22.1, 26.12.1 or later, which carry the same distrust.

Piglet Binary verification

A Piglet Binary verifies its embedded Piglet and component plan before command dispatch. A Binary built with --sign-key also verifies its Ed25519 signature offline and refuses to run when its executable, manifest, or signature changed. When its file is unchanged since its last passing start, it skips the hash of its executable bytes. See Verification cache for what that keeps and gives up. The startup check is a self-check: it does not stop an attacker who can rewrite the Binary.

Use pig verify <binary> to report the signature status without running the Binary. Use pig piglet trust add <key.pub> to trust a reviewed publisher key, pig piglet trust revoke <key-id> to reject it, and pig piglet trust require on to require signatures by locally trusted keys. An embedded author key proves continuity from that key, not the human identity of its holder.

A Sigstore keyless attestation is separate build-provenance evidence. pig verify --provenance --repo <owner/name> --signer-workflow <workflow> <binary> delegates to gh attestation verify and may contact GitHub. Startup never makes that network request.

It does not silently install, download, substitute, or weaken missing requirements. Verify the release checksum, offline signature, and available provenance before execution.

A Binary can still require external services, configuration, runtimes, and secrets. Read its record instead of assuming that one file is self-contained.

Enterprise deployment

An enterprise review asks for a set of controls. This table maps each to a Piglet setting. A row that says "No setting" has no control in PiG today. Provide that control outside PiG.

Control
Piglet setting
What it gives
Limit
C1: run untrusted tools and extensions inside an operating-system boundary, with a low-privilege accountagentEnv.image with pigRuntime.mode: image, on a source Piglet. For a Binary, run it in a container or virtual machine that you provide.The agent runs in a container as the invoking user, with no capabilities, no new privileges and a read-only root file system.Not available inside a Binary. --unsafe-host skips it. The network is not restricted.
C2a: run model-chosen commands as an argument array, never through a shelltools without bash or powershell, or strip.tools.The model has no shell tool.No setting makes the bash tool use an argument array. It always runs shell -c <command>.
C2b: allow only listed commands and argumentsNo setting.None. Omit bash as above, and give the model a fused extension tool that runs only the commands you accept.A fused extension tool is code you review. PiG does not check it.
C3a: children get a minimal environment and a secrets brokeragentEnv.secrets with secretRef, and secrets declarations.The container receives only the bound secrets, not the host environment.A command that the bash tool runs inherits the whole container environment. No per-tool filter or broker exists.
C3b: pin an absolute PATHNo setting.None. Set PATH in the image.Node, Python and Lisp source extensions find their runtimes on PATH.

Build a controlled Binary in these steps:

  1. Set an exact tools list, and set discovery.extensions: [] and discovery.skills: [].
  2. Strip the built-ins that the application does not need, with strip.
  3. Set build.closed: true, and add mcp to strip.extensions when the application needs no MCP server.
  4. Build with --sign-key. Run pig piglet trust add for the publisher key, and run pig piglet trust require on on each host.
  5. Run the Binary in a container or virtual machine that you provide, with the secrets injected at run time. The closed Binary refuses -e, the package commands and MCP configuration, so the command line cannot add code. The Binary fixes what it ships, and the container fixes what it can reach.
  6. Run pig verify <binary> and pig piglet verify <binary> --source <piglet.yaml> before you release it. The second command fails when the source differs from the baked Piglet, which includes a source that turns build.closed off.

An open Binary refuses nothing for --piglet. A closed Binary refuses --piglet with a message that names build.closed. Use that message to test a build.

Network content

The documentation site's package and model catalogs contain third-party metadata. A listing does not prove PiG compatibility, security, or endorsement.

Review the publisher, license, source, and integrity evidence before use.

Report a vulnerability

Do not open a public issue for an undisclosed vulnerability. Follow the private reporting instructions in the repository's .github/SECURITY.md. Do not publish exploit details.

PiG project documentation · MIT License