Skip to content

Sandbox multiplataforma

源码版本rust-v0.145.0

codex aísla la ejecución de comandos en el sandbox nativo de cada plataforma: en macOS usa sandbox-exec (seatbelt); en Linux, bubblewrap + seccomp; en Windows, restricted token. El crate sandboxing unifica la abstracción; linux-sandbox/, bwrap/, windows-sandbox-rs/ y process-hardening/ son las implementaciones por plataforma. core calcula el SandboxType antes de cada exec, y luego se lo pasa a SandboxManager::transform para que componga el argv que se va a spawnear de verdad.

Responsabilidades

  1. Decidir según PermissionProfile si se habilita sandbox y qué backend se elige: codex-rs/sandboxing/src/manager.rs:273-319
  2. Componer en macOS la policy seatbelt de sandbox-exec y el argv: codex-rs/sandboxing/src/seatbelt.rs:21-30
  3. En Linux, ir al helper codex-linux-sandbox: primero no_new_privs + seccomp, y luego exec bubblewrap: codex-rs/linux-sandbox/src/lib.rs:1-30
  4. En Windows, aislar sistema de archivos y red con restricted token / elevated backend: codex-rs/windows-sandbox-rs/src/lib.rs:13-50
  5. Endurecer el proceso antes de main (cerrar core dumps, rechazar ptrace, limpiar LD_PRELOAD/DYLD_*): codex-rs/process-hardening/src/lib.rs:12-25

Motivación de diseño

¿Por qué no confiar directamente en el bloqueo de execpolicy? Porque el modelo puede construir shells arbitrarios y un motor de reglas siempre tendrá casos límite. Forzar que cada comando se meta en el sandbox nativo del OS es la red de seguridad: «por mucho que el modelo lo intente rodear, el kernel lo frena». SandboxablePreference::Auto hace que los profiles de política como workspace-write / read-only activen sandbox, mientras que el profile full-access degenera en SandboxType::None, evitando un wrap de proceso sin sentido.

Los backends por plataforma son distintos porque no hay un primitivo de sandbox unificado multiplataforma: el seatbelt de macOS es un .sbpl declarativo; bubblewrap en Linux es user namespace + bind mount; el restricted token de Windows es token + ACL. El enum SandboxType unifica esos tres backends y None en una sola etiqueta; core y exec-server solo miran la etiqueta, sin importarles los detalles de plataforma.

Archivos clave

SandboxType unifica los tres backends de plataforma y «sin sandbox» en una sola etiqueta; core solo la lee.

rust
pub enum SandboxType {
    None,
    MacosSeatbelt,
    LinuxSeccomp,
    WindowsRestrictedToken,
}

En select_initial, primero should_sandbox decide si hace falta sandbox, y luego se pregunta a la plataforma qué backend puede ofrecer:

rust
pub fn select_initial(
    &self,
    file_system_policy: &FileSystemSandboxPolicy,
    network_policy: NetworkSandboxPolicy,
    pref: SandboxablePreference,
    windows_sandbox_level: WindowsSandboxLevel,
    has_managed_network_requirements: bool,
) -> SandboxType {
    if self.should_sandbox(
        file_system_policy,
        network_policy,
        pref,
        has_managed_network_requirements,
    ) {
        get_platform_sandbox(windows_sandbox_level != WindowsSandboxLevel::Disabled)
            .unwrap_or(SandboxType::None)
    } else {
        SandboxType::None
    }
}

El launcher de Linux elige entre el bwrap del sistema y el bundled; si no encuentra ninguno, entra en panic: sin bubblewrap, toda la cadena de sandbox en Linux se rompe.

rust
pub(crate) fn exec_bwrap(argv: Vec<String>, preserved_files: Vec<File>) -> ! {
    match preferred_bwrap_launcher() {
        BubblewrapLauncher::System(launcher) => {
            exec_system_bwrap(&launcher.program, argv, preserved_files)
        }
        BubblewrapLauncher::Bundled(launcher) => launcher.exec(argv, preserved_files),
        BubblewrapLauncher::Unavailable => {
            panic!(
                "bubblewrap is unavailable: no system bwrap was found on PATH and no bundled \
                 codex-resources/bwrap binary was found next to the Codex executable"
            )
        }
    }
}

Flujo de datos

Bordes y fallos

Resumen

SandboxManager es la entrada unificada al sandbox multiplataforma de codex: traduce PermissionProfile en SandboxType y luego en un argv con wrapper. Los backends por plataforma se aíslan cada uno por su lado, pero todos derivan de la misma FileSystemSandboxPolicy / NetworkSandboxPolicy. Para rastrear «por qué este comando fue rechazado», consulta Clasificación de comandos (execpolicy) y Ejecución de comandos exec-server.