environnements waza sécurisés

waza : sécuriser vos agents et vos environnements

Anti-patterns et pièges RubyAvancé

waza : sécuriser vos agents et vos environnements

Un agent LLM qui accède à votre dossier ~/.ssh n’est pas un outil de productivité, c’est une vulnér’abilité critique. Les environnements waza sécurisés existent précisément pour empêcher ce type de catastrophe systémique.

La montée en puissance des agents autonomes (AutoGPT, BabyAGI) introduit un nouveau vecteur d’attaque : l’exécution de code non vérifié avec les privilèges de l’utilisateur courant. Les statistiques de sécurité sur les pipelines CI/CD montrent une augmentation de 40% des incidents liés à l’exfiltration de secrets via des processus enfants mal isolés en 2023.

Après la lecture de ce guide, vous saurez identifier les fuites de contexte entre votre hôte et vos agents, et comment configurer des environnements waza sécurisés pour isoler strictement les processus critiques.

environnements waza sécurisés

🛠️ Prérequis

Installation des composants nécessaires pour tester l’isolation :

  • Linux Kernel 5.15 ou supérieur (pour le support complet des namespaces et cgroups v2).
  • Go 1.22+ (pour compiler les wrappers de sécurité).
  • waza CLI version 1.0.4+.
  • Utilisateur avec privilèges sudo pour la configuration des cgroups.

📚 Comprendre environnements waza sécurisés

Le concept repose sur l’isolation par couches. Contrairement à Docker qui utilise des images complètes, les environnements waza sécurisés se concentrent sur la restriction des primitives système Linux.

Architecture de l'isolation :
[ Host Kernel ]
      | 
      +-- [ cgroups (Resource Limits) ]
      | 
      +-- [ Namespaces (Isolation) ]
      |     |-- PID (Process visibility)
      |     |-- NET (Network stack)
      |     |-- MNT (Filesystem mount)
      |     +-- UTS (Hostname)
      | 
      +-- [ seccomp (Syscall filtering) ]
      |
      +-- [ Waza Agent Sandbox ]

En Ruby, nous utilisons souvent Process.spawn ou Open3.capture3. Ces méthodes héritent par défaut de l’environnement de l’hôte. L’utilisation de waza impose une rupture de ce lien. On ne cherche pas la portabilité, on cherche l’étanchéité. Là où un développeur Rails cherche la facilité, le développeur sécurité cherche l’imprévisibilité contrôlée.

💎 Le code — environnements waza sécurisés

Ruby
require 'open3'
require 'etc'

# Simulation d'un exécuteur non sécurisé
# Ce code illustre le danger de l'héritage de l'environnement
class UnsafeExecutor
  def run_agent(script_path)
    puts "Exécution de l'agent : #{script_path}"
    # Erreur critique : on ne filtre pas ENV
    # L'agent voit AWS_SECRET_KEY, DATABASE_URL, etc.
    stdout, stderr, status = Open3.capture3("ruby #{script_path}")
    
    if status.success?
      puts "Résultat : #{stdout}"
    else
 $stderr.puts "Erreur : #{stderr}"
    end
  end
end

# Exemple d'utilisation qui expose les secrets
# Imaginons que ENV['STRIPE_API_KEY'] soit défini
ENV['STRIPE_API_KEY'] = 'sk_live_123456789'
executor = UnsafeExecutor.new
executor.run_agent('agent_malveillant.rb')

📖 Explication

Dans le premier snippet, l’utilisation de Open3.capture3("ruby #{script_path}") est la source du problème. Sans le premier argument, Ruby passe le hash ENV complet. C’est une violation du principe du moindre étonnement : on ne s’attend pas à ce qu’un simple script de test puisse lire les clés Stripe de l’application parente.

Dans le second snippet, nous passons explicitement un hash @allowed_sane_env. Notez que nous n’incluons que le PATH. Cela signifie que même si l’agent tente de chercher une variable secrète, elle n’existe tout simplement pas dans son contexte. C’est la base de la construction d’environnements waza sécurisés : la création d’un vide informationnel autour du processus tiers.

Documentation officielle Ruby

🔄 Second exemple

Ruby
require 'open3'

# Simulation d'un exécuteur utilisant des environnements waza sécurisés
# Ici, on applique le principe du moindre privilège
class WazaSecureExecutor
  def initialize(allowed_env = { 'PATH' => '/usr/bin:/bin' })
    @allowed_sane_env = allowed_env
  end

  def run_agent_securely(script_path)
    puts "Exécution sécurisée via waza-layer : #{script_path}"
    
    # On ne passe QUE l'environnement filtré
    # On utilise l'option env de capture3
    stdout, stderr, status = Open3.capture3(@allowed_sane_env, "ruby #{script_path}")

    if status.success?
      puts "Résultat sécurisé : #{stdout}"
    else
      puts "Échec de l'isolation : #{stderr}"
    end
  end
end

# Utilisation correcte
# L'agent ne verra jamais STRIPE_API_KEY
executor = WazaSecureExecutor.new
executor.run_agent_securely('agent_malveillant.rb')

▶️ Exemple d’utilisation

Exemple de commande pour lancer un environnement isolé via l’interface CLI de waza (simulée) :

# Création d'un environnement avec limite de 50MB de RAM et accès réseau coupé
waza run --mem 50M --no-net --env PATH=/bin -- script_agent.rb

Sortie attendue si l’agent tente d’accéder au réseau :

[Waza] Initializing sandbox...
[Waza] Namespace MNT, NET, PID applied.
[Waza] Execution started.
[Agent] Attempting to connect to api.stripe.com...
[Waza] Error: Network access denied by policy.
[Waza] Process terminated with exit code 1.

🚀 Cas d’usage avancés

1. Exécution de plugins tiers : Dans une application SaaS, utilisez un wrapper waza pour exécuter le code des utilisateurs sans risque de fuite de votre configuration database.yml.
2. Pipelines de test de sécurité : Lancez des scanners de vulnérabilités dans des environnements waza sécurisés pour éviter que le scanner lui-même ne soit compromis par un dépôt malveillant.
3. Systèmes d’automatisation par IA : Lorsqu’un agent LLM génère et exécute du code pour répondre à une requête, l’isolation doit être totale (Network, PID, MNT).

🐛 Erreurs courantes

⚠️ Fuite d'environnement

Transmettre l’objet ENV complet au sous-processus.

✗ Mauvais

Open3.capture3("ruby agent.rb")
✓ Correct

Open3.capture3({"PATH" => "/bin"}, "ruby agent.rb")

⚠️ Montage racine trop large

Donner accès à tout le répertoire de travail ou au home utilisateur.

✗ Mauvais

waza run --mount /home/user/app:/app
✓ Correct

waza run --mount /tmp/sandbox_data:/app

⚠️ Absence de limite mémoire

Laisser l’agent consommer toute la RAM disponible.

✗ Mauvais

Process.spawn("python script.py")
✓ Correct

waza run --mem 128M python script.py

⚠️ Accès réseau non filtré

Permettre à l’agent de contacter l’internet ou le LAN.

✗ Mauvais

system("./agent_script")
✓ Correct

waza run --no-net ./agent_script

✅ Bonnes pratiques

Pour garantir l’intégrité de vos services, suivez ces règles d’or :

  • Principe du moindre privilège : Ne donnez jamais plus de variables d’environnement que ce qui est strictement nécessaire au fonctionnement du script.
  • Immutabilité du système de fichiers : Montez vos dépendances en lecture seule (ro).
  • Isolation réseau systématique : Utilisez des environnements waza sécurisés avec l’option --no-net par défaut pour tout agent non supervisé.
  • Surveillance des ressources : Configurez toujours des limites de CPU et de mémoire pour éviter les attaques par déni de service (DoS) interne.
  • Audit des syscalls: Utilisez des profils seccomp pour interdire les appels système dangereux comme mount ou ptrace.
Points clés

  • L'héritage de ENV est la première cause de fuite de secrets.
  • L'isolation réseau est obligatoire pour les agents autonomes.
  • Le montage de dossiers persistants expose votre application à l'écriture malveillante.
  • Les cgroups protègent votre hôte contre l'épuisement des ressources.
  • Waza permet d'appliquer des primitives Linux (namespaces) de manière simple.
  • Un agent ne doit jamais voir le processus parent (PID namespace).
  • Le principe du moindre étonnement s'applique : un agent ne doit pas pouvoir modifier son environnement.
  • La sécurité ne doit pas être une option, mais une couche d'infrastructure.

❓ Questions fréquentes

Est-ce que waza est aussi lourd que Docker ?

Non. Docker crée des couches d’abstraction et un réseau virtuel complet. Waza se contente de restreindre les primitives existent du noyau Linux, ce qui est beaucoup plus léger.

Puis-je utiliser waza pour des applications Rails entières ?

C’est possible, mais l’objectif est l’isolation de processus tiers. Pour une application entière, Docker reste le standard industriel.

Comment savoir si mon agent a réussi à s'échapper ?

Utilisez des outils de monitoring comme auditd pour surveper les appels système suspects ou les tentatives d’accès aux fichiers sensibles.

Est-ce compatible avec les conteneurs Kubernetes ?

Oui, waza peut être utilisé comme un sidecar ou comme un wrapper de commande à l’intérieur d’un pod pour isoler des tâches spécifiques.

📚 Sur le même blog

🔗 Le même sujet sur nos autres blogs

📝 Conclusion

Sécuriser l’exécution de code tiers n’est pas une option de confort, c’est une nécessité de survie pour tout développeur manipulant des agents autonomes. L’utilisation d’environnements waza sécurisés permet de transformer un risque d’exécution de code en un simple processus isolé et contrôlé. Pour approfondir la gestion des processus en Ruby, consultez la documentation Ruby officielle. Un processus sans limite est une bombe à retardement dans votre infrastructure.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *