FRENES

Sécurité IA

Faire tourner un agent IA dans un bac à sable

Par · · 6 min

Mini-serveur sur un bureau, à côté d'un ordinateur affichant un terminal flou et d'un câble réseau débranché

Pour isoler un agent IA, exécutez ses commandes dans un environnement qui limite les fichiers accessibles, les connexions réseau et les ressources consommées. Un bac à sable réduit les conséquences d’une erreur ou d’un détournement, sans garantir l’absence de fuite ni d’action dangereuse dans les services autorisés.

1. Définir le périmètre avant de lancer l’agent

Prérequis : une machine Linux de test, un terminal Bash, Docker installé et fonctionnel, ainsi qu’une image de votre agent déjà préparée et disponible localement. Cette image doit contenir ses dépendances et un interpréteur sh. Le tutoriel commence après l’installation : aucune commande universelle ne convient à tous les agents.

L’exemple utilise des conteneurs Linux et un moteur Docker local. Avec un moteur distant, les chemins partagés désignent la machine du moteur. Adaptez également la gestion des permissions si vous utilisez un autre environnement.

Commencez par une tâche limitée : analyser des documents factices et produire un rapport dans un dossier réservé. Écartez les identifiants, les données clients et les connexions métier pendant cette première vérification. Le guide pour sécuriser un agent IA aide à définir ensuite les autorisations adaptées.

Un bac à sable impose des restrictions techniques. Une instruction demandant à l’agent de respecter un dossier ne bloque pas une commande qui en sortirait.

ContrôleConfiguration de départExtension à examiner
FichiersEntrées en lecture seuleCopie de travail modifiable
RéseauAucune connexion extérieureDestinations explicitement autorisées
SecretsAucun identifiantAccès dédié à droits limités
Actions métierAucune connexionBrouillons soumis à validation

Cette progression applique le moindre privilège. Précisez aussi le résultat attendu et les conditions d’arrêt : un agent bloqué ne doit pas obtenir automatiquement davantage de droits.

2. Préparer des données jetables et une image identifiée

Créez un dossier neuf, sans y copier votre répertoire personnel ni un dépôt entier par habitude. Les fichiers de configuration, sauvegardes et historiques peuvent contenir des secrets inutiles à la tâche.

Sur la machine hôte, préparez cette arborescence :

mkdir -p sandbox-agent/entree sandbox-agent/sortie
printf '%s\n' 'Document fictif à analyser.' \
  > sandbox-agent/entree/exemple.txt
cd sandbox-agent

Le dossier d’entrée sera accessible en lecture seule. Le dossier de sortie sera modifiable : considérez tout son contenu comme remplaçable et potentiellement malveillant. La documentation des montages de dossiers précise qu’un partage est inscriptible par défaut ; la restriction de lecture doit donc être explicite.

Choisissez ensuite l’image préalablement vérifiée de votre agent. Évitez une référence flottante pour un essai que vous souhaitez reproduire : utilisez la référence par empreinte fournie par votre registre. La documentation d’exécution des conteneurs décrit cette identification par digest.

La commande suivante demande cette référence sans inventer un nom d’image :

read -r -p 'Référence complète de votre image vérifiée : ' AGENT_IMAGE

Vérifiez sa provenance et son contenu avant de continuer. Le bac à sable ne rend pas fiable une image inconnue.

Ne partagez ni le socket Docker, ni les clés SSH, ni les dossiers de configuration cloud. Évitez également les liens symboliques dans les données préparées : une arborescence simple facilite la relecture et limite les ambiguïtés lors de la récupération des résultats.

3. Démarrer un environnement fermé

Le lancement ci-dessous constitue un exemple de configuration à adapter, construit avec les options de la référence officielle de Docker. Il ouvre un terminal dans l’image choisie ; il ne suppose aucune commande particulière pour votre agent.

docker run --rm -it \
  --name agent-bac-a-sable \
  --pull=never \
  --network none \
  --read-only \
  --user "$(id -u):$(id -g)" \
  --cap-drop ALL \
  --security-opt no-new-privileges=true \
  --memory 1g \
  --memory-swap 1g \
  --cpus 1 \
  --pids-limit 128 \
  --tmpfs /tmp:rw,nosuid,nodev,size=256m,mode=1777 \
  --mount "type=bind,src=$(pwd)/entree,dst=/entree,readonly" \
  --mount "type=bind,src=$(pwd)/sortie,dst=/sortie" \
  --workdir /sortie \
  --env HOME=/tmp \
  --entrypoint sh \
  "$AGENT_IMAGE"

Les valeurs de mémoire, de processeur, de processus et d’espace temporaire sont des choix pour cet exemple, pas des besoins mesurés d’un agent. Ajustez-les à la charge prévue. Elles ne plafonnent ni la taille du dossier de sortie sur l’hôte, ni une éventuelle facture d’API.

Le processus utilise votre identifiant utilisateur, sans capacités Linux supplémentaires. La racine est en lecture seule ; les écritures utiles vont dans le dossier de sortie et l’espace temporaire. L’image doit accepter ce fonctionnement sans compte administrateur.

Conservez le profil seccomp par défaut lorsqu’il est disponible. Si une erreur apparaît, identifiez son origine avant de modifier la protection.

Avec le réseau désactivé, seule l’interface de boucle locale subsiste. Un agent dépendant d’une API distante ne pourra donc pas encore fonctionner : cette étape vérifie d’abord son environnement d’exécution.

4. Vérifier les refus avant la première tâche

Dans le terminal du conteneur, lancez ces contrôles simples :

id
touch /entree/ecriture-interdite
touch /ecriture-interdite
printf '%s\n' 'sortie autorisée' > /sortie/controle.txt
printf '%s\n' 'temporaire autorisé' > /tmp/controle.txt
test ! -S /var/run/docker.sock && printf '%s\n' 'Socket Docker absent'

Les écritures dans l’entrée et à la racine doivent échouer. Celles dans la sortie et dans l’espace temporaire doivent réussir. Contrôlez aussi que l’identifiant affiché ne correspond pas au compte administrateur.

Ces vérifications sont des tests fonctionnels ciblés, pas un audit de sécurité. L’absence du socket à cet emplacement ne prouve notamment pas l’absence de toute autre interface d’administration.

Depuis un autre terminal de l’hôte, examinez la configuration effective :

docker inspect agent-bac-a-sable

Vérifiez les montages, le réseau, l’utilisateur et les limites. Si votre image fournit un outil de diagnostic réseau, tentez aussi une connexion vers une destination de test : elle doit échouer. Un programme absent ne constitue pas une preuve de blocage.

Lancez ensuite votre agent avec la commande documentée pour votre propre image. Donnez-lui une consigne bornée : lire le document fictif et écrire un rapport dans le dossier de sortie. Sans modèle local embarqué, cette tâche attendra l’étape réseau.

Ajoutez enfin un document factice contenant une injection de prompt qui demande une écriture interdite. Le résultat recherché est le refus technique de l’opération, même si l’agent suit la mauvaise instruction. Notre article sur l’injection de prompt explique pourquoi ce contrôle complète les consignes données au modèle.

5. Ajouter uniquement les accès nécessaires

Pour utiliser un modèle distant, prévoyez une seconde configuration réseau. Retirer simplement le blocage ouvre une possibilité de communication extérieure ; cela demande une nouvelle évaluation des fichiers et secrets accessibles.

Une architecture à examiner consiste à garder les outils d’exécution sans réseau et à placer les appels au modèle dans un service séparé. Ce service conserve les identifiants et transmet uniquement les données nécessaires. Toute donnée envoyée au modèle quitte néanmoins le bac à sable, même si le processus qui exécute le code reste isolé.

Si l’agent doit accéder lui-même au réseau, imposez les restrictions depuis l’infrastructure : relais obligatoire, filtrage des destinations et blocage des chemins directs. Une variable de configuration de proxy ne suffit pas si le programme peut la contourner.

Distinguez également permission technique et autorisation métier. Un accès à une messagerie peut permettre un envoi regrettable sans aucune sortie du conteneur. Préparez les brouillons dans l’environnement isolé, puis soumettez leur envoi à une validation extérieure.

Pour les connecteurs, le guide de choix d’un serveur MCP complète cette vérification. Un serveur distant agit avec ses propres identifiants : isoler le terminal local ne réduit pas automatiquement ses droits.

Enfin, traitez les résultats comme des données non fiables. Relisez les modifications avant de les intégrer ; n’exécutez pas un script produit par l’agent directement sur votre poste. L’article sur la sécurité des agents IA détaille ces autres voies de risque.

Problèmes fréquents

L’agent refuse de démarrer. Il peut chercher à écrire sa configuration dans un emplacement protégé ou nécessiter un utilisateur nommé. Préparez une image adaptée, puis ajoutez seulement les espaces d’écriture identifiés. Ne rendez pas toute la racine modifiable pour résoudre une erreur de cache.

Les sorties sont inaccessibles. Examinez les propriétaires et permissions du dossier hôte, ainsi que les éventuelles règles de sécurité locales. Évitez d’accorder des droits d’écriture à tous les utilisateurs.

Le processus s’arrête pendant une tâche. Consultez son état et ses erreurs avant d’augmenter les limites. Une saturation peut venir d’une charge légitime, d’une boucle ou d’un nombre excessif de sous-processus.

Le conteneur semble isolé, mais dispose de droits étendus. Recherchez les montages supplémentaires, les connexions métier et les interfaces d’administration. La documentation de sécurité du moteur rappelle que les conteneurs partagent des mécanismes du noyau et que certaines configurations compromettent l’isolation.

Le mode sans privilèges administrateur réduit certains risques liés au moteur. Pour du code potentiellement hostile, envisagez une machine virtuelle jetable dédiée, sans données sensibles partagées.

Checklist avant utilisation

Quittez le terminal du conteneur après l’essai. Dans cette configuration, sa suppression automatique ne supprime pas les dossiers partagés : inspectez leur contenu et recréez un environnement propre pour la tâche suivante.

  • Les données fournies sont nécessaires et dépourvues de secrets inutiles.
  • Les écritures interdites échouent et les sorties autorisées fonctionnent.
  • Les connexions extérieures sont bloquées ou explicitement contrôlées.
  • Les limites de ressources et les conditions d’arrêt sont définies.
  • Les actions sensibles exigent une validation extérieure.
  • Les résultats seront relus avant leur utilisation.

Le diagnostic de sécurité des agents IA permet de compléter cette checklist selon les accès réellement accordés.

Questions fréquentes

Un conteneur suffit-il pour sécuriser un agent IA ?

Il fournit une couche d'isolation dont l'efficacité dépend des droits accordés. Pour exécuter du code potentiellement hostile, envisagez aussi une machine virtuelle dédiée et jetable, sans partage de dossiers sensibles.

Peut-on utiliser une API de modèle sans ouvrir tout Internet ?

Oui, avec une architecture qui impose les communications par un relais contrôlé. Le filtrage doit être appliqué hors de portée de l'agent et tenir compte des destinations réellement nécessaires.

Un environnement Python virtuel est-il une sandbox ?

Un environnement virtuel sépare les dépendances Python. Il ne constitue pas une frontière de sécurité pour les fichiers, les connexions réseau ou les commandes exécutées avec les droits de votre compte.

Faut-il donner sa clé API à l'agent isolé ?

Évitez de transmettre une clé générale lorsqu'un relais peut conserver le secret et effectuer les appels autorisés. Si une clé doit entrer dans l'environnement, réservez-la à cet usage, limitez ses droits et prévoyez sa révocation.

Dans la même rubrique

Neutralité. Aucun lien d'affiliation. Aucun éditeur ne paie pour être évalué, noté ou classé. Les évaluations sont dirigées par François Chollet, neutres et factuelles, et chaque donnée est datée et sourcée. Comment nous notons