How Nash enforces complete isolation from the host system
Nash achieves total sandboxing through structural enforcement, not just policy. The runtime is architecturally incapable of executing system commands or accessing the host filesystem without explicit permission.
Every file operation goes through the Vfs API, which maintains an in-memory directory tree. Host paths are completely unreachable unless explicitly mounted.
pub fn read(&self, path: &str) -> Result<Vec<u8>> { let p = VfsPath::normalize(path); // Try in-memory nodes first if let Some(node) = self.nodes.get(&p) { match node { FsNode::File(data) => return Ok(data.clone()), FsNode::Directory(_) => bail!("is a directory: {}", path), } } // Fall back to host mount only if configured if let Some(mp) = self.find_mount(&p) { let host_path = /* map VFS path to host */; return std::fs::read(&host_path); } bail!("no such file: {}", path)}
Without a mount binding, Nash commands cannot read, write, or even detect the existence of host files.
Subshells ( ) run on a cloned context. Environment variable changes and directory changes inside the subshell do not escape.
Subshell isolation
Expr::Subshell { expr } => { // Save current state let saved_cwd = self.ctx.cwd.clone(); let saved_env = self.ctx.env.clone(); // Execute subshell let result = self.eval(expr, stdin); // Restore state (env changes don't propagate) self.ctx.cwd = saved_cwd; self.ctx.env = saved_env; result}
You can audit Nash’s sandboxing guarantees by inspecting the source:
Commands to verify sandboxing
Check for system calls
# Should return no resultsgrep -r "std::process" src/grep -r "Command::new" src/grep -r "std::process::Command" src/
Check VFS enforcement
# All file operations go through vfs/mod.rsgrep -rn "std::fs::read\|std::fs::write" src/ | grep -v "src/vfs/"# Only vfs/mod.rs touches std::fs (for mounts)
Verify read-only checks
grep -n "check_write_allowed" src/vfs/mod.rs# Line 127, 159, 241, 259, 348 — all write paths protected