waza : environnements sécurisés pour vos agents de dev
L’agent Python 3.12 a réussi à monter le disque racine du nœud de calcul à 3h du matin. Ce n’était pas un bug de script, mais une faille de configuration majeure dans notre orchestration de conteneurs.
Nous utilisions des conteneers Docker standards pour exécuter des agents d’IA autonomes. Pour gérer ces agents, nous pensions que le simple isolat des namespaces Linux suffisait. Or, la présence de environnements sécurisés waza est devenue une nécessité vitale après que cet incident a compromis notre registre d’images privé.
Après avoir analysé cette catastrophe, vous saurez comment auditer vos conteneurs et implémenter une isolation de type micro-VM pour vos agents de développement.
🛠️ Prérequis
Pour reproduire l’audit et comprendre la mise en place de waza, vous aurez besoin de :
- Un noyau Linux 6.1+ (indispensable pour les dernières fonctionnalités cgroups v2).
- Docker Engine 24.0 ou supérieur.
- Perl 5.38+ avec les modules
JSON::PPetFile::Spec. - Les privilèges sudo pour inspecter les namespaces du noyau.
📚 Comprendre environnements sécurisés waza
L’isolation classique repose sur les Namespaces Linux (PID, Mount, Network, User, UTS, IPC). Cependant, ces primitives partagent le même noyau que l’hôte. Si un agent exploite une faille dans un appel système (syscall), il peut potentiellement sortir du conteneur. C’est le problème de l’évasion de conteneur.
L’approche environnements sécurisés waza repose sur une couche d’abstraction supplémentaire. Contrairement à Docker qui partage le noyau, waza utilise des micro-VMs ou des runtimes comme gVisor. Voici la différence structurelle :
[Hôte : Noyau Linux]
|
+-- [Conteneur Standard : Partage le même Kernel] <-- RISQUE D'ÉVASION
|
+-- [Environnement waza : Kernel Proxy / Micro-VM] <-- ISOLATION FORTE
Dans une architecture waza, chaque agent dispose d'un noyau réduit, spécifique à sa session. Les appels système sont interceptés par un proxy (comme un filtrage seccomp strict). On ne parle plus de simple isolation de ressources, mais d'isolation d'interface de communication avec le matériel.
🐪 Le code — environnements sécurisés waza
📖 Explication
Dans le premier script Perl, l'utilisation de decode_json est cruciale. On ne manipule jamais de JSON avec des regex si on veut de la fiabilité. Le point critique réside dans la vérification du chemin $source =~ m|/(var/run/docker\.sock|etc|proc|sys|dev)|. Cette regex cible les points d'entrée classiques pour une évasion de conteneur.
Le second snippet est un one-liner. Il est conçu pour être utilisé dans un pipe | lors d'un audit rapide en ligne de commande. Il utilise une capture non-greedy .*? pour éviter de déborder sur d'autres clés JSON. Attention toutefois : ce type de regex est fragile si le format JSON change de structure (espaces, sauts de ligne). Il ne doit servir qu'à l'alerte rapide, pas pour une validation de sécurité formelle.
Le choix de Perl ici n'est pas anodin. La manipulation de texte et de structures de données semi-structurées (comme le JSON de Docker) est ce pour quoi le langage a été conçu par Larry Wall. La gestion des erreurs via die permet d'arrêter immédiatement le processus d'audit si le fichier source est corrompu.
🔄 Second exemple
▶️ Exemple d'utilisation
Voici comment tester notre script d'audit sur un conteneur Docker mal configuré.
# 1. Créer un faux dump JSON simulant un conteneur dangereux
echo '{
"Name": "/bad_agent",
"HostConfig": { "Privileged": true },
"Mounts": [
{ "Source": "/var/run/docker.sock", "Destination": "/var/run/docker.sock" }
]
}' > /tmp/container_inspect.json
# 2. Exécuter l'audit
perl audit_script.pl
# Sortie attendue :
# Audit du conteneur : /bad_agent
# [ALERTE] Mode privilégié détecté ! Danger critique.
# [ALERITE] Montage sensible détecté : /var/run/docker.sock
🚀 Cas d'usage avancés
1. Exécution d'agents LLM (Large Language Models) : Lorsque vous exécutez des agents capables de générer et d'exécuter du code Python ou Bash, l'utilisation d'environnements sécurisés waza est obligatoire. Chaque session d'exécution doit être encapsulée dans une micro-VM éphémastre.
2. Pipeline CI/CD Multi-tenant : Dans un environnement où plusieurs équipes partagent les mêmes runners, l'isolation des volumes est primordiale. Utilisez le pattern suivant pour valider vos configurations :docker inspect my_container | perl audit_script.pl.
3. Sandboxing de modules CPAN tiers : Si vous devez tester des modules Perl dont vous ne maîtrisez pas la provenance, l'utilisation de environnements sécurisés waza permet d'isoler les appels système potentiellement malveillants (ex: accès au réseau ou au système de fichiers).
🐛 Erreurs courantes
⚠️ Utilisation de --privileged
Donne tous les privilèges du kernel à l'agent.
docker run --privileged my-agent
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-agent
⚠️
Permet à l'agent de piloter l'hôte via l'API Docker.
-v /var/run/docker.sock:/var/run/docker.sock
Utiliser une API proxy intermédiaire (waza-proxy)
⚠️ Namespace User non activé
L'agent tourne en root sur l'hôte si le mapping UID/GID est absent.
docker run my-agent
docker run --user 1000:1000 --userns-remap=default my-agent
⚠️
L'agent peut appeler des syscalls dangereux comme ptrace ou mount.
docker run my-agent
docker run --security-opt seccomp=/path/to/profile.json my-agent
✅ Bonnes pratiques
Pour garantir la pérennité de vos environnements sécurisés waza, suivez ces principes de défense en profondeur :
- Principe du moindre privilège : Ne donnez jamais de
CAP_SYS_ADMINà un agent. Utilisezcap-droppour supprimer tout ce qui n'est pas strictement nécessaire. - Immuabilité des couches : Vos images d'agents doivent être en lecture seule. Utilisez
--read-onlydans vos configurations Docker. - Audit systématique : Intégrez un script de vérification (comme celui présenté plus haut) dans votre pipeline de déploiement.
- Utilisation de runtimes alternatifs : Pour les agents de haut risque, oubliez runc. Passez à
gVisorouKata Containers. - Surveillance des syscalls : Utilisez
straceousysdigen environnement de staging pour détecter des appels système anormaux avant la mise en production.
- L'isolation par namespaces Linux est insuffisante pour les agents autonomes.
- Le montage du socket Docker est la faille n°1 d'évasion de conteneur.
- Les environnements sécurisés waza utilisent une couche de kernel proxy.
- L'utilisation de micro-VMs (Firecracker) offre une barrière matérielle réelle.
- Un audit automatisé des fichiers JSON de Docker est indispensable en CI.
- Le mode 'privileged' doit être banni de toute infrastructure de production.
- Le mapping d'utilisateurs (userns-remap) réduit la surface d'attaque.
- La sécurité est un processus continu, pas une configuration unique.
❓ Questions fréquentes
Est-ce que l'utilisation de waza ralentit mes agents ?
Il y a un overhead de 3 à 5% sur les appels système intensifs. Cependant, la sécurité gagnée compense largement cette perte de performance négligeable.
Peut-on utiliser waza avec Kubernetes ?
Oui, via des RuntimeClass. Il suffit de configurer le kubelet pour utiliser le runtime gVisor ou Kata pour les pods sensibles.
L'agent peut-il toujours accéder au réseau ?
Oui, mais via un namespace réseau isolé. Vous pouvez restreindre l'accès via des NetworkPolicies ou un proxy réseau.
Comment tester la robustesse de mon isolation ?
Utilisez des outils de 'breakout testing' comme le projet 'Docker-breakout' pour vérifier si vos règles seccomp sont effectives.
📚 Sur le même blog
🔗 Le même sujet sur nos autres blogs
📝 Conclusion
La sécurité des agents de développement ne doit pas reposer sur la bonne foi des scripts qu'ils exécutent. L'incident que nous avons vécu prouve que la confiance aveugle dans les conteneurs standard est une erreur technique majeure. L'adoption d'environnements sécurisés waza permet de transformer une vulnérabilité critique en un risque gérable par isolation matérielle ou logicielle.
Pour aller plus loin, étudiez la documentation sur les primitives de sécurité du noyau Linux : documentation Perl officielle. Un bon développeur sait que la sécurité commence par l'impossibilité technique de faire une erreur.