agcodex_core/
landlock.rs

1use crate::protocol::SandboxPolicy;
2use crate::spawn::StdioPolicy;
3use crate::spawn::spawn_child_async;
4use std::collections::HashMap;
5use std::path::Path;
6use std::path::PathBuf;
7use tokio::process::Child;
8
9/// Spawn a shell tool command under the Linux Landlock+seccomp sandbox helper
10/// (codex-linux-sandbox).
11///
12/// Unlike macOS Seatbelt where we directly embed the policy text, the Linux
13/// helper accepts a list of `--sandbox-permission`/`-s` flags mirroring the
14/// public CLI. We convert the internal [`SandboxPolicy`] representation into
15/// the equivalent CLI options.
16pub async fn spawn_command_under_linux_sandbox<P>(
17    codex_linux_sandbox_exe: P,
18    command: Vec<String>,
19    sandbox_policy: &SandboxPolicy,
20    cwd: PathBuf,
21    stdio_policy: StdioPolicy,
22    env: HashMap<String, String>,
23) -> std::io::Result<Child>
24where
25    P: AsRef<Path>,
26{
27    let args = create_linux_sandbox_command_args(command, sandbox_policy, &cwd);
28    let arg0 = Some("agcodex-linux-sandbox");
29    spawn_child_async(
30        codex_linux_sandbox_exe.as_ref().to_path_buf(),
31        args,
32        arg0,
33        cwd,
34        sandbox_policy,
35        stdio_policy,
36        env,
37    )
38    .await
39}
40
41/// Converts the sandbox policy into the CLI invocation for `codex-linux-sandbox`.
42fn create_linux_sandbox_command_args(
43    command: Vec<String>,
44    sandbox_policy: &SandboxPolicy,
45    cwd: &Path,
46) -> Vec<String> {
47    #[expect(clippy::expect_used)]
48    let sandbox_policy_cwd = cwd.to_str().expect("cwd must be valid UTF-8").to_string();
49
50    #[expect(clippy::expect_used)]
51    let sandbox_policy_json =
52        serde_json::to_string(sandbox_policy).expect("Failed to serialize SandboxPolicy to JSON");
53
54    let mut linux_cmd: Vec<String> = vec![
55        sandbox_policy_cwd,
56        sandbox_policy_json,
57        // Separator so that command arguments starting with `-` are not parsed as
58        // options of the helper itself.
59        "--".to_string(),
60    ];
61
62    // Append the original tool command.
63    linux_cmd.extend(command);
64
65    linux_cmd
66}