### Configure and Spawn a Sandboxed Process Source: https://context7.com/phylum-dev/birdcage/llms.txt Use `birdcage::process::Command` to define process arguments, standard I/O, and then spawn it within a sandbox. Ensure necessary exceptions are added to the sandbox before spawning. ```rust use birdcage::process::{Command, Stdio}; use birdcage::{Birdcage, Exception, Sandbox}; // Create and configure a command let mut command = Command::new("/bin/echo"); command .arg("-n") .args(["Hello", "World"]) .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::inherit()); // Verify command configuration assert_eq!(command.get_program(), "/bin/echo"); // Setup sandbox and spawn let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/echo".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let child = sandbox.spawn(command).unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello World"); ``` -------------------------------- ### Birdcage::new Source: https://context7.com/phylum-dev/birdcage/llms.txt Creates a new sandbox instance with default deny-all restrictions. This is the entry point for configuring and spawning sandboxed processes. ```APIDOC ## Birdcage::new ### Description Creates a new sandbox instance with default deny-all restrictions. This is the entry point for configuring and spawning sandboxed processes. ### Method Associated function (constructor-like) ### Endpoint N/A (Rust library function) ### Request Example ```rust use birdcage::{Birdcage, Sandbox}; // Create a new sandbox instance let sandbox = Birdcage::new(); // The sandbox starts with no exceptions - everything is denied by default // You must add exceptions before spawning a process ``` ### Response #### Success Response (Instance) - **sandbox** (Birdcage) - A new, empty sandbox instance. ### Response Example ```rust // Example of a successful creation (no explicit return value shown, but sandbox is ready) let sandbox = Birdcage::new(); ``` ``` -------------------------------- ### Initialize a new Birdcage sandbox Source: https://context7.com/phylum-dev/birdcage/llms.txt Creates a new sandbox instance with default deny-all restrictions. Must be initialized from a single-threaded process. ```rust use birdcage::{Birdcage, Sandbox}; // Create a new sandbox instance let sandbox = Birdcage::new(); // The sandbox starts with no exceptions - everything is denied by default // You must add exceptions before spawning a process ``` -------------------------------- ### Running an application with explicit permissions Source: https://github.com/phylum-dev/birdcage/blob/main/README.md Executing the same command with explicit permissions for the 'echo' binary allows the application to run successfully. ```bash $ cargo run --example sandbox -- -e /usr/bin/echo -e /usr/lib echo "Hello, Sandbox\!" Hello, Sandbox! ``` -------------------------------- ### Spawn a sandboxed process Source: https://context7.com/phylum-dev/birdcage/llms.txt Activates the sandbox and launches a child process. This method must be called from a single-threaded process. ```rust use birdcage::process::Command; use birdcage::{Birdcage, Exception, Sandbox}; // Setup sandbox with required permissions let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/echo".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib64".into())).unwrap(); // Create command to run in sandbox let mut command = Command::new("/bin/echo"); command.arg("Hello from sandbox!"); // Spawn the sandboxed process let mut child = sandbox.spawn(command).unwrap(); // Wait for completion and check exit status let status = child.wait().unwrap(); assert!(status.success()); ``` -------------------------------- ### Running an application without permissions Source: https://github.com/phylum-dev/birdcage/blob/main/README.md Attempting to run an application without explicit permissions will result in a permission denied error. ```bash $ cargo run --example sandbox -- echo "Hello, Sandbox\!" Error: Os { code: 13, kind: PermissionDenied, message: "Permission denied" } ``` -------------------------------- ### Enable Network Access with Exception::Networking Source: https://context7.com/phylum-dev/birdcage/llms.txt Use Exception::Networking to enable network access for the sandboxed process. By default, all network operations like TCP and UDP are blocked. ```rust use std::net::TcpStream; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; let mut sandbox = Birdcage::new(); // Allow network access sandbox.add_exception(Exception::Networking).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/sh".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/sh"); command.args(["-c", "curl -s https://example.com > /dev/null && echo 'Network OK'"]); let mut child = sandbox.spawn(command).unwrap(); child.wait().unwrap(); // Network connections succeed with this exception ``` -------------------------------- ### Run Sandboxed Command with Custom Permissions Source: https://context7.com/phylum-dev/birdcage/llms.txt Configures and runs a command within a sandbox, specifying allowed read, write, execute paths, environment variables, and network access. Use this to isolate processes with fine-grained control over their environment. ```rust use std::error::Error; use std::path::PathBuf; use birdcage::process::Command; use birdcage::{Birdcage, Exception, Sandbox}; fn run_sandboxed( program: &str, args: &[&str], read_paths: &[&str], write_paths: &[&str], exec_paths: &[&str], env_vars: &[&str], allow_network: bool, ) -> Result> { let mut sandbox = Birdcage::new(); // Add read exceptions for path in read_paths { sandbox.add_exception(Exception::Read(PathBuf::from(path)))?; } // Add write exceptions for path in write_paths { sandbox.add_exception(Exception::WriteAndRead(PathBuf::from(path)))?; } // Add execute exceptions for path in exec_paths { sandbox.add_exception(Exception::ExecuteAndRead(PathBuf::from(path)))?; } // Add environment variable exceptions for var in env_vars { sandbox.add_exception(Exception::Environment(var.to_string()))?; } // Add network exception if allow_network { sandbox.add_exception(Exception::Networking)?; } // Build and spawn command let mut command = Command::new(program); command.args(args); let mut child = sandbox.spawn(command)?; let status = child.wait()?; Ok(status.code().unwrap_or(-1)) } // Example usage: fn main() -> Result<(), Box> { let exit_code = run_sandboxed( "/bin/ls", &["-la", "/tmp"], &["/tmp"], // Read access to /tmp &[], // No write access &["/bin/ls", "/lib", "/lib64"], // Execute permissions &["PATH", "HOME"], // Allowed env vars false, // No network )?; println!("Process exited with code: {}", exit_code); Ok(()) } ``` -------------------------------- ### Manage Child Process Lifecycle and I/O Source: https://context7.com/phylum-dev/birdcage/llms.txt Interact with a running sandboxed process using the `Child` struct. Write to its stdin, capture its output, and manage its execution state. Close stdin by calling `.take()` to signal EOF. ```rust use std::io::{Read, Write}; use birdcage::process::{Command, Stdio}; use birdcage::{Birdcage, Exception, Sandbox}; // Setup sandbox for interactive process let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/cat".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/cat"); command.stdin(Stdio::piped()); command.stdout(Stdio::piped()); let mut child = sandbox.spawn(command).unwrap(); // Write to stdin if let Some(ref mut stdin) = child.stdin { stdin.write_all(b"Hello, sandbox!").unwrap(); } child.stdin.take(); // Close stdin to signal EOF // Get process ID println!("Child PID: {}", child.id()); // Wait and collect output let output = child.wait_with_output().unwrap(); assert!(output.status.success()); assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, sandbox!"); // Alternative: Non-blocking wait // match child.try_wait() { // Ok(Some(status)) => println!("Exited: {}", status), // Ok(None) => println!("Still running"), // Err(e) => println!("Error: {}", e), // } // Alternative: Kill the process // child.kill().unwrap(); ``` -------------------------------- ### Sandbox::spawn Source: https://context7.com/phylum-dev/birdcage/llms.txt Activates the sandbox and spawns a new child process within it. The sandbox restrictions are applied to the current process before launching the child. This method must be called from a single-threaded process. ```APIDOC ## Sandbox::spawn ### Description Activates the sandbox and spawns a new child process within it. The sandbox restrictions are applied to the current process before launching the child. This method must be called from a single-threaded process. ### Method `spawn` on a `Sandbox` instance ### Endpoint N/A (Rust library function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A (Method arguments) - **command** (birdcage::process::Command) - The command and its arguments to execute within the sandbox. ### Request Example ```rust use birdcage::process::Command; use birdcage::{Birdcage, Exception, Sandbox}; // Setup sandbox with required permissions let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/echo".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib64".into())).unwrap(); // Create command to run in sandbox let mut command = Command::new("/bin/echo"); command.arg("Hello from sandbox!"); // Spawn the sandboxed process let mut child = sandbox.spawn(command).unwrap(); // Wait for completion and check exit status let status = child.wait().unwrap(); assert!(status.success()); ``` ### Response #### Success Response (200) - **child** (std::process::Child) - A handle to the spawned child process. #### Response Example ```rust // The child process handle is returned upon successful spawning. let mut child = sandbox.spawn(command).unwrap(); ``` ``` -------------------------------- ### Preserve All Environment Variables with Exception::FullEnvironment Source: https://context7.com/phylum-dev/birdcage/llms.txt Use Exception::FullEnvironment to preserve all environment variables in the sandboxed process. This is useful when the child process requires the complete parent environment. ```rust use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; let mut sandbox = Birdcage::new(); // Keep all environment variables sandbox.add_exception(Exception::FullEnvironment).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/env".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/env"); let mut child = sandbox.spawn(command).unwrap(); child.wait().unwrap(); // All parent environment variables are inherited ``` -------------------------------- ### Configure sandbox exceptions Source: https://context7.com/phylum-dev/birdcage/llms.txt Adds specific access rules to the sandbox. Exceptions for symlinks automatically apply to the target. ```rust use std::path::PathBuf; use birdcage::{Birdcage, Exception, Sandbox}; let mut sandbox = Birdcage::new(); // Allow read-only access to a file or directory sandbox.add_exception(Exception::Read("/etc/passwd".into())).unwrap(); // Allow read and write access to a path sandbox.add_exception(Exception::WriteAndRead("/tmp/workdir".into())).unwrap(); // Allow execution (and reading) of a binary and its dependencies sandbox.add_exception(Exception::ExecuteAndRead("/usr/bin/ls".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib64".into())).unwrap(); // Allow access to a specific environment variable sandbox.add_exception(Exception::Environment("PATH".into())).unwrap(); // Allow access to all environment variables sandbox.add_exception(Exception::FullEnvironment).unwrap(); // Allow network access sandbox.add_exception(Exception::Networking).unwrap(); ``` -------------------------------- ### Grant Execute and Read Permissions with Exception::ExecuteAndRead Source: https://context7.com/phylum-dev/birdcage/llms.txt Use Exception::ExecuteAndRead to grant execute and read permissions to a path, which is necessary for running binaries and accessing shared libraries. Always pair this with library paths for executables. ```rust use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; let mut sandbox = Birdcage::new(); // Allow executing a specific binary sandbox.add_exception(Exception::ExecuteAndRead("/usr/bin/python3".into())).unwrap(); // Include standard library paths for dynamic linking sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib64".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/usr/lib".into())).unwrap(); let mut command = Command::new("/usr/bin/python3"); command.args(["-c", "print('Hello from Python!')"]); let mut child = sandbox.spawn(command).unwrap(); let status = child.wait().unwrap(); ``` -------------------------------- ### Grant Write and Read Access with Exception::WriteAndRead Source: https://context7.com/phylum-dev/birdcage/llms.txt Use Exception::WriteAndRead to grant both read and write access to a file or directory and its contents. This is suitable for temporary directories or output files. ```rust use std::fs::{self, File}; use std::path::PathBuf; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; // Setup a writable directory let work_dir = PathBuf::from("/tmp/sandbox_work"); fs::create_dir_all(&work_dir).unwrap(); let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::WriteAndRead(work_dir.clone())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/sh".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/sh"); command.args(["-c", "echo 'output' > /tmp/sandbox_work/result.txt"]); let mut child = sandbox.spawn(command).unwrap(); child.wait().unwrap(); // File can be both written and read within the sandbox ``` -------------------------------- ### Grant read-only access with Exception::Read Source: https://context7.com/phylum-dev/birdcage/llms.txt Allows read-only access to a specified path and its contents. The sandboxed process cannot modify or execute files under this exception. ```rust use std::fs; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; // Create sandbox allowing read access to /etc let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::Read("/etc".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/cat".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/cat"); command.arg("/etc/hostname"); let mut child = sandbox.spawn(command).unwrap(); let status = child.wait().unwrap(); // Reading /etc/hostname succeeds with read exception ``` -------------------------------- ### Exception::Read Source: https://context7.com/phylum-dev/birdcage/llms.txt Grants read-only access to a file or directory path and everything beneath it. The sandboxed process cannot modify or execute files with this exception. ```APIDOC ## Exception::Read ### Description Grants read-only access to a file or directory path and everything beneath it. The sandboxed process cannot modify or execute files with this exception. ### Method Used as an argument to `Sandbox::add_exception` ### Endpoint N/A (Enum variant for exception configuration) ### Parameters N/A (This is an enum variant constructor) ### Request Example ```rust use std::fs; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; // Create sandbox allowing read access to /etc let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::Read("/etc".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/cat".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/cat"); command.arg("/etc/hostname"); let mut child = sandbox.spawn(command).unwrap(); let status = child.wait().unwrap(); // Reading /etc/hostname succeeds with read exception ``` ### Response N/A (This is a configuration type, not an endpoint that returns data directly.) ``` -------------------------------- ### Control Environment Variables with Exception::Environment Source: https://context7.com/phylum-dev/birdcage/llms.txt Use Exception::Environment to allow a sandboxed process to access a specific environment variable. By default, all environment variables are removed from the sandbox. ```rust use std::env; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::process::Command; // Set environment variables before sandbox env::set_var("ALLOWED_VAR", "visible"); env::set_var("SECRET_VAR", "hidden"); let mut sandbox = Birdcage::new(); // Only ALLOWED_VAR will be accessible in the sandbox sandbox.add_exception(Exception::Environment("ALLOWED_VAR".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/sh".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); let mut command = Command::new("/bin/sh"); command.args(["-c", "echo $ALLOWED_VAR"]); // Prints: visible // $SECRET_VAR is not accessible let mut child = sandbox.spawn(command).unwrap(); child.wait().unwrap(); ``` -------------------------------- ### Sandbox::add_exception Source: https://context7.com/phylum-dev/birdcage/llms.txt Adds an exception rule to the sandbox, allowing access to specific resources. Returns a mutable reference to self for method chaining. Exceptions for symlinks automatically apply to the symlink's target. ```APIDOC ## Sandbox::add_exception ### Description Adds an exception rule to the sandbox, allowing access to specific resources. Returns a mutable reference to self for method chaining. Exceptions for symlinks automatically apply to the symlink's target. ### Method `add_exception` on a `Sandbox` instance ### Endpoint N/A (Rust library function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A (Method arguments) - **exception** (Exception) - The type of exception rule to add (e.g., Read, WriteAndRead, ExecuteAndRead, Environment, FullEnvironment, Networking). ### Request Example ```rust use std::path::PathBuf; use birdcage::{Birdcage, Exception, Sandbox}; let mut sandbox = Birdcage::new(); // Allow read-only access to a file or directory sandbox.add_exception(Exception::Read("/etc/passwd".into())).unwrap(); // Allow read and write access to a path sandbox.add_exception(Exception::WriteAndRead("/tmp/workdir".into())).unwrap(); // Allow execution (and reading) of a binary and its dependencies sandbox.add_exception(Exception::ExecuteAndRead("/usr/bin/ls".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib".into())).unwrap(); sandbox.add_exception(Exception::ExecuteAndRead("/lib64".into())).unwrap(); // Allow access to a specific environment variable sandbox.add_exception(Exception::Environment("PATH".into())).unwrap(); // Allow access to all environment variables sandbox.add_exception(Exception::FullEnvironment).unwrap(); // Allow network access sandbox.add_exception(Exception::Networking).unwrap(); ``` ### Response #### Success Response (200) - **self** (Sandbox) - A mutable reference to the sandbox instance, allowing for method chaining. #### Response Example ```rust // The .unwrap() indicates success, and the sandbox instance is modified in place. sandbox.add_exception(Exception::Networking).unwrap(); ``` ``` -------------------------------- ### Handle Birdcage Errors Source: https://context7.com/phylum-dev/birdcage/llms.txt Catch and handle specific `birdcage::error::Error` variants, such as `InvalidPath`, `Io`, `ActivationFailed`, and `Seccomp` (on Linux), during sandbox configuration and process spawning. ```rust use std::path::PathBuf; use birdcage::{Birdcage, Exception, Sandbox}; use birdcage::error::Error; use birdcage::process::Command; let mut sandbox = Birdcage::new(); // Handle invalid path exceptions let result = sandbox.add_exception(Exception::Read("/nonexistent/path".into())); match result { Ok(_) => println!("Exception added"), Err(Error::InvalidPath(path)) => { println!("Invalid path: {:?}", path); }, Err(Error::Io(e)) => { println!("I/O error: {}", e); }, Err(Error::ActivationFailed(msg)) => { println!("Sandbox activation failed: {}", msg); }, #[cfg(target_os = "linux")] Err(Error::Seccomp(e)) => { println!("Seccomp error: {}", e); }, } ``` ```rust let mut sandbox = Birdcage::new(); sandbox.add_exception(Exception::ExecuteAndRead("/bin/ls".into())).unwrap(); let command = Command::new("/bin/ls"); match sandbox.spawn(command) { Ok(mut child) => { let status = child.wait().unwrap(); println!("Exit status: {}", status); }, Err(e) => { eprintln!("Failed to spawn sandbox: {}", e); }, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.