Module: Pikuri::Code::Bash::Sandbox
- Defined in:
- lib/pikuri/code/bash/sandbox.rb
Overview
Filesystem-sandbox seam for the bash tool. A sandbox responds to
#wrap(argv) → Array<String>, transforming the +timeout … bash -c
bwrap + bind/isolation flags, FullFsNoNet is Bubblewrap's inverse.
Distinct from Workspace, deliberately: Workspace is "what the LLM
observes via Read/Write/Edit/Grep/Glob"; Sandbox is "what the executed
subprocess sees." They overlap on project + toolchain dirs but diverge
on the OS-runtime baseline (Bubblewrap::ETC_BASELINE — TLS certs,
DNS, tz, hosts): the LLM has no need to Read /etc/resolv.conf, the
curl subprocess does. Separate objects keep each allowlist with its
owner.
The full two-sandbox design — each posture's threat model, the
overlay/concurrency reasoning, and which to pick — is in
pikuri-code/DESIGN.md.
Posture predicates
A sandbox also answers two questions about itself, which is how Pikuri::Code::Bash computes its Tool::TrifectaLegs — asking the object rather than reading a flag out of the argv, because the argv is exactly where that reading goes wrong:
#egress?— can the wrapped command reach a network sink?#confined_to_workspace?— does it see only the workspace?
Both are conservative at the identity element: NONE answers
+true+/+false+ respectively, so a host that subclasses one of these
(the Bubblewrap header invites it) inherits an answer that is wrong
only in the safe direction. A sandbox that could ever degrade to a
networked run rather than raising must answer egress? == true, and a
severed network namespace alone is not evidence of a severed leg — a
reachable session bus spawns the fetch outside every namespace (see
FullFsNoNet::SESSION_IPC_MASKS).
Defined Under Namespace
Modules: NONE Classes: Bubblewrap, FullFsNoNet
Constant Summary collapse
- BWRAP_BINARY =
The +bwrap+(1) binary, resolved on
PATH. 'bwrap'
Class Method Summary collapse
-
.probe(*flags) ⇒ Pikuri::Subprocess::Result
Run a one-shot
bwrapprobe and return the finished process: spawnsbwrap <flags> --die-with-parent /bin/trueat/and waits.
Class Method Details
.probe(*flags) ⇒ Pikuri::Subprocess::Result
Run a one-shot bwrap probe and return the finished process: spawns
bwrap <flags> --die-with-parent /bin/true at / and waits.
Sandbox.probe('--bind', '/', '/', '--unshare-net').status.success?
flags are the isolation each sandbox promises (+--unshare-net+, an
overlay mount, …) — deliberately not defaulted, because the probe's
whole job is to prove that exact isolation works on this host (see
pikuri-code/DESIGN.md on why the two probes aren't interchangeable).
Propagates Errno::ENOENT when bwrap is absent; each caller rescues
it to raise its own install hint.
66 67 68 69 70 |
# File 'lib/pikuri/code/bash/sandbox.rb', line 66 def self.probe(*flags) Pikuri::Subprocess.spawn( BWRAP_BINARY, *flags, '--die-with-parent', '/bin/true', chdir: '/' ).wait end |