Sandbox eBPF au niveau du noyau pour sécuriser les appels d'outils d'agents LLM effectués via le protocole de contexte de modèle (MCP)
Sandboxing au niveau du noyau pour les appels d'outils d'agents LLM via le Model Context Protocol (MCP).
MCPGuard se place comme un proxy transparent entre un client MCP (l'agent / exécuteur) et un sous-processus serveur MCP, appliquant trois couches de défense à chaque invocation d'outil. La couche la plus basse est implémentée en eBPF et applique des politiques de capacité à la frontière des appels système, de sorte qu'un serveur MCP malveillant ne peut contourner la politique en codant en dur un comportement sensible dans sa propre implémentation.
Ce dépôt contient le proxy, les programmes eBPF, le benchmark 14 serveurs / 82 cas, et le harnais d'évaluation utilisés dans l'article associé Kernel-Level Sandboxing for LLM Agent Tool Calls via eBPF.
| Couche | Composant | Objectif |
|---|
| L1 | proxy/policy_engine.py | Politique de capacité par serveur dérivée du schéma MCP de chaque outil ; listes blanches pour les chemins, destinations réseau, processus, variables d'environnement. |
| L2 | proxy/argument_validator.py | Inspection au niveau application des arguments d'appel d'outil : canonicalisation de chemin, validation d'URL, détection d'injection de prompt, détection de fuite d'environnement / d'injection de commande, analyse des clés sensibles, assainissement des réponses. |
| L3 | ebpf/*.bpf.c + proxy/ebpf_sandbox.py | Application au niveau du système d'exploitation : trois programmes BPF LSM (file_guard, net_guard, proc_guard) interceptant open() / connect() / execve(), et un programme tracepoint (fork_guard) qui suit les processus enfants via sched_process_fork afin que la politique soit transmise entre forks. |
Six configurations de défense commutables (proxy/proxy_base.py) couvrent l'espace d'ablation utilisé dans l'article : C0 (pass-through), C-AB (baseline AgentBound), C-app (L1 + L2), C-ebpf (L3 uniquement), C-full (L1 + L2 + L3), C-AB+ebpf (AgentBound + L3).
. ├── proxy/ Moteur de politique L1, validateur d'arguments L2, contrôleur eBPF L3, baseline AgentBound ├── ebpf/ Sources C BPF pour les gardes fichier/réseau/processus/fork + Makefile + vmlinux.h ├── policies/ Politiques de capacité JSON par serveur (valeurs par défaut + surcharges) ├── servers/ 14 serveurs MCP : 11 Python (filesystem, notes, weather, shell, sqlite, git, env + variantes malveillantes/trojanisées) + 3 JavaScript (servers/js/) ├── test_cases/ 82 scénarios de benchmark sur 7 catégories (file_read, exfiltration, env_leak, sandbox_escape, priv_escalation, cross_language, benign) ├── notes_data/ 170 fixtures JSON valides de notes synthétiques utilisées par notes_server ├── runner/ evaluate.py, aggregate.py, agentbound_check.py, ebpf_edge_tests.py, latency_benchmark.py, override_workflow.py, smoke_test.py └── EXECUTION_PLAN.md Instructions de reproduction phase par phase
CONFIG_BPF_LSM=y, lsm=bpf dans la ligne de commande du noyau)clang 21 ou plus récent avec la cible BPFbpftool pour charger les programmes et cartes BPFservers/js/)# Build the eBPF programs
cd ebpf && make && cd ..
# Smoke test (one server, a handful of cases)
python3 runner/smoke_test.py
# Full benchmark for one configuration
python3 runner/evaluate.py --config C-full --run-id trial
# Aggregate a reproduced run
python3 runner/aggregate.py --run-id trial
# Reproduce the steady-state latency table after installing eBPF
sudo python3 runner/latency_benchmark.py --run-id codex_20260523_latency --iterations 100 --warmup 20
# Reproduce the audit/override workflow
python3 runner/override_workflow.py --run-id codex_20260523_override
# Run focused eBPF edge tests after installing eBPF
sudo python3 runner/ebpf_edge_tests.py --run-id codex_20260523_ebpf_edges
# Run AgentBound-style baseline conformance checks
python3 runner/agentbound_check.py --run-id codex_20260523_agentbound
C-ebpf, C-full et C-AB+ebpf échouent en mode fermé si les programmes BPF LSM et les cartes épinglées ne sont pas disponibles. Exécutez-les uniquement après avoir installé la couche eBPF avec les privilèges root.
Taux de prévention des attaques (APR), APR des attaques viables (V-APR) et taux de faux positifs (FPR) sur le benchmark codex_20260523_full de 14 serveurs et 82 cas utilisé dans l'article :
| Config | APR | V-APR | Bloqués viables | FPR |
|---|---|---|---|---|
| C0 | 21.3% | 0.0% | 0/48 | 0/21 |
| C-AB | 37.7% | 20.8% | 10/48 | 0/21 |
| C-app | 42.6% | 27.1% | 13/48 | 0/21 |
| C-ebpf | 60.7% | 50.0% | 24/48 | 0/21 |
| C-full | 68.9% | 60.4% | 29/48 | 0/21 |
| C-AB+ebpf | 67.2% | 58.3% | 28/48 | 0/21 |
L'APR inclut les attaques qui échouent intrinsèquement sous C0. V-APR utilise uniquement les attaques qui réussissent sous C0 comme dénominateur, ce qui est la mesure la plus conservatrice de la couverture de défense.
Le benchmark de latence des appels bénins répétés est stocké dans l'espace de travail interne de l'article sous results/latency/codex_20260523_latency.md. Il mesure BN-01 (filesystem_server.read_file) avec 20 appels d'échauffement et 100 appels mesurés par configuration ; C-full ajoute +0,488 ms de latence médiane par rapport à C0 et reste à 1,141 ms p95 pour cet appel bénin fixe. L'arbre CodeSync public exclut results/, donc les utilisateurs externes régénèrent cet artefact avec la commande ci-dessus.
Le workflow d'audit/surcharge est stocké en interne sous results/audit/codex_20260523_override.md. Il montre comment un refus bénin est enregistré comme un événement d'audit structuré et résolu en ajoutant une surcharge d'opérateur ciblée sous une disposition compatible policies/overrides.
Les tests ciblés des cas limites eBPF sont stockés en interne sous results/ebpf_edges/codex_20260523_ebpf_edges.md. Ils couvrent la disponibilité des cartes en mode fermé, le comportement d'autorisation d'écriture dans l'espace de travail, le refus aux limites de préfixe de répertoire, le refus de transit par /tmp, et le refus d'exfiltration localhost.
La vérification de la baseline de type AgentBound est stockée en interne sous results/agentbound/codex_20260523_agentbound.md. Elle documente que C-AB est une reproduction par serveur au niveau application et vérifie la couverture prévue visible par les arguments ainsi que l'angle mort caché par l'implémentation.
Le serveur MCP est considéré comme non fiable. Il peut être bénin mais mal configuré, intentionnellement malveillant, ou un fork trojanisé d'un serveur légitime. L'agent / exécuteur et le système d'exploitation hôte sont fiables. La couche eBPF suppose que le noyau est non compromis ; les escalades de privilèges dans le noyau (CWE-269 dans les modules du noyau) sont hors de portée.
Une entrée BibTeX sera ajoutée ici une fois l'article publié.
Voir CONTRIBUTING.md. Tous les contributeurs doivent signer le CLA de Meta.
Pour signaler un problème de sécurité, voir SECURITY.md. Veuillez ne pas soumettre de problèmes GitHub publics pour les rapports de sécurité.
MIT — voir LICENSE.