@synthryn/sypi-sandbox
v0.6.0-beta.20260816.6a00fcae
Published
Wrap bash commands in SyPi's opt-in filesystem sandbox policy on macOS. Use it when you want shadow reporting or kernel-enforced write boundaries; it is inert unless the profile enables sandbox mode and does not restrict reads, network, or extension code.
Maintainers
Readme
sypi-sandbox
The hook half of the filesystem-sandbox subsystem. Profile resolution,
shadow-mode scanning, the seatbelt wrapper, and per-command policy live in
core/sandbox/ and need no extension API. This extension owns a tool_call
hook. It passes each bash command to decideCommand, renders the result, and
mutates event.input.command in place. This is the same seam used by sypi-rtk
and the only SyPi mechanism that changes a bash command.
The active profile's two-axis sandbox field controls this extension. shadow
observes commands that write outside the workspace boundary. enforce applies
the kernel boundary by wrapping the command in sandbox-exec. Without a
sandbox field, the extension is inert.
Platform coverage, stated once
core/sandbox's sandboxSupport(platform, probes) is the single coverage
source. It reports full, partial, or unavailable; enforce mode accepts
only full:
- macOS: a functional
sandbox-execprobe must pass before SyPi claims a full seatbelt boundary. Apple has deprecatedsandbox-execsince 10.10. - Linux, Windows, and other platforms: confinement is unavailable. A
requested enforce-mode command is blocked with
SANDBOX_UNAVAILABLE; it never falls through to an unconfined process.
The boundary covers processes sypi launches. It does not constrain sypi or
extension code running inside sypi. The boundary applies only to bash writes;
reads and network access are unrestricted.
Profile field (two axes)
One field, sandbox, composes two orthogonal axes plus a write allowlist:
{
"sandbox": {
"mode": "shadow", // off | shadow | enforce (filesystem boundary)
"approval": "never", // never | on-request | untrusted (human escalation)
"trustedFolders": ["/abs/path"], // extra write roots beyond cwd + OS temp dirs
},
}- mode:
offis inert.shadowreports out-of-boundary writes and never blocks.enforcewraps every bash command in a deny-default seatbelt profile. The kernel then denies writes outside cwd, the canonical OS temp directories, andtrustedFolders. Canonical aliases are deduplicated, and enforce mode refuses a workspace/temp containment overlap. Whenmodeis unset, it defaults toshadow. - approval:
never(default) never prompts.on-requestanduntrustedprompt when a UI is attached and the command is flagged. The prompt can allow, block, or escalate an out-of-boundary write.
The shadow scan is bounded and deterministic. It uses no LLM and adds no bash
latency. It is a heuristic; the kernel seatbelt in enforce mode is the
authoritative boundary. A malformed sandbox field fails closed to a shadow
configuration. It observes and reports, never blocks, and emits one warning.
If root resolution is invalid, shadow mode warns that analysis is unavailable
instead of claiming a boundary.
YOLO bypass
Prefix a single command with YOLO (e.g. YOLO rm -rf /tmp/x) to run that ONE
command unsandboxed. The prefix is re-typed per invocation, never persisted as a
setting, and every use is appended to ~/.sypi/logs/sandbox-bypass.log
(extending the session-bypass accountability trail). The next command is
sandboxed again.
Notes
- Entry:
index.ts. It MUST be the LAST extension inpi.extensions(load-order security requirement, guarded by a test): enforce mode wraps the bash command after every othertool_callhook runs, so it sees the fully-decided command and never blinds the permission guard, and no later extension has its own bash view wrapped by us. A model-forgedsandbox-execis not trusted — our profiles carry a per-process signature, and an unsigned wrapper is nested inside our deny-default outer (macOS can only further-restrict a nested sandbox, never widen it). - Imports only the public extension API surface. No model-facing tool or new
command. State (the bypass log) lives under
~/.sypi, never the repo.
