Exécution de code en bac à sable
La crate adk-sandbox fournit une exécution isolée du code 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 bac à sable au niveau du système d’exploitation — restrictions au niveau du noyau concernant le système de fichiers, le réseau et la création de processus
Moteurs d’exécution
| Backend | Niveau d’isolation | Langages | Indicateur de fonctionnalité |
|---|---|---|---|
ProcessBackend | Environnement + délai d’attente | Rust, Python, JS, TS, Commande | process (par défaut) |
ProcessBackend + bac à sable | Niveau noyau | Identique à ci-dessus | process + sandbox-native |
WasmBackend | Complet (mémoire, fs, réseau) | WASM uniquement | wasm |
Quelle isolation obtenez-vous ?
ProcessBackend::isolation() le signale, ce n’est donc pas quelque chose qu’il faut déduire du nom de la crate :
| Résultat | Signification |
|---|---|
IsolationClass::SubprocessOnly | Un processus enfant avec un environnement effacé, un délai d’expiration et son propre groupe de processus. Le système d’exploitation n’applique aucune restriction supplémentaire : 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 fournit. |
IsolationClass::OsEnforced | Un enforceur et une politique sont attachés, de sorte que le système d’exploitation restreint l’enfant. |
Deux éléments du backend de processus méritent d’être connus :
- Les programmes sont résolus avant l’effacement de l’environnement. Un
python3,nodeourustcnu est recherché dans lePATHde l’appelant et transmis au processus enfant sous forme de chemin absolu. Cela signifie que l’enfant n’a pas besoin de son proprePATHpour démarrer — auparavant, l’appelant devait placerPATHdansExecRequest::env, ce qui permettait également au code exécuté de lancer n’importe quel autre programme présent sur celui-ci. - 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é ; la compilation ne bénéficiait donc d’aucun wrapper d’application de contraintes, d’aucun délai d’expiration ni d’aucun groupe de processus. Cela est important, car la compilation n’est pas inoffensive :
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 des outils de la chaîne de compilation spécifique à la plateforme ; sous Windows, celle-ci inclut les chemins de MSVC et de Windows SDK, détectés à partir de la chaîne de compilation installée lorsque l’appelant ne se trouve pas déjà dans un shell de développeur. La compilation utilise l’éditeur de liensrust-lldde la chaîne de compilation Rust afin qu’unlink.exesans rapport, situé plus tôt dansPATH, ne puisse pas être sélectionné. C’est l’application de contraintes au niveau du système d’exploitation qui restreint 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 contraintes 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 la création de processus.
Prise en charge des plateformes
| 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 sur liste blanche) |
| Windows | AppContainer | Non implémenté — le contrôleur 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?;
Indicateurs de fonctionnalité
[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
La politique définit ce qu’un processus exécuté en bac à sable est autorisé à faire :
| Champ | Valeur par défaut | Description |
|---|---|---|
allowed_paths | [] (tout refuser) | Chemins du système de fichiers avec accès en lecture seule ou en lecture-écriture |
allow_network | false | Indique si l’accès réseau est autorisé |
allow_process_spawn | false | Indique si la création de processus enfants est autorisée |
env | {} | Variables d’environnement pour le processus en bac à sable |
Différences entre les plateformes
macOS (Seatbelt) : utilise le principe « autoriser par défaut, refuser ce qui est dangereux » — commence avec un accès complet, puis bloque le réseau, les écritures de fichiers et la création de processus. Une approche basée uniquement sur une liste blanche ne fonctionne pas, car Python a besoin de dizaines de catégories d’appels système spécifiques à macOS au démarrage.
Linux (bubblewrap) : utilise une liste blanche fondée sur les espaces de noms — rien n’existe par défaut, vous ne montez que ce qui est nécessaire. Installez-le avec apt install bubblewrap ou dnf install bubblewrap.
Windows (AppContainer) : non implémenté. La conception repose sur des ACL fondées sur des jetons — un SID restreint sans aucun 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 objets de travail sont absents, donc probe() renvoie EnforcerUnavailable. Exécutez sans dispositif d’application des règles sur Windows, ou utilisez macOS ou Linux, où l’application des règles est effective.
Exemple
Consultez examples/sandbox_agent/ pour obtenir un exemple complet piloté par un agent LLM qui exécute du code Python dans un environnement isolé, avec un accès réseau bloqué par le noyau du système d’exploitation.