Quand un agent est compromis — par prompt injection, par jailbreak, par bug logique — la question n'est plus "comment éviter la compromission ?". Elle l'est aussi, mais elle est secondaire. La première question opérationnelle est : "qu'est-ce que l'attaquant peut faire avec un agent compromis ?". C'est ce que définit le confinement.
Le confinement en 2026 repose sur trois couches : sandbox, capabilities, kill-switch. Chacune attaque le problème sous un angle différent. Les trois ensemble couvrent les cas réels.
Couche 1 — Sandbox
La sandbox délimite l'environnement d'exécution du runtime de l'agent. Si un attaquant exécute du code dans cet environnement (via un tool d'exécution arbitraire, via un eval injecté, via un bug dans le parser de sortie), qu'a-t-il en main ?
Architecture minimale
- Container isolé par session ou par tâche, jamais partagé entre utilisateurs.
- Filesystem éphémère, sans persistance entre invocations.
- Réseau strictement allowliste : l'agent ne peut joindre que les hosts autorisés (LLM provider, outils déclarés). Pas d'egress libre.
- Pas de credentials montés en clair dans la sandbox : tout passe par un broker qui vérifie l'autorisation à chaque appel.
Le cas particulier des agents qui exécutent du code
Beaucoup d'agents modernes (Claude Code, Cursor agents, OpenAI Code Interpreter) exécutent du code. C'est leur fonction. La sandbox doit alors :
- Refuser tous les syscalls de réseau hors allowlist, même par exec.
- Refuser l'écriture en dehors d'un dossier dédié.
- Avoir un CPU/mémoire limit strict — la consommation est un indicateur d'abus.
- Avoir un timeout sur chaque session.
Les containers gVisor ou Firecracker offrent une isolation suffisante pour ce cas, à des coûts opérationnels raisonnables.
Couche 2 — Capabilities
La sandbox protège l'environnement. Les capabilities protègent les actions externes. C'est l'équivalent du least privilege pour les agents.
Principe
Chaque outil exposé à l'agent est associé à :
- Un scope : quoi exactement il peut faire (lire les fichiers du projet X, pas tous les fichiers ; envoyer un email à un client à la fois, pas en bulk).
- Une autorisation : qui peut activer cette capability (l'agent l'a en permanence, ou il doit la demander via UI à l'utilisateur).
- Une traçabilité : chaque utilisation est logguée, avec paramètres et résultat.
Le pattern de "capability brokered"
Au lieu d'exposer directement à l'agent un outil send_email(to, subject, body), on expose un broker :
`` agent → broker → vérification (utilisateur OK ? rate limit ? destinataire allowlist ?) → send_email ``
Le broker peut :
- Refuser silencieusement si le destinataire n'est pas dans l'allowlist du user.
- Demander une confirmation UI pour les actions à fort impact.
- Refuser si la fréquence dépasse un seuil.
- Logger chaque tentative.
C'est ce qui fait la différence entre "mon agent a accès à Gmail" (catastrophique) et "mon agent peut envoyer 5 emails par jour vers les contacts du user, avec confirmation pour les nouveaux destinataires" (vivable).
Capabilities et permissions utilisateur
Une capability ne suffit pas. Elle doit être dérivée des permissions de l'utilisateur courant. Un agent qui agit pour un user à droits limités ne doit pas hériter des droits du compte de service de l'application. C'est la pierre angulaire pour empêcher l'élévation de privilèges via agent.
Couche 3 — Kill-switch
Le kill-switch, c'est la capacité de stopper proprement et instantanément un agent qui dérape, sans casser le reste du système. Trois niveaux :
Kill-switch local — par session
Un endpoint qui interrompt la session courante de l'agent, ferme les outils, sauvegarde les logs, notifie l'utilisateur. Doit être accessible depuis l'interface du user et depuis un dashboard admin.
Kill-switch global — par version
Un flag (feature flag, env var, config remote) qui désactive tous les agents d'une version donnée. Utile quand on découvre que la version v2.3.1 a un bug qui rend l'agent vulnérable à un nouveau prompt injection pattern.
Kill-switch par capability
Couper sélectivement un outil. Exemple : si on découvre que send_email est exploitable via prompt injection, désactiver send_email pendant l'investigation, sans couper les autres outils.
Ce qui rend un kill-switch utile
Pas juste son existence : son temps de propagation. Si le kill-switch met 15 minutes à se propager à toutes les instances en production, vous perdez 15 minutes critiques.
Bonne pratique :
- Propagation visée < 30 secondes.
- Testé en exercice mensuel sur prod (pas seulement en staging).
- Documenté : qui peut l'actionner, dans quel cas, après quelle vérification.
L'erreur classique : confinement absent par défaut
Beaucoup d'équipes déploient un agent et activent les confinements "après les premiers retours". C'est la mauvaise séquence. Les confinements doivent être :
- Activés par défaut au moment du go-live.
- Relâchés progressivement au fur et à mesure que les patterns d'usage sont connus.
Pas l'inverse. Un confinement qu'on rajoute après coup est presque toujours partiel — il y a déjà des intégrations en aval qui dépendent du périmètre actuel.
Test de maturité — 5 questions
- Votre agent tourne-t-il dans une sandbox isolée par session ?
- Pouvez-vous lister, pour chaque tool, les paramètres autorisés et les exceptions ?
- Y a-t-il une confirmation humaine sur les actions à impact externe non réversible ?
- Avez-vous un kill-switch qui se propage en moins de 30 secondes ?
- L'avez-vous testé en exercice ce mois-ci ?
Si vous avez 5 oui, vous êtes dans le top 10% des déploiements actuels. 3 oui est un bon point de départ. 0-1 oui = ne mettez pas l'agent en production en l'état.
Pour la cartographie complète des surfaces, Threat model d'un agent : 7 surfaces. Pour le runbook d'incident, Agent compromis : runbook 0-72h.