Running unshare

Sandbox your scripts with --unshare

Rye can run scripts inside Linux namespaces (aka “unshare”) with a single flag. This isolates your script from the host:

  • Filesystem: your project directory is mounted as /app (read-mostly), the rest is a tiny tmpfs jail
  • Network: optional new net namespace (defaults to no network)
  • PID: new process namespace (hides host processes)
  • UTS: separate hostname namespace

This is Linux-only and requires no root privileges.

Quick start

# Full isolation (fs+net+pid+uts)
rye --unshare myscript.rye

# Allow network but keep other isolation
rye --unshare --unshare-net=false myscript.rye

# Keep your full filesystem view (cwd not remounted), but isolate net/pid/uts
rye --unshare --unshare-fs=false myscript.rye

You can also enable it per-project in .ryesec:

unshare:
  enabled: true
  fs: true
  net: true
  pid: true
  uts: true

Detect and adapt in code

Rye exposes simple helpers to check isolation at runtime (Rye-itself context):

cc Rye-itself
cfg: Unshare-config?        ; => {active: true, fs: true, net: true, pid: true, uts: true}
if (cfg -> "active") { print "Sandboxed." }

Common checks:

  • Is-unshare — true if running inside unshare
  • Is-unshare-fs / Is-unshare-net / Is-unshare-pid / Is-unshare-uts
  • Require-unshared — exit with error if not sandboxed (great for CI)

Example: skip network work when isolated

cc Rye-itself
if Is-unshare-net {
  print "Network disabled; skipping fetch."
} else {
  ; do network work here
}

When and why to use --unshare

--unshare gives you predictability, safety, and reproducibility without heavy tools like Docker/Podman. Its usefulness depends on what your script does and where it runs.

When it shines

  1. Preventing accidental side effects
  • No system pollution: avoids writes to user configs, home dirs, or system paths.
  • No network side effects: with net isolation on (default), scripts can’t make unexpected API calls, telemetry, or download deps at runtime.
  1. Reproducible builds and CI/CD
  • Tests don’t rely on host network config, ambient env, or stray files on runners.
  • Hermetic execution: same behavior on any Linux host.
  1. Running untrusted/third‑party code
  • Lightweight sandbox restricting what the script can read, write, or send over the network.

When it may be unnecessary (or inconvenient)

  • Standard CLI tools that must modify files in your working directory (formatters/linters) will fail unless you pass --unshare-fs=false.
  • Network‑heavy scripts (scrapers, API clients, deployments) need --unshare-net=false.
  • Non‑Linux environments: namespaces aren’t available (except inside WSL2).

Summary: For tests, CI, builds, batch jobs, and untrusted code, --unshare provides container‑like safety with near‑zero setup. For day‑to‑day interactive tools that must edit your project, run without it or relax specific namespaces.

Files and mounts inside --unshare

Rye constructs a minimal, in‑memory filesystem (tmpfs) “jail” and selectively mounts a few locations:

  • /app: your current working directory (project) is mounted here. Intended read‑mostly.
  • /tmp: writable tmpfs for scratch files.
  • Other root paths (/bin, /etc, /home, …): minimal stubs inside the jail; host locations are not mounted unless explicitly allowed.

Default access policy

  • Read inside /app: allowed. Your script can read any files that exist in your project.
  • Write inside /app: blocked or read‑only best‑effort. Many kernels allow read‑only bind mounts; if not possible, Rye warns. Prefer writing to /tmp.
  • Read/write in /tmp: allowed; data is ephemeral and lost when the process exits.
  • Access outside /app and /tmp (e.g., /home, /etc): denied; you’ll see EACCES (Permission denied) or EROFS (Read‑only file system).

What happens if a script writes to /home?

  • The host /home is not mounted. Writes to /home (or other host paths) fail with EACCES/EROFS.
  • If the path exists only inside the tmpfs jail, writes may land in RAM and vanish after exit; they never touch your real host.

Verify the behavior

Bash

# Attempt to create a file in host home dir (will fail)
rye --unshare -e 'file "/home/test.txt" | .write "hello"'
  • Console: you’ll get a permission/read‑only error.
  • Host: ls /home/test.txt shows no such file.

Read vs. write in /app

; 1) Reading works
_ = file "/app/README.md" | .read
print "Read successfully!"

; 2) Writing is blocked
file "/app/test.txt" | .write "data"

Running with rye --unshare prints “Read successfully!” then errors on the write.

Tips

  • Writes: prefer /tmp for outputs when using --unshare (project dir /app is remounted read-only where possible)
  • CI: add Require-unshared at the start of critical scripts to enforce policy
  • Troubleshooting: if your script needs network, run with --unshare-net=false or adjust .ryesec
  • Non-Linux: --unshare is not available; scripts should branch on Is-unshare and continue gracefully

Caveats

  • Linux-only
  • Read-only remount of /app is best-effort; on some kernels it may remain writable (a warning is printed)
  • Isolation is decided at startup; you can’t enable it mid-run

See also

  • CLI flags overview: “More on flags”
  • Security: Seccomp/Landlock (Linux)