module

Cordon

Cordon provides a platform-agnostic API for running shell commands inside a configurable sandbox.

Platform mapping: Linux → bwrap (Bubblewrap), using unprivileged user namespaces macOS → sandbox-exec, using the Seatbelt MACF kernel module (SBPL profiles) Windows → not yet implemented (see ARCHITECTURE.md)

Quick start:

policy = Cordon::Policy.build do |p| p.read_only "/usr/share/myapp" p.read_write "/tmp/workspace" p.tmpfs "/tmp" p.allow_network = false p.working_dir = "/tmp/workspace" end

result = Cordon.run(["python3", "script.py"], policy)

if result.success? puts result.stdout else STDERR.puts result.stderr exit result.exit_code end

Inspecting the generated invocation without executing:

runner = Cordon::Bwrap.new puts runner.build_argv(["ls", "-la"], policy).inspect

runner = Cordon::SandboxExec.new puts runner.generate_profile(policy)

Constants

MAX_RELAUNCH_DEPTH = 1

Maximum relaunch hops before #relaunch refuses and returns, guarding against runaway re-entrancy (e.g. two libraries in the same process both calling #relaunch).

PRERELEASE = VERSION.match(/^\d+\.\d+\.\d+$/).nil?
RELAUNCH_DEPTH_ENV = "CORDON_RELAUNCH_DEPTH"

Env var used to detect and count self-relaunch hops. Not a security boundary — see #relaunch.

VERSION = {{ (`shards version /tmp/tmp.PmNCCK/src/src`).chomp.stringify }}

Read this at compile time from shard.yml one day

Class methods

confirm

Confirms that the platform-appropriate runner not only exists but actually enforces isolation on this host — see Runner#confirm. Prefer this over Runner#available? when you need to know sandboxing really works, not just that the binary is present.

Source
platform_runners

Returns all known runners for this platform, in preference order. Runners may not be available; each responds to #available?.

Source
relaunch(policy : Policy, depth_env : String = RELAUNCH_DEPTH_ENV, max_depth : Int32 = MAX_RELAUNCH_DEPTH, runner : Runner = self.runner) : Nil

Re-executes the current process inside a sandbox governed by policy, using Process.executable_path and ARGV to reconstruct the invocation. Does not return on success — the calling process image is replaced.

Call this once, early, before any untrusted code runs:

Cordon.relaunch(my_policy)

only reached once already inside the sandbox

run_untrusted_code

Re-entrancy guard, not a security boundary. depth_env tracks how many times the process has relaunched itself, via an env var passed through to the sandboxed child. Its only job is to stop a relaunched process from relaunching itself again — it is not a defense against a hostile process tampering with its own environment. Anything already able to set env vars for this process before Cordon runs can set depth_env to skip relaunch entirely; that's equivalent to simply invoking the unsandboxed binary directly, and is outside what #relaunch can prevent. All real protection comes from the sandbox applied on the first hop, before untrusted code has ever run.

Source
run(command : Array(String), policy : Policy, shell : Bool = false) : Result

Runs command inside a sandbox governed by policy. Uses the platform-appropriate runner (see platform_runners).

See Runner#run for shell's contract. Not available on the relaunch path (see #relaunch) — relaunch stays focused on re-exec'ing the current process image, not running scripts.

Source
runner

Returns the best available runner for the current platform. Raises RunnerUnavailableError if nothing is usable.

Source

Nested types