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 :
- Isolation des processus — processus enfants avec isolation de l’environnement et application d’un délai d’expiration
- 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
| Backend | Niveau d’isolation | Langages | Drapeau de fonctionnalité |
|---|---|---|---|
ProcessBackend | Environnement + délai d’attente | Rust, Python, JS, TS, Command | process (par défaut) |
ProcessBackend + sandbox | Niveau noyau | Identiques à ci-dessus | process + sandbox-native |
WasmBackend | Complet (mémoire, fs, réseau) | WASM uniquement | wasm |
Quelle isolation obtenez-vous ?
ProcessBackend::isolation() le signale, donc ce n’est pas quelque chose à déduire du nom du crate :
| Résultat | Signification |
|---|---|
IsolationClass::SubprocessOnly | Un 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::OsEnforced | Un 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, ourustcest recherché surPATHde l’appelant et transmis au processus enfant comme un chemin absolu. Cela signifie que l’enfant n’a pas besoin dePATHà lui pour démarrer — auparavant, un appelant devait mettrePATHdansExecRequest::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 inclutLIBet utilise le lieurrust-lldde la chaîne d’outils Rust afin qu’unlink.exenon مرتبط plus tôt surPATHne 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
| Plateforme | Mécanisme d'application | Fonctionnement |
|---|---|---|
| macOS | Seatbelt (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 |
| Linux | bubblewrap (bwrap) | Isolation de l’espace de noms du système de fichiers (montages en liste blanche) |
| Windows | AppContainer | Non 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:
| Champ | Valeur par défaut | Description |
|---|---|---|
allowed_paths | [] (deny all) | Chemins du système de fichiers avec accès en lecture seule ou en lecture-écriture |
allow_network | false | Si l'accès réseau est autorisé |
allow_process_spawn | false | Indique 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.