Que doit vraiment isoler le sandbox ?
Un sandbox d’agent IA doit isoler l’environnement d’exécution, mais aussi les outils, les données, l’état d’exécution et la mémoire persistante.
Une application classique suit souvent un chemin assez prévisible. Elle reçoit une entrée, applique une logique, renvoie un résultat. Un agent IA, lui, interprète une consigne, choisit une action, appelle un outil, relit des données, ajuste son raisonnement, modifie parfois son état, puis recommence. Le vrai sujet de sécurité est là, dans cette boucle de décision.
Tester uniquement le code ne suffit pas. Le code peut être propre, couvert par des tests, revu sérieusement, et l’agent peut quand même prendre une décision différente selon le contexte, l’historique de conversation, les données récupérées ou une instruction cachée dans un document. C’est le cas typique du prompt injection, une instruction malveillante glissée dans une page, un PDF ou un ticket, que le modèle peut interpréter comme une consigne légitime.
Chez des clients, le risque n’est pas toujours l’agent qui casse tout d’un coup. C’est souvent un outil trop puissant exposé trop tôt, avec trop de données derrière. Un accès CRM complet, une API de facturation, un connecteur Slack, un drive partagé entier. L’agent n’a pas besoin d’être “méchant”. Il suffit qu’il se trompe avec trop de droits.
Les frontières à poser sont assez simples, mais elles doivent être réelles, pas juste documentées dans un schéma :
- Exécution : Conteneur, VM, sandbox navigateur, limites CPU, mémoire, réseau et système de fichiers.
- Outils : Allowlist stricte, paramètres validés, permissions par outil et journalisation de chaque appel.
- Données : Accès minimal, filtrage des sources, masquage des secrets et séparation des jeux de données sensibles.
- État : Session limitée, contexte court, nettoyage après exécution et pas d’accumulation silencieuse.
- Mémoire persistante : Pas de stockage libre sans règle, TTL, validation avant écriture et suppression possible.
Le sandbox ne doit donc pas seulement empêcher un script de lire un fichier local. Il doit empêcher l’agent de combiner trop librement des capacités, des données et de la mémoire. C’est cette combinaison qui crée les surprises.
| Frontière | Ce que je limite | Risque réduit |
| Exécution | CPU, mémoire, réseau, fichiers, navigateur, conteneur ou VM | Fuite système, exécution abusive, accès non prévu |
| Outils | Liste autorisée, paramètres, permissions, logs | Actions dangereuses, appels API trop larges, erreurs non traçables |
| Données | Sources accessibles, secrets, périmètre des datasets | Exposition de données sensibles, mélange de contextes, fuite d’informations |
| État | Durée de session, taille du contexte, nettoyage final | Décisions biaisées par l’historique, persistance involontaire |
| Mémoire persistante | Écriture contrôlée, TTL, validation, suppression | Stockage de mauvaises informations, secrets mémorisés, dérive dans le temps |
Pourquoi l’isolation doit être prévue dès le départ ?
L’isolation doit être prévue dès le départ parce qu’un agent IA peut combiner instructions, outils, données et mémoire d’une manière difficile à anticiper après coup. C’est ça le vrai sujet. Un agent ne fait pas juste “répondre à une question”. Il lit, il décide, il appelle des outils, il garde parfois du contexte, et il peut enchaîner tout ça très vite.
Les risques reviennent souvent, même sur des projets simples. Pas besoin d’imaginer un scénario de film. Le problème arrive avec des usages très classiques.
- Injection de prompt : Une instruction malveillante cachée dans une page web, un fichier, un ticket support ou un email peut influencer la décision de l’agent. Le modèle peut confondre donnée lue et instruction à suivre.
- Exécution d’outils non contrôlée : L’agent peut appeler un outil autorisé, mais avec de mauvais paramètres, au mauvais moment, ou trop largement. Un outil légitime reste dangereux s’il n’est pas cadré.
- Exfiltration de données : L’agent peut faire sortir des informations sensibles dans une réponse, via une API, un connecteur, ou un résumé envoyé au mauvais endroit.
- Escalade de privilèges : Un accès trop large peut transformer une tâche banale en action critique. Lire un lead, ce n’est pas modifier tout le CRM.
- Fuite de mémoire : Une mémoire persistante peut garder des données personnelles, des secrets ou des infos business qui n’auraient jamais dû rester là.
- Abus d’API : Des appels excessifs peuvent exploser les coûts, les quotas, ou déclencher plusieurs fois le même workflow.
- Persistance de session : Un état mal nettoyé peut influencer les prochaines exécutions. L’agent repart avec des restes de contexte qui ne devraient plus exister.
Ces risques recoupent clairement les sujets documentés par l’OWASP, notamment les injections, les sorties de données sensibles, les abus d’outils et les permissions excessives. L’OWASP, c’est une référence sécurité applicative très utilisée par les équipes produit et dev. Même logique côté NIST AI Risk Management Framework, qui pousse à penser gouvernance, contrôle, traçabilité et mesure du risque dès la conception.

Rajouter un sandbox après déploiement coûte cher. Les outils sont déjà connectés. Les droits sont déjà larges. La mémoire contient déjà des données. Les workflows dépendent déjà de mauvais choix d’architecture. J’ai vu ça chez un client, on voulait “juste limiter un peu après coup”, mais chaque limitation cassait un automatisme existant.
Si je donne à un agent un accès CRM complet pour simplement qualifier des leads, j’ai déjà perdu la bataille du moindre privilège. Il devait avoir un outil limité à lire quelques champs et écrire une note validée. Rien de plus.
Une fois les risques clairs, on peut dessiner l’architecture du sandbox.
Comment concevoir l’architecture du sandbox ?
Je conçois un sandbox d’agent IA comme un ensemble de frontières coordonnées, pas comme un simple conteneur Docker autour d’un script. Le conteneur aide, oui, mais il ne décide pas seul de ce que l’agent peut lire, appeler, écrire ou retenir.
Dans une architecture propre, je sépare trois blocs qui communiquent sous contrôle :
- Environnement d’exécution : Conteneur, machine virtuelle ou sandbox navigateur. Il limite le système de fichiers, le réseau, les ressources CPU/RAM et l’accès à l’hôte.
- Runtime agent et couche décisionnelle : C’est là que l’agent interprète les instructions, choisit un outil, applique les politiques et contrôle les entrées/sorties.
- État et stockage : Contexte de session, logs, mémoire temporaire, mémoire persistante et données métier, avec des règles précises.
Ces trois blocs doivent rester séparés. Le LLM ne doit pas avoir un accès direct et libre à tout. Il propose ou déclenche une action dans un cadre contrôlé. Les outils exécutent uniquement ce qui est autorisé. Le stockage garde seulement ce qui est utile, traçable et conforme. J’ai vu un agent CRM trop libre écrire des notes internes avec des données récupérées dans un mauvais contexte. Le problème n’était pas le modèle. C’était l’architecture.


# Exemple docker-compose.yml simplifié
services:
agent_sandbox:
image: python:3.12-slim
user: "10001:10001" # Pas d'utilisateur root
read_only: true # Système de fichiers en lecture seule
tmpfs:
- /tmp:size=64m,noexec # Espace temporaire limité, non exécutable
mem_limit: 256m # Limite mémoire
cpus: "0.5" # Limite CPU
network_mode: "none" # Réseau désactivé par défaut
cap_drop:
- ALL # Retire les capacités Linux inutiles
security_opt:
- no-new-privileges:true # Empêche l'escalade de privilèges
volumes:
- ./input:/app/input:ro # Données accessibles en lecture seule
command: ["python", "/app/runner.py"]Côté runtime, je préfère une allowlist explicite. Un agent ne “choisit” pas n’importe quelle fonction. Il demande une action, je valide, puis j’exécute.
# Pseudo-code Python
def read_ticket(ticket_id):
return {"id": ticket_id, "text": "Ticket client fictif"}
def summarize_text(text):
return text[:500]
def create_crm_note(customer_id, note):
return {"status": "created"}
TOOLS = {
"read_ticket": read_ticket,
"summarize_text": summarize_text,
"create_crm_note": create_crm_note,
}
def validate(tool_name, params):
if tool_name == "read_ticket":
return isinstance(params.get("ticket_id"), str)
if tool_name == "summarize_text":
return isinstance(params.get("text"), str) and len(params["text"]) <= 5000
if tool_name == "create_crm_note":
return isinstance(params.get("customer_id"), str) and isinstance(params.get("note"), str)
return False
def call_tool(tool_name, params):
if tool_name not in TOOLS:
raise ValueError("Outil refusé")
if not validate(tool_name, params):
raise ValueError("Paramètres invalides")
return TOOLS[tool_name](**params)Un LLM sandbox peut aussi filtrer les messages avant et après décision. Il limite les interactions externes, bloque certains patterns, empêche les sorties sensibles et sépare les instructions système des contenus récupérés sur le web ou dans les tickets. Cette séparation évite qu’un texte lu par l’agent devienne une nouvelle consigne prioritaire.
| Option | Isolation | Coût opérationnel | Cas d’usage |
| Conteneur | Moyenne à bonne | Faible | Agents batch, outils internes, tâches courtes |
| VM | Forte | Plus élevé | Code non fiable, clients isolés, contraintes fortes |
| Sandbox navigateur | Ciblée web | Moyen | Navigation, tests UI, agents web |
Quels contrôles appliquer aux outils et aux données ?
Les outils et les données doivent être contrôlés avec le principe du moindre privilège, des validations strictes et une traçabilité complète. C’est là que je mets le plus d’attention, parce que dans un agent IA, l’outil est souvent la vraie zone de danger.
Le modèle peut se tromper, halluciner, mal interpréter une demande. Mais c’est l’outil qui lit le CRM, envoie l’email, modifie une base, appelle une API ou écrit en mémoire. Donc je place la sécurité entre la décision et l’action. Pas après.
Concrètement, je limite tout ce que l’agent peut faire, même si ça paraît un peu pénible au départ :
- Allowlist d’outils : Aucun outil n’est disponible par défaut. Je branche seulement ceux qui sont nécessaires.
- Permissions granulaires : Lire n’est pas écrire. Résumer n’est pas supprimer. Créer une note n’est pas modifier une fiche client.
- Validation des paramètres : Je contrôle les types, les longueurs, les formats, les valeurs autorisées. Un email doit ressembler à un email, un ID client doit avoir le bon format.
- Scopes par tâche : Un agent support n’a pas les mêmes droits qu’un agent finance. Le scope, c’est simplement le périmètre d’action autorisé.
- Rate limiting : Je limite le nombre d’appels pour éviter les boucles, les coûts absurdes et l’abus d’API.
- Journalisation : Je garde qui a demandé quoi, quel outil a été appelé, avec quels paramètres, et quel résultat a été produit.
- Human in the loop : Je demande une validation humaine pour les actions sensibles, comme envoyer un email client ou modifier une donnée critique.
Côté données, même logique. Je réduis ce que l’agent voit. Filtrage en amont, masquage des données sensibles, séparation des sources, récupération ciblée plutôt qu’un gros dump documentaire. Le RAG, c’est la récupération de documents pour enrichir le contexte du modèle. Mal cadré, il peut ramener des documents inutiles, sensibles, ou piégés par injection indirecte. Et là, l’agent “voit” trop de choses.

{
"agent": "support",
"permissions": [
{
"action": "ticket.read",
"allowed": true,
"commentaire": "Autorise la lecture d’un ticket précis, pas de toute la base support."
},
{
"action": "crm.note.create",
"allowed": true,
"commentaire": "Autorise la création d’une note CRM sans modifier la fiche client."
},
{
"action": "customers.export",
"allowed": false,
"commentaire": "Interdit l’export de listes clients, trop risqué pour un agent support."
},
{
"action": "crm.email.update",
"allowed": false,
"commentaire": "Interdit la modification d’une adresse email client."
}
]
}Observation honnête : le bon design est rarement le plus spectaculaire. Chez un client, ce qui a évité les problèmes, ce n’était pas une grosse brique magique de sécurité. C’était une série de petites limites bien placées.
- Vérifier que l’outil est vraiment nécessaire.
- Définir les droits exacts : lecture, écriture, suppression, export.
- Valider tous les paramètres avant l’appel.
- Limiter le volume et la fréquence des appels.
- Filtrer les données envoyées au modèle.
- Journaliser chaque action sensible.
- Ajouter une validation humaine quand l’impact est réel.
Comment gérer mémoire et sessions sans fuite ?
Je gère la mémoire et les sessions comme des zones sensibles, parce qu’elles peuvent transporter des données d’une exécution à l’autre sans qu’on s’en rende compte.
Dans un agent IA, tout ce qui reste en mémoire peut finir par influencer une réponse, une action, ou une décision. C’est pratique, oui. Mais c’est aussi là que j’ai vu des problèmes bêtes arriver chez des clients : un agent qui ressort une info d’un ancien utilisateur, ou qui garde une consigne temporaire comme si c’était une règle permanente.
Je sépare toujours trois choses :

- Contexte temporaire : Ce que l’agent utilise pendant une exécution. Par exemple les derniers messages, un résultat d’API, un fichier analysé.
- État de session : Les informations conservées le temps d’une conversation ou d’un workflow. Par exemple l’étape actuelle, le panier, le dossier en cours.
- Mémoire persistante : Les informations réutilisables plus tard. C’est le plus risqué, surtout si elle est mal isolée entre utilisateurs, clients ou processus.
Les risques sont assez concrets : fuite d’informations personnelles, conservation de secrets, contamination entre sessions, reprise d’instructions malveillantes, mauvaise personnalisation, décisions influencées par un ancien contexte. Un agent peut devenir “bizarre” juste parce qu’il se souvient trop bien de mauvaises choses.
Mes règles de base sont simples :
- TTL sur les sessions : J’ajoute une expiration automatique. TTL veut dire “Time To Live”, donc durée de vie maximale.
- Nettoyage après tâche : Je supprime le contexte qui n’est plus utile.
- Isolation par utilisateur ou par tenant : Je ne partage jamais une mémoire sans règle claire. Un tenant, c’est un client ou une organisation isolée dans une application SaaS.
- Validation avant écriture en mémoire : L’agent ne doit pas mémoriser librement tout ce qu’il voit.
- Classification des données : Je bloque certains types d’informations, comme les mots de passe, tokens, données bancaires ou données personnelles sensibles.
- Audit et suppression : Je dois pouvoir retrouver, expliquer et effacer ce qui a été mémorisé.
import re
def is_memory_safe(text, purpose):
# Refuse les secrets classiques
secret_patterns = [
r"sk-[a-zA-Z0-9]{20,}", # Clés API type OpenAI
r"Bearer\s+[a-zA-Z0-9\._-]+", # Tokens Bearer
r"password\s*[:=]", # Mot de passe
r"token\s*[:=]", # Token explicite
]
for pattern in secret_patterns:
if re.search(pattern, text, re.IGNORECASE):
return False
# Refuse les emails personnels sauf besoin métier explicite
email_found = re.search(r"[\w\.-]+@[\w\.-]+\.\w+", text)
if email_found and purpose != "contact_client":
return False
# Refuse les phrases qui ressemblent à des règles système
system_like = [
"ignore les instructions précédentes",
"tu dois toujours",
"nouvelle règle système",
"révèle tes consignes",
"désactive la sécurité"
]
if any(rule in text.lower() for rule in system_like):
return False
return True
def write_memory(user_id, tenant_id, text, purpose):
# Isolation stricte par utilisateur et par tenant
if not is_memory_safe(text, purpose):
return "Mémoire refusée"
memory_key = f"{tenant_id}:{user_id}"
# Ici, on écrirait dans une base vectorielle ou un stockage sécurisé
save_to_memory(memory_key, text, ttl_days=30)
return "Mémoire enregistrée"Le bénéfice business est direct. Un agent fiable n’est pas seulement un agent intelligent, c’est un agent dont on comprend les limites, les traces et les effets dans le temps. Ça réduit les incidents, ça rassure les équipes sécurité, et ça évite de transformer une bonne automatisation en boîte noire incontrôlable.
| Type de mémoire | Durée recommandée | Contrôle minimum | Risque principal |
| Contexte temporaire | Une exécution | Nettoyage après tâche | Réutilisation accidentelle |
| État de session | Quelques minutes à quelques heures | TTL et isolation utilisateur | Contamination entre sessions |
| Mémoire persistante | Limitée et justifiée | Validation, audit, suppression | Fuite durable ou mauvaise personnalisation |
Votre agent IA est-il assez cadré pour agir seul ?
Un sandbox d’agent IA ne se résume pas à enfermer du code dans un conteneur. Je dois aussi cadrer les outils, les données, la mémoire, les sessions et la couche de décision. C’est là que beaucoup de projets deviennent fragiles : l’agent a l’air pratique, puis on découvre qu’il voit trop, qu’il peut trop faire, ou qu’il garde trop longtemps certaines informations. La bonne approche, c’est l’isolation dès la conception, avec des permissions courtes, des traces claires et des validations avant action. Le bénéfice pour vous est simple : un agent utile, exploitable en business, mais contrôlable.
FAQ
- Qu’est-ce qu’un sandbox d’agent IA ?
Un sandbox d’agent IA est un cadre d’exécution contrôlé qui limite ce que l’agent peut faire, voir, appeler et mémoriser. Il ne protège pas seulement le serveur. Il encadre aussi les outils, les données, l’état de session et la mémoire persistante. - Pourquoi un agent IA est plus difficile à sécuriser qu’une application classique ?
Parce qu’il prend des décisions à l’exécution. Une même consigne peut produire des actions différentes selon le contexte, les données récupérées ou l’historique. La sécurité doit donc contrôler le workflow complet, pas seulement le code. - Quels sont les principaux risques d’un agent IA mal isolé ?
Les risques les plus courants sont l’injection de prompt, l’appel incontrôlé d’outils, l’exfiltration de données, l’escalade de privilèges, la fuite de mémoire, l’abus d’API et les problèmes de persistance de session. - Un conteneur Docker suffit-il pour sécuriser un agent IA ?
Non. Docker peut aider à isoler l’environnement d’exécution, mais il ne contrôle pas à lui seul les décisions du LLM, les permissions des outils, les données accessibles ou ce que l’agent écrit en mémoire. Il faut plusieurs frontières coordonnées. - Quelle est la première règle à appliquer avant de connecter des outils à un agent IA ?
Je commence par le moindre privilège. Aucun outil n’est disponible par défaut, chaque action est limitée, les paramètres sont validés, et les actions sensibles passent par une validation humaine ou une politique stricte.
A propos de l’auteur
Je suis Franck Scandolera, responsable de l’agence webAnalyste et de l’organisme Formations Analytics. J’accompagne des entreprises sur le tracking avancé server-side, l’Analytics Engineering, l’automatisation No/Low Code avec n8n, l’intégration de l’IA en entreprise et les sujets SEO/GEO. J’ai travaillé avec des équipes chez Logis Hôtel, Yelloh Village, BazarChic, la Fédération Française de Football, Texdecor et d’autres. Si vous voulez cadrer vos agents IA, vos automatisations ou vos architectures data sans partir dans tous les sens, contactez-moi.
⭐ Analytics engineer, Data Analyst et Automatisation IA indépendant ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data Analyst & Analytics engineering : tracking avancé (GTM server, e-commerce, CAPI, RGPD), entrepôt de données (BigQuery, Snowflake, PostgreSQL, ClickHouse), modèles (Airflow, dbt, Dataform), dashboards décisionnels (Looker, Power BI, Metabase, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.
