Sandboxed-Codeausführung

Der Crate adk-sandbox bietet isolierte Codeausführung für ADK-Agenten mit zwei Isolationsstufen:

  1. Prozessisolierung — Kindprozesse mit Umgebungsisolierung und Timeout-Durchsetzung
  2. Sandbox-Profile auf Betriebssystemebene — Einschränkungen auf Kernel-Ebene für Dateisystem, Netzwerk und das Starten von Prozessen

Backends

BackendIsolationsstufeSprachenFeature-Flag
ProcessBackendUmgebung + ZeitlimitRust, Python, JS, TS, Befehlprocess (Standard)
ProcessBackend + SandboxAuf Kernel-EbeneWie obenprocess + sandbox-native
WasmBackendVollständig (Speicher, Dateisystem, Netzwerk)nur WASMwasm

Welche Isolation erhalten Sie?

ProcessBackend::isolation() meldet dies, daher ist dies nichts, was sich aus dem Crate-Namen ableiten lässt:

ErgebnisBedeutung
IsolationClass::SubprocessOnlyEin Kindprozess mit bereinigter Umgebung, einem Zeitlimit und einer eigenen Prozessgruppe. Das Betriebssystem wendet keine weiteren Einschränkungen an: Der Code kann das Host-Dateisystem lesen und auf das Netzwerk zugreifen. Das erhalten Sie mit ProcessBackend::default().
IsolationClass::OsEnforcedEin Enforcer und eine Richtlinie sind angehängt, sodass das Betriebssystem den Kindprozess einschränkt.

Zwei Dinge über das Prozess-Backend sind wissenswert:

  • Programme werden aufgelöst, bevor die Umgebung geleert wird. Ein einfaches python3, node oder rustc wird in der PATH des Aufrufers gesucht und dem Kindprozess als absoluter Pfad übergeben. Das bedeutet, dass der Kindprozess zum Starten keine eigene PATH benötigt – zuvor musste ein Aufrufer PATH in ExecRequest::env setzen, wodurch der ausgeführte Code außerdem beliebige andere Programme darüber starten konnte.
  • Die Kompilierung läuft durch dieselbe Grenze wie die Ausführung. Rust-Quellcode wurde bisher von einem außerhalb des gemeinsamen Pfads erstellten Befehl kompiliert, sodass für die Kompilierung kein Enforcer-Wrapper, kein Timeout und keine Prozessgruppe vorhanden war. Das ist relevant, weil die Kompilierung nicht passiv ist: include_str! liest Dateien, und prozedurale Makros führen beliebigen Code aus, bevor die erzeugte Binärdatei existiert. Die Kompilierungsphase erhält eine plattformspezifische Zulassungsliste für Toolchains; unter Windows umfasst diese die MSVC- und Windows-SDK-Pfade, die aus der installierten Toolchain ermittelt werden, wenn sich der Aufrufer nicht bereits in einer Entwicklershell befindet. Die Kompilierung verwendet den rust-lld-Linker der Rust-Toolchain, sodass ein davon unabhängiges link.exe, das weiter vorne in PATH steht, nicht ausgewählt werden kann. Ein Enforcer des Betriebssystems begrenzt diese Phase.

Vorrang der Umgebung

SandboxPolicy::env stellt für jede Ausführung Standardwerte bereit, und ExecRequest::env überschreibt sie pro Aufruf. Die Variablen der Richtlinie wurden zuvor vollständig ignoriert.

Sandbox-Profile des Betriebssystems

Die Sandbox-Durchsetzung auf Betriebssystemebene beschränkt Kindprozesse auf Kernel-Ebene. Dies geht über die Isolierung der Umgebung hinaus – das Betriebssystem selbst blockiert nicht autorisierten Dateisystemzugriff, Netzwerkverbindungen und das Starten von Prozessen.

Plattformunterstützung

PlattformDurchsetzerFunktionsweise
macOSSeatbelt (sandbox-exec)Regeln auf Systemaufrufebene: „standardmäßig erlauben, Gefährliches verweigern“ — verweigert Schreibzugriffe, Netzwerkzugriff und Forks; Lesezugriffe sind nicht eingeschränkt
Linuxbubblewrap (bwrap)Isolierung des Dateisystem-Namensraums (Whitelist-Einhängungen)
WindowsAppContainerNicht implementiert – der Enforcer meldet sich als nicht verfügbar

Schnellstart

use adk_sandbox::{
    ProcessBackend, ProcessConfig, SandboxBackend,
    SandboxPolicyBuilder, get_enforcer,
};

// 1. Define what the sandboxed process can do
let policy = SandboxPolicyBuilder::new()
    .allow_read("/usr")           // Read system libraries
    .allow_read_write("/tmp/work") // Write to work directory
    .allow_process_spawn()         // Python needs to exec
    // Network is denied by default
    .env("PATH", "/usr/bin:/usr/local/bin")
    .build();

// 2. Get the platform-appropriate enforcer
let enforcer = get_enforcer()?;

// 3. Create a sandboxed backend
let backend = ProcessBackend::with_sandbox(
    ProcessConfig::default(),
    enforcer,
    policy,
);

// 4. Execute code — network is blocked, writes restricted
let result = backend.execute(request).await?;

Feature-Flags

[dependencies]
# Auto-detect platform enforcer
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-native"] }

# Or pick a specific platform
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-macos"] }
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-linux"] }

SandboxPolicy

Die Richtlinie legt fest, was ein isolierter Prozess tun darf:

FeldStandardBeschreibung
allowed_paths[] (alles verweigern)Dateisystempfade mit schreibgeschütztem oder Lese-/Schreibzugriff
allow_networkfalseGibt an, ob der Netzwerkzugriff zulässig ist
allow_process_spawnfalseOb das Erzeugen von Kindprozessen erlaubt ist
env{}Umgebungsvariablen für den isolierten Prozess

Plattformunterschiede

macOS (Seatbelt): Verwendet „standardmäßig erlauben, Gefährliches verweigern“ – startet mit vollständigem Zugriff und blockiert anschließend Netzwerkzugriff, Dateischreibvorgänge und das Starten von Prozessen. Ein reiner Whitelist-Ansatz funktioniert nicht, da Python beim Start Dutzende macOS-spezifische Syscall-Kategorien benötigt.

Linux (bubblewrap): Verwendet eine namespace-basierte Whitelist – standardmäßig ist nichts vorhanden, und Sie binden nur das ein, was benötigt wird. Installieren Sie mit apt install bubblewrap oder dnf install bubblewrap.

Windows (AppContainer): Nicht implementiert. Das Design basiert auf tokenbasierten ACLs – einer eingeschränkten SID, die standardmäßig keinen Zugriff hat, wobei anschließend ACLs für bestimmte Pfade gewährt werden. Da jedoch die Containererstellung, ACLs, Capabilities und die Bereinigung von Job-Objekten fehlen, gibt probe() EnforcerUnavailable zurück. Führen Sie Windows ohne Enforcer aus oder verwenden Sie macOS oder Linux, wo die Durchsetzung tatsächlich funktioniert.

Beispiel

Siehe examples/sandbox_agent/ für ein vollständiges von LLM gesteuertes Beispiel, das Python-Code in einer Sandbox-Umgebung ausführt, wobei der Netzwerkzugriff durch den Betriebssystemkernel blockiert wird.

Sandboxed-Codeausführung - ADK-Rust Dokumentation | ADK-Rust