Exécution de code isolée

Le crate adk-sandbox fournit une exécution de code isolée pour les agents ADK, avec deux niveaux d’isolation :

  1. Isolation des processus — processus enfants avec isolation de l’environnement et application d’un délai d’expiration
  2. Profils de sandbox au niveau du système d’exploitation — restrictions au niveau du noyau sur le système de fichiers, le réseau et le lancement de processus

Backends

BackendNiveau d’isolationLangagesDrapeau de fonctionnalité
ProcessBackendEnvironnement + délai d’attenteRust, Python, JS, TS, Commandprocess (par défaut)
ProcessBackend + sandboxNiveau noyauIdentiques à ci-dessusprocess + sandbox-native
WasmBackendComplet (mémoire, fs, réseau)WASM uniquementwasm

Quelle isolation obtenez-vous ?

ProcessBackend::isolation() le signale, donc ce n’est pas quelque chose à déduire du nom du crate :

RésultatSignification
IsolationClass::SubprocessOnlyUn processus enfant avec un environnement nettoyé, un délai d'attente et son propre groupe de processus. L'OS n'applique aucune autre restriction : le code peut lire le système de fichiers de l'hôte et accéder au réseau. C'est ce que ProcessBackend::default() vous offre.
IsolationClass::OsEnforcedUn enforceur et une politique sont attachés, donc l'OS restreint le processus enfant.

Deux choses à savoir concernant le backend de processus :

  • Les programmes sont résolus avant que l’environnement ne soit effacé. Un simple python3, node, ou rustc est recherché sur PATH de l’appelant et transmis au processus enfant comme un chemin absolu. Cela signifie que l’enfant n’a pas besoin de PATH à lui pour démarrer — auparavant, un appelant devait mettre PATH dans ExecRequest::env, ce qui permettait aussi au code exécuté de lancer n’importe quoi d’autre dessus.
  • La compilation passe par la même frontière que l’exécution. Le code source Rust était auparavant compilé par une commande construite en dehors du chemin partagé, donc la compilation n’avait ni enrouleur d’application de politique, ni délai d’expiration, ni groupe de processus. C’est important parce que la compilation n’est pas inerte : include_str! lit des fichiers et les macros procédurales exécutent du code arbitraire avant que le binaire produit n’existe. La phase de compilation reçoit une liste d’autorisation de chaîne d’outils spécifique à la plateforme ; sous Windows, cela inclut LIB et utilise le lieur rust-lld de la chaîne d’outils Rust afin qu’un link.exe non مرتبط plus tôt sur PATH ne puisse pas être sélectionné. Un enforcer du système d’exploitation est ce qui contraint cette phase.

Priorité de l’environnement

SandboxPolicy::env fournit des valeurs par défaut pour chaque exécution et ExecRequest::env les remplace pour chaque appel. Les variables de la politique étaient auparavant entièrement ignorées.

Profils de bac à sable du système d’exploitation

L’application de l’enforcement du bac à sable au niveau du système d’exploitation restreint les processus enfants au niveau du noyau. Cela va au-delà de l’isolation de l’environnement — le système d’exploitation lui-même bloque les accès non autorisés au système de fichiers, les connexions réseau et le lancement de processus.

Prise en charge de la plateforme

PlateformeMécanisme d'applicationFonctionnement
macOSSeatbelt (sandbox-exec)Règles au niveau des appels système : « autoriser par défaut, refuser les opérations dangereuses » — refuse les écritures, le réseau et fork ; les lectures ne sont pas restreintes
Linuxbubblewrap (bwrap)Isolation de l’espace de noms du système de fichiers (montages en liste blanche)
WindowsAppContainerNon implémenté — le mécanisme de contrôle se signale comme indisponible

Démarrage rapide

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?;

Drapeaux de fonctionnalité

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

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

SandboxPolicy

La politique définit ce qu’un processus sandboxé est autorisé à faire:

ChampValeur par défautDescription
allowed_paths[] (deny all)Chemins du système de fichiers avec accès en lecture seule ou en lecture-écriture
allow_networkfalseSi l'accès réseau est autorisé
allow_process_spawnfalseIndique si le lancement de processus enfants est autorisé
env{}Variables d'environnement pour le processus isolé

Différences entre plateformes

macOS (Seatbelt) : utilise « allow default, deny dangerous » — commence avec un accès complet, puis bloque le réseau, les écritures de fichiers et le lancement de processus. Une approche de liste blanche pure ne fonctionne pas, car Python a besoin de dizaines de catégories de syscall spécifiques à macOS au démarrage.

Linux (bubblewrap) : utilise une liste blanche basée sur les espaces de noms — rien n’existe par défaut, vous montez uniquement ce qui est nécessaire. Installez avec apt install bubblewrap ou dnf install bubblewrap.

Windows (AppContainer) : non implémenté. La conception repose sur des ACL basées sur des jetons — un SID restreint sans accès par défaut, puis des ACL accordées sur des chemins spécifiques — mais la création de conteneurs, les ACL, les capacités et le nettoyage des job objects sont absents, donc probe() renvoie EnforcerUnavailable. Exécutez sans enforceur sur Windows, ou utilisez macOS ou Linux où l’application des règles est réelle.

Exemple

Voir examples/sandbox_agent/ pour un exemple complet piloté par LLM-agent qui exécute du code Python dans un environnement sandboxé avec l’accès réseau bloqué par le noyau du système d’exploitation.