Rate limiting, sandboxing & uitvoeringscontroles
Rate-limiting-strategieën voor AI-API's, sandboxing van code-uitvoering met E2B en Docker, goedkeuringsworkflows voor tool-aanroepen, en het principe van minimale rechten voor AI-agents.
Controles op architectuurniveau zijn de moeilijkste verdedigingen voor aanvallers om te omzeilen, omdat ze buiten de invloed van het model werken. Een gejailbreakt model dat kwaadaardige code wil uitvoeren, kan dat niet als de uitvoering in een sandbox plaatsvindt. Een agent die wordt verleid om gevaarlijke tools aan te roepen, kan dat niet als die tools menselijke goedkeuring vereisen.
Rate-limiting-strategieën
Rate limiting voor AI-API's verschilt van traditionele web-API-rate-limiting, omdat AI-verzoeken zeer variabele kosten hebben (zowel computationeel als financieel).
Dimensies van rate limiting
| Dimensie | Wat het beperkt | Waarom het belangrijk is |
|---|---|---|
| Verzoeken per minuut | Ruwe verzoekentelling | Voorkomt geautomatiseerde aanvalstools |
| Tokens per minuut | Totaal aantal invoer- + uitvoertokens | Voorkomt kostenmisbruik en het volstoppen van context |
| Gelijktijdige verzoeken | Tegelijkertijd lopende verzoeken | Voorkomt resource-uitputting |
| Kosten per uur | Dollarkosten van inferentie | Voorkomt financiële schade door uitbuiting |
| Verzoeken per sessie | Berichten binnen een gesprek | Voorkomt escalatie over meerdere beurten |
Implementatiepatroon
from dataclasses import dataclass, field
from datetime import datetime, timedelta
@dataclass
class RateLimitConfig:
requests_per_minute: int = 20
tokens_per_minute: int = 40_000
max_input_tokens: int = 4_096
max_output_tokens: int = 4_096
max_session_messages: int = 50
cost_limit_per_hour_usd: float = 10.0
class AIRateLimiter:
def __init__(self, config: RateLimitConfig):
self.config = config
self.windows: dict[str, list] = {}
def check_and_record(
self, user_id: str, input_tokens: int, session_messages: int
) -> tuple[bool, str]:
now = datetime.utcnow()
window_start = now - timedelta(minutes=1)
key = f"rpm:{user_id}"
# Controle van verzoeksnelheid
recent = [t for t in self.windows.get(key, []) if t > window_start]
if len(recent) >= self.config.requests_per_minute:
return False, "Rate limit exceeded: too many requests"
# Controle van invoergrootte
if input_tokens > self.config.max_input_tokens:
return False, f"Input too large: {input_tokens} tokens"
# Controle van sessielengte
if session_messages > self.config.max_session_messages:
return False, "Session message limit reached"
recent.append(now)
self.windows[key] = recent
return True, "OK"Red team-omzeilingstechnieken voor rate limiting
| Techniek | Beschrijving | Tegenmaatregel |
|---|---|---|
| Gedistribueerde verzoeken | Gebruik meerdere API-sleutels of accounts | Geaggregeerde limieten per organisatie |
| Langzaam-en-gestaag | Blijf net onder de rate limit | Gedragsanalyse over langere vensters |
| Sessierotatie | Start nieuwe sessies om sessielimieten te resetten | Bijhouden per gebruiker (niet per sessie) |
| Timing buiten piekuren | Aanvallen tijdens rustige periodes wanneer dynamische limieten hoger zijn | Vaste rate limits ongeacht de belasting |
Sandboxing van code-uitvoering
Wanneer AI-agents code genereren en uitvoeren, is sandboxing cruciaal. Zonder dit kan een gecompromitteerde agent toegang krijgen tot het host-bestandssysteem, het netwerk en andere infrastructuur.
E2B biedt in de cloud gehoste sandbox-omgevingen die specifiek zijn ontworpen voor AI-code-uitvoering:
from e2b_code_interpreter import Sandbox
# Maak een geïsoleerde sandbox met een time-out van 30 seconden
sandbox = Sandbox(timeout=30)
# Voer AI-gegenereerde code geïsoleerd uit
result = sandbox.run_code("""
import os
# This runs in a completely isolated environment
# No access to host filesystem, network restrictions applied
print(os.listdir('/')) # Only sees sandbox filesystem
""")
print(result.text) # Output from sandboxed execution
sandbox.kill() # Clean upBeveiligingseigenschappen:
- Geïsoleerd bestandssysteem (geen hosttoegang)
- Netwerkbeperkingen (configureerbare allowlists)
- CPU-/geheugenlimieten
- Automatische time-out en opruiming
- Geen persistentie tussen uitvoeringen
Docker-containers bieden isolatie op procesniveau voor code-uitvoering:
import docker
import tempfile
client = docker.from_env()
def execute_sandboxed(code: str, timeout: int = 10) -> str:
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(code)
f.flush()
container = client.containers.run(
"python:3.11-slim",
command=f"python /code/{f.name.split('/')[-1]}",
volumes={f.name: {"bind": f"/code/{f.name.split('/')[-1]}", "mode": "ro"}},
network_disabled=True, # No network access
mem_limit="256m", # Memory cap
cpu_period=100000, # CPU throttling
cpu_quota=50000,
read_only=True, # Read-only filesystem
remove=True, # Auto-cleanup
timeout=timeout,
)
return container.decode("utf-8")Belangrijke Docker-flags voor AI-sandboxing:
network_disabled=True-- voorkomt data-exfiltratieread_only=True-- voorkomt wijziging van het bestandssysteemmem_limit-- voorkomt geheugenuitputtingsaanvallen--security-opt=no-new-privileges-- voorkomt privilege-escalatie
WASM-runtimes bieden de sterkste isolatie voor lichtgewicht code-uitvoering:
# Using wasmtime for sandboxed Python execution
# Pyodide runs Python in a WASM sandbox with no system access
from pyodide_sandbox import PySandbox
sandbox = PySandbox(
allowed_imports=["math", "json", "re"], # Whitelist imports
max_execution_time_ms=5000,
max_memory_mb=64,
)
result = sandbox.execute(ai_generated_code)Afweging: Sterkste isolatie maar meest beperkte mogelijkheden. Geen bestandssysteem, geen netwerk, beperkte standaardbibliotheek.
Goedkeuringsworkflows voor tool-aanroepen
Voor AI-agents die acties in de echte wereld kunnen uitvoeren (e-mails versturen, databases wijzigen, aankopen doen) voorkomen goedkeuringspoorten ongeautoriseerde acties.
Goedkeuringsarchitectuur
from enum import Enum
class ApprovalPolicy(Enum):
AUTO_APPROVE = "auto" # Low-risk tools
NOTIFY_AND_PROCEED = "notify" # Medium-risk: log but allow
REQUIRE_APPROVAL = "approve" # High-risk: block until human approves
ALWAYS_DENY = "deny" # Forbidden tools
TOOL_POLICIES = {
"search_web": ApprovalPolicy.AUTO_APPROVE,
"read_file": ApprovalPolicy.NOTIFY_AND_PROCEED,
"send_email": ApprovalPolicy.REQUIRE_APPROVAL,
"execute_sql": ApprovalPolicy.REQUIRE_APPROVAL,
"delete_record": ApprovalPolicy.ALWAYS_DENY,
"modify_permissions": ApprovalPolicy.ALWAYS_DENY,
}
class ToolGatekeeper:
def __init__(self, policies: dict[str, ApprovalPolicy]):
self.policies = policies
async def check_tool_call(
self, tool_name: str, arguments: dict, user_id: str
) -> tuple[bool, str]:
policy = self.policies.get(tool_name, ApprovalPolicy.ALWAYS_DENY)
if policy == ApprovalPolicy.AUTO_APPROVE:
return True, "Auto-approved"
elif policy == ApprovalPolicy.NOTIFY_AND_PROCEED:
await self.log_notification(tool_name, arguments, user_id)
return True, "Approved with notification"
elif policy == ApprovalPolicy.REQUIRE_APPROVAL:
approved = await self.request_human_approval(
tool_name, arguments, user_id
)
return approved, "Human review"
else:
return False, f"Tool '{tool_name}' is forbidden"Overwegingen voor red teams
| Aanval | Goedkeuringscontrole | Omzeilingspotentieel |
|---|---|---|
| Directe tool-aanroep naar verboden tool | ALWAYS_DENY | Geen -- architectonisch geblokkeerd |
| Argumentinjectie in toegestane tool | AUTO_APPROVE op de tool | Hoog -- argumenten worden niet beoordeeld |
| Tool-ketening (veilige tools → onveilige uitkomst) | Individueel toolbeleid | Gemiddeld -- de keten creëert emergent risico |
| Goedkeuringsmoeheid (veel laagrisicoverzoeken) | REQUIRE_APPROVAL | Gemiddeld -- mensen tekenen na vele goedkeuringen klakkeloos af |
Principe van minimale rechten voor AI-agents
Minimale rechten is de belangrijkste architectonische verdediging voor agentic AI-systemen.
Implementatiechecklist
| Principe | Implementatie | Voorbeeld |
|---|---|---|
| Minimale toolset | Registreer alleen de tools die de agent daadwerkelijk nodig heeft | Een klantenservicebot krijgt search_faq en create_ticket, niet execute_sql |
| Lezen-voor-schrijven | Standaard alleen-lezen toegang; schrijven vereist expliciete toekenning | Agent kan de database lezen maar niet wijzigen zonder verhoogde sessie |
| Gescopete inloggegevens | Elke tool krijgt inloggegevens beperkt tot zijn functie | E-mailtool kan alleen vanaf een specifiek adres naar toegestane domeinen versturen |
| Tijdsgebonden toegang | Rechten verlopen na een sessie of tijdvenster | Schrijftoegang tot de database ingetrokken na 5 minuten |
| Audittrail | Log elke toolaanroep met volledige argumenten | Doorzoekbaar logboek van alle agentacties voor forensische beoordeling |
Verder lezen
- Defense-in-depth voor LLM-apps -- waar uitvoeringscontroles passen in de verdedigingsstack
- Runtime-monitoring & anomaliedetectie -- omzeilingspogingen detecteren
- Guardrails- & veiligheidslaagarchitectuur -- aanvullende guardrail-lagen
- Toolmisbruik -- aanvallen waartegen deze controles verdedigen
Verwante onderwerpen
- Defense-in-depth voor LLM-apps - Waar uitvoeringscontroles passen in de verdedigingsstack
- Runtime-monitoring & anomaliedetectie - Omzeilingspogingen tegen uitvoeringscontroles detecteren
- Agent-architecturen & tool-use-patronen - De agentpatronen die deze controles verdedigen
- Guardrails- & veiligheidslaagarchitectuur - Aanvullende guardrail-lagen
Referenties
- "E2B Documentation: AI Code Execution Sandbox" - E2B (2025) - Documentation for the cloud-hosted sandboxed execution environment designed for AI agents
- "Docker Security Best Practices" - Docker Inc. (2025) - Official security guidance for container isolation including network disabling and read-only filesystems
- "Principle of Least Privilege in Modern Applications" - NIST SP 800-53 (2023) - Federal security control defining least privilege requirements applicable to AI agent tool access
- "OWASP Top 10 for LLM Applications: LLM08 Excessive Agency" - OWASP (2025) - Risk classification for over-permissioned AI agents that execution controls mitigate
Een AI-agent is gejailbreakt en de aanvaller instrueert hem om alle records in een database te verwijderen. De agent heeft de tool 'execute_sql' met REQUIRE_APPROVAL-beleid en 'delete_record' met ALWAYS_DENY-beleid. Wat gebeurt er?