
Sandboxing léger et multiplateforme de processus, propulsé par le runtime d'OpenAI Codex. Isolez toute commande avec des contrôles de fichier, réseau et d'identifiants.
SDK Python pour zerobox. Permet de mettre en sandbox n'importe quelle commande avec des contrôles sur les fichiers, le réseau et les identifiants.
pip install zerobox
L'installation de la wheel dépose la CLI zerobox dans le bin/ de votre environnement et expose un SDK Python.
Pour l'utilisation de la CLI, les concepts de secrets, la référence complète des flags, les chiffres de performance et la prise en charge des plateformes, consultez le README principal.
from zerobox import Sandbox
sandbox = Sandbox.create({"allow_write": ["/tmp"]})
print(sandbox.sh("echo hello").text())
Trois façons d'exécuter une commande. Chacune renvoie un ShellCommand que vous terminez avec .text(), .json() ou .output().
name = "world"
sandbox.sh(f"echo hello {name}").text()
data = sandbox.py("import json; print(json.dumps({'sum': 1 + 2}))").json()
sandbox.exec("python3", ["-c", "print('hi')"]).text()
data = sandbox.sh("cat data.json").json()
result = sandbox.sh("exit 42").output()
# CommandOutput(code=42, stdout='', stderr='')
Utilisez AsyncSandbox dans les applications asynchrones afin que l'attente du sous-processus sandboxé ne bloque pas la boucle d'événements. La forme des commandes est la même que pour Sandbox, mais la création et les terminateurs sont utilisés avec await.
from zerobox import AsyncSandbox
sandbox = await AsyncSandbox.create({"allow_write": ["/tmp"]})
text = await sandbox.sh("echo hello").text()
data = await sandbox.sh("printf '{\"ok\": true}'").json()
result = await sandbox.exec("python3", ["-c", "print('hi')"]).output()
Les commandes asynchrones acceptent la même option timeout :
import subprocess
try:
await sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelled")
Une sortie non nulle lève SandboxCommandError :
from zerobox import Sandbox, SandboxCommandError
sandbox = Sandbox.create()
try:
sandbox.sh("exit 1").text()
except SandboxCommandError as e:
print(e.code, e.stderr)
Transmettez des clés API que le processus sandboxé ne voit jamais. Le proxy ne substitue la valeur réelle que pour les hôtes approuvés.
import os
from zerobox import Sandbox
sandbox = Sandbox.create({
"secrets": {
"OPENAI_API_KEY": {
"value": os.environ["OPENAI_API_KEY"],
"hosts": ["api.openai.com"],
},
"GITHUB_TOKEN": {
"value": os.environ["GITHUB_TOKEN"],
"hosts": ["api.github.com"],
},
},
})
sandbox.sh('curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models').text()
Consultez le README principal pour savoir comment fonctionne la substitution des placeholders.
Enregistrez les modifications du système de fichiers et annulez-les automatiquement :
sandbox = Sandbox.create({
"allow_write": ["."],
"restore": True,
})
sandbox.sh("npm install").text()
Enregistrez sans annuler :
sandbox = Sandbox.create({
"allow_write": ["."],
"snapshot": True,
"snapshot_exclude": ["node_modules"],
})
sandbox.sh("npm install").text()
Passez un timeout (en secondes) à n'importe quel terminateur :
import subprocess
try:
sandbox.sh("sleep 60").text(timeout=1.0)
except subprocess.TimeoutExpired:
print("cancelled")
sandbox = Sandbox.create({
"env": {"NODE_ENV": "production"},
"allow_env": ["PATH", "HOME"],
"deny_env": ["AWS_SECRET_ACCESS_KEY"],
})
Consultez le README principal pour savoir ce qui est hérité par défaut et les équivalents CLI.
Sandbox.create(options) accepte une dataclass SandboxOptions ou un simple dict. Tous les champs sont facultatifs.
Les clés de dict inconnues (par exemple allowWrite au lieu de allow_write) lèvent une TypeError au moment de la construction.
Sandbox.py(code) exécute le python3 présent sur le PATH dans le sandbox. Si votre interpréteur actif se trouve en dehors des racines lisibles du sandbox (par exemple les Pythons gérés par uv sous ~/.local/share/uv/), utilisez plutôt :
import sys
sandbox = Sandbox.create({"allow_read": [sys.prefix]})
sandbox.exec(sys.executable, ["-c", "print('hi')"]).text()
zerobox)zerobox)Apache-2.0
| Méthode | En cas de succès | En cas de sortie non nulle |
|---|
.text() | Renvoie stdout sous forme de chaîne | Lève SandboxCommandError |
.json() | Analyse stdout comme JSON | Lève SandboxCommandError |
.output() | Renvoie CommandOutput(code, stdout, stderr) | Renvoie la même structure, ne lève jamais |
| Champ | Type | Description |
|---|
profile | str | list[str] | Profil(s) nommé(s). Une liste fusionne de gauche à droite. Valeur par défaut : "workspace". |
allow_read / deny_read | list[str] | Chemins lisibles / bloqués. |
allow_write / deny_write | list[str] | Chemins inscriptibles / bloqués. |
allow_net | bool | list[str] | True autorise tout. Une liste restreint l'accès à ces domaines. |
deny_net | list[str] | Domaines bloqués. |
allow_all | bool | Accès complet au système de fichiers et au réseau. |
no_sandbox | bool | Désactive entièrement le sandbox. |
strict_sandbox | bool | Échoue au lieu de recourir à une isolation plus faible. |
cwd | str | Répertoire de travail. |
env | dict[str, str] | Variables d'environnement explicites. |
allow_env | bool | list[str] | Hérite des variables d'environnement du parent. |
deny_env | list[str] | Variables d'environnement bloquées. |
snapshot | bool | Enregistre les modifications du système de fichiers. |
restore | bool | Enregistre et annule après la sortie. Implique snapshot. |
snapshot_paths / snapshot_exclude | list[str] | Chemins suivis / motifs exclus. |
secrets | dict[str, SecretConfig] | Secrets avec des portées par hôte. |
debug | bool | Affiche la configuration du sandbox sur stderr. |