SSD Nodes Learn Hosting plans →
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-28

Auto-héberger open-kritt pour scanner votre code

Installez open-kritt sur un VPS avec Docker Compose, figez une release, accédez à l’interface via un tunnel SSH sur le port 5173 et définissez votre budget.

Pourquoi auto-héberger open-kritt sur un VPS plutôt que sur votre ordinateur portable

Auto-hébergez open-kritt sur un serveur que vous pouvez détruire et recréer. L’outil exécute ses agents d’analyse en tant que root dans des conteneurs de jobs temporaires, fournit à chacun une copie inscriptible de votre code et un accès direct à Internet, puis monte le socket Docker de l’hôte dans son service engine. Ce compromis est raisonnable sur une machine dédiée à cette tâche. Il est mauvais sur la machine qui contient vos clés SSH.

Quatre propriétés de la configuration par défaut justifient cette recommandation. Elles proviennent toutes du README et du fichier compose du projet.

Les agents sont conçus pour être puissants. Le README indique que les agents dotés d’outils s’exécutent en tant que root dans des conteneurs de jobs temporaires, avec des copies inscriptibles des dépôts et un accès direct à Internet. Ils peuvent donc installer des outils, compiler des cibles, exécuter des tests et construire des preuves de concept. Une analyse n’est pas un linter qui lit des fichiers. Il s’agit d’une exécution de code arbitraire que vous avez explicitement demandée. Cet accès à Internet présente un risque dans les deux sens : tout ce qu’un agent récupère pendant l’analyse d’une cible est du texte non fiable qui arrive dans son prompt. Vous êtes exposé de la même manière lorsque vous donnez à un agent son propre accès à la recherche web.

L’engine détient le socket Docker. docker-compose.yml monte le socket Docker de l’hôte dans le service engine, car l’engine construit et lance un conteneur d’analyse pour chaque job. Tout processus qui peut accéder à ce socket peut démarrer un conteneur montant le système de fichiers de l’hôte. L’engine dispose donc, en pratique, des privilèges root sur l’hôte qui l’exécute.

Il n’y a pas d’écran de connexion. Le backend est fourni sans authentification applicative. L’accès au port donne accès à vos résultats et au crédit de votre fournisseur.

Le code analysé ne vous appartient souvent pas. Pointer les agents vers un dépôt tiers revient à exécuter le build de ce dépôt sur votre machine, en tant que root et avec un accès réseau.

Si vous avez lu pourquoi les agents de programmation doivent rester dans une VM temporaire, il s’agit du même modèle de menace, mais plus puissant. Donnez à open-kritt un VPS qui n’héberge rien d’autre et administrez ce VPS depuis un compte utilisateur distinct avec le principe du moindre privilège, plutôt que depuis root.

Ce que fait réellement open-kritt

open-kritt (le dépôt est Kritt-ai/open-kritt et est distribué sous licence AGPL-3.0) décompose la recherche de vulnérabilités en petites tâches, exécute ces tâches en parallèle avec plusieurs agents IA, puis déduplique et classe les résultats. Vous définissez un workflow sous la forme d’une chaîne de prompts ciblés. Chaque étape reçoit le contexte structuré des étapes précédentes. La cible du scan est un dépôt git distant ou local. Le moteur d’analyse est Codex ou Claude Code. Lorsqu’un résultat potentiel apparaît, des post-scripts facultatifs peuvent tenter de le valider ou de construire une preuve de concept. Concevoir cette chaîne relève du fonctionnement courant des agents, et non de la sécurité. Si les prompts, les outils et le transfert de contexte vous sont encore peu familiers, apprendre comment les agents sont construits vous aidera davantage que n’importe quel réglage présenté dans ce guide.

À la fin, vous obtenez une liste classée de résultats potentiels. Utilisez-la comme une file de triage, et non comme un rapport.

Ce dont vous avez besoin avant de commencer

  • Un VPS exécutant Ubuntu 24.04, Debian 12 ou Rocky Linux 9. La documentation d’installation indique qu’il s’agit des distributions testées, sur x86_64 et ARM64.
  • Docker Engine avec le plugin Compose.
  • Node.js 20 ou une version ultérieure sur l’hôte, car la CLI ./kritt s’exécute sur l’hôte et non dans un conteneur.
  • Un fournisseur de modèles : un compte Codex, ou OPENAI_API_KEY, CODEX_API_KEY, ANTHROPIC_API_KEY ou OPENROUTER_API_KEY.
  • GITHUB_TOKEN uniquement si vous prévoyez d’analyser des dépôts privés. Le .env.example fourni l’indique clairement : un token GitHub seul ne permet pas d’exécuter des analyses.

Installer Docker et Node 20 au préalable

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

Déconnectez-vous, puis reconnectez-vous pour appliquer l’appartenance au nouveau groupe. Vérifiez ensuite que le plugin Compose est présent.

docker compose version

L’affichage d’une chaîne de version signifie que Compose est installé comme plugin. docker: 'compose' is not a docker command indique à l’inverse que vous disposez de l’ancien binaire autonome docker-compose, et open-kritt appelle docker compose. L’appartenance au groupe docker équivaut à un accès root sur l’hôte. Ajoutez-y donc uniquement le compte qui exécute open-kritt. Pour la procédure complète, consultez exécuter Docker sur un VPS.

Ubuntu 24.04 fournit Node 18 dans son propre dépôt, mais la CLI s’arrête avec toute version antérieure à 20. Utilisez NodeSource.

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v

node -v doit afficher v20. ou une version supérieure. Sur Rocky Linux 9, l’équivalent est sudo dnf module enable nodejs:20 -y, suivi de sudo dnf install -y nodejs.

Cloner open-kritt et utiliser une release taguée

git clone https://github.com/Kritt-ai/open-kritt
cd open-kritt
git fetch --tags
git tag --list
git checkout v1.3.0

main évolue avec le temps. Un tag, non. En août 2026, le tag le plus récent est v1.3.0, publié le 4 août 2026, et git tag --list affiche les tags disponibles le jour où vous clonez le dépôt. Le checkout d’un tag place le dépôt dans l’état detached HEAD, ce qui est correct ici : vous utilisez ce clone comme un déploiement figé, et non comme une branche sur laquelle vous allez créer des commits. Pour effectuer une mise à niveau ultérieure, lisez les notes de version, puis exécutez git fetch --tags, faites le checkout du nouveau tag et exécutez à nouveau ./kritt start, car start reconstruit les images.

N’exécutez pas ./kritt avec sudo. La documentation l’indique explicitement. La CLI gère les répertoires d’identifiants propres au projet sous .data/. Une exécution en tant que root laisse donc ces répertoires appartenir à root, et l’exécution normale suivante ne peut pas y écrire.

Configurer l’accès aux modèles avec ./kritt setup

./kritt setup

La commande crée .env à partir de .env.example s’il n’existe pas, affiche l’état de chaque identifiant et permet de les définir ou de les supprimer. Elle n’affiche jamais les valeurs dans le terminal. .env et le fichier d’identifiants du moteur sont tous deux écrits avec le mode 0600.

Si vous préférez le faire manuellement :

cp .env.example .env
chmod 600 .env
mkdir -p .data/codex
chmod 700 .data/codex

Modifiez ensuite la clé du fournisseur dans .env et conservez le fichier avec le mode 0600. Dans les deux cas, un identifiant de fournisseur fonctionnel se trouve désormais sur ce serveur. C’est une raison supplémentaire de ne rien héberger d’autre sur cette machine. Créez une clé dédiée à ce seul projet afin que sa révocation ultérieure ne perturbe rien d’important. Garder les secrets hors de portée des agents IA présente cette pratique plus largement.

Définir un plafond de dépenses chez le fournisseur avant le premier scan

open-kritt est conçu pour lancer plusieurs tâches en parallèle, et c’est ce parallélisme qui génère les coûts. Les valeurs par défaut dans .env.example de la version v1.3.0 sont prudentes : ENGINE_WORKER_COUNT=2, décrit dans le fichier comme une valeur prudente pour une petite machine équipée de 2 vCPU, et ENGINE_MAX_CONCURRENT_SCANS=1. Au-dessus se trouvent ENGINE_WORKERS_PER_ACCOUNT=15, le nombre maximal d’appels simultanés au modèle root autorisés sur un même compte fournisseur, et ENGINE_CODEX_MAX_SUBAGENTS_PER_SESSION=5, car une session Codex peut exécuter jusqu’à cinq agents enfants. Si vous augmentez le nombre de workers sur un VPS plus puissant, le nombre d’appels au modèle en cours augmente également.

Rien dans le dépôt ne plafonne vos dépenses. .env.example ne comporte aucun paramètre de budget. Les conditions d’arrêt propres au moteur sont ces limites de workers, ainsi que ENGINE_HARNESS_TIMEOUT_SECONDS, qui vaut par défaut 7200 secondes par exécution du harness. Ici, un harness désigne la boucle qui continue d’appeler le modèle avec des outils et du contexte jusqu’à ce qu’un élément mette fin à l’exécution. Ce délai d’expiration s’applique donc à au programme qui entoure le modèle, et non à ce que le modèle dépense à l’intérieur de celui-ci. Le plafond doit donc être défini chez le provider. Ouvrez la console de votre provider et définissez une limite mensuelle stricte avant le premier scan, et non après. Contrôler le coût d’un agent IA sur un VPS présente les paramètres propres à chaque provider.

Il existe également un mécanisme d’arrêt local. La définition de ENGINE_WORKER_COUNT=0 suspend la récupération de nouveaux jobs. Vous pouvez aussi modifier les mêmes valeurs de workers dans l’écran Settings une fois la stack démarrée.

Ce guide n’indique aucun prix par scan, car le coût dépend de la taille du dépôt, du workflow que vous créez et du modèle utilisé. Exécutez un scan sur un petit dépôt, puis consultez la page d’utilisation de votre fournisseur avant de lancer un scan sur un dépôt volumineux.

Démarrer la stack et vérifier son état

./kritt start

Cette commande vérifie .env et au moins un identifiant, puis exécute docker compose up --build. Le premier build est lent, car il construit les images du frontend, du backend, du moteur, de la vue executor et de la base de données. Il s’exécute aussi au premier plan. La fermeture de la session SSH arrête donc la stack. Démarrez-la dans tmux, ou démarrez-la en mode détaché une fois le premier build terminé. Ces deux méthodes ne survivent pas seules à un redémarrage. Si vous voulez que la stack redémarre après celui-ci, le modèle d’unité systemd présenté dans maintenir un agent auto-hébergé après les redémarrages s’applique directement.

docker compose up -d --build
docker compose ps

docker compose ps doit lister open-kritt-frontend, open-kritt-backend, open-kritt-engine, open-kritt-executor-view et open-kritt-db. Vérifiez ensuite que le backend répond directement sur le serveur.

curl -s http://127.0.0.1:3002/api/health

Une réponse JSON indique que le backend fonctionne. Failed to connect to 127.0.0.1 port 3002: Connection refused indique le contraire, et docker compose logs backend en précise la cause. Arrêtez tous les composants avec docker compose down depuis le répertoire du dépôt.

Une étape facultative : docker compose exec backend npm run seed charge des données de démonstration. C’est un moyen simple de vérifier l’interface avant de lancer un véritable scan.

Accéder à l’interface sur le port 5173 via un tunnel SSH

Chaque service du fichier compose est lié à 127.0.0.1 par défaut : le frontend sur 5173, le backend sur 3002, la vue de l’exécuteur sur 8090 et Postgres sur 5432. Ne modifiez pas ces liaisons. Transférez le port via SSH depuis votre propre machine.

ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip

Ouvrez http://localhost:5173 dans votre navigateur local pendant l’exécution de cette commande. -N signifie que la connexion effectue la redirection et n’ouvre pas de shell. Ajoutez un second -L 8090:127.0.0.1:8090 à la même commande lorsque vous voulez également accéder à la vue de l’exécuteur.

La tentation consiste à définir FRONTEND_BIND_ADDRESS=0.0.0.0 et à supprimer le tunnel. Ne le faites pas. Le backend n’a pas d’écran de connexion. Toute personne qui atteint cette page peut lancer des analyses et consommer le crédit de votre fournisseur. À titre de comparaison, Vaultwarden est conçu pour être exposé sur Internet, et son durcissement repose toujours sur le jeton d’administration et le fichier de sauvegarde, deux leviers qu’open-kritt ne vous fournit pas. Un second piège se trouve en dessous : un port de conteneur publié est traité avant l’application de la stratégie par défaut d’ufw. Une règle ufw deny 5173 semble donc correcte, mais ne bloque rien. Les ports Docker qui contournent ufw présente la chaîne de règles à l’origine de ce comportement.

Dimensionnement du VPS

ENGINE_MIN_FREE_STORAGE_GB vaut 20 par défaut, et le moteur refuse de démarrer un nouveau conteneur de scan par tâche lorsque l’espace de stockage disponible passe sous cette valeur. Les images construites, le cache des clones, les données Postgres et les espaces de travail des tâches résident tous sur le même disque. Un VPS de 20 GB ne lance donc jamais aucun scan. Considérez 40 GB comme le minimum et prévoyez davantage si vous analysez de gros dépôts. N’essayez pas de récupérer de la capacité en installant à côté un service gourmand en stockage, car les besoins mesurés en RAM et en disque dans cette comparaison de PhotoPrism et Immich montrent à quelle vitesse une bibliothèque multimédia consommerait la marge nécessaire aux scans. Il en va de même pour les composants annexes qui semblent légers à côté d’un scanner : une interface web qui transforme une bibliothèque Jellyfin pour lui donner l’apparence d’un vidéoclub des années 90 mobilise tout de même un serveur multimédia complet et ses transcodages sur le disque sous-jacent. Installez-la donc sur un autre hôte.

La mémoire se calcule simplement. ENGINE_MEMORY_RESERVE_GB=2 réserve de la mémoire pour le moteur, la base de données, l’API et les surcoûts temporaires. Chaque runner de scan dispose d’une réservation et d’une limite stricte de ENGINE_SCAN_RUNNER_MEMORY_MB=1536. Deux workers nécessitent donc environ 5 GB avant même le démarrage des autres services. Le moteur n’autorise que les runners qui tiennent dans le budget restant. Sur une petite machine, les scans sont donc mis en file d’attente au lieu d’échouer. C’est un bien meilleur comportement que le déclenchement de l’out-of-memory killer. Le même calcul définit le minimum pour tout outil qui attribue son propre conteneur à chaque unité de travail. C’est pourquoi le conteneur et le navigateur d’OpenBot pour chaque collègue IA atteint une limite de RAM bien avant une limite de CPU.

Deux paramètres de prune valent true par défaut : ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHE et ENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES. À la fin d’une tâche, le moteur supprime le cache de build inutilisé, les images inutilisées et les conteneurs de scan arrêtés. Les images utilisées par un conteneur en cours d’exécution, les bind mounts, les données de la base, les credentials et les volumes sont conservés. C’est une raison supplémentaire de ne pas partager l’hôte : un pruner que vous n’avez pas configuré s’exécute sur ce Docker daemon.

Paramètres du moteur que la plupart des utilisateurs finissent par modifier
  • ENGINE_WORKER_COUNT : nombre total de slots de workers partagés par les étapes de scan et de post-traitement. Définissez-le à 0 pour suspendre la prise en charge de nouvelles tâches.
  • ENGINE_MAX_CONCURRENT_SCANS : nombre de scans admis simultanément. Les scans en file d’attente attendent que le pool actif soit vide.
  • ENGINE_MAX_WORKERS_PER_SCAN : 0 répartit équitablement les slots cumulés entre les scans.
  • ENGINE_HARNESS_TIMEOUT_SECONDS : 7200 par défaut. Il s’agit de la durée maximale d’une tâche unique qui s’emballe.
  • ENGINE_MIN_FREE_STORAGE_GB : seuil minimal de stockage. ENGINE_IGNORE_LOW_STORAGE=true désactive cette protection, et le fichier avertit que le disque de l’hôte peut alors être rempli.
  • ENGINE_SCAN_RUNNER_MEMORY_MB : limite stricte de mémoire par runner. 0 supprime cette limite.

Analyser un dépôt local sans le divulguer

LOCAL_REPOS_PATH est défini par défaut sur ./local_repos et est monté en bind dans les conteneurs backend et engine à /local_repos. Un dépôt placé dans ce dossier sur l’hôte apparaît donc immédiatement dans les conteneurs. Utilisez un clone propre, pas votre arborescence de travail. Le conteneur du job dispose d’une copie accessible en écriture, de root à l’intérieur du conteneur et d’un accès sortant à Internet. Tout fichier présent dans cette copie peut donc être modifié ou envoyé hors de la machine. Supprimez les fichiers .env et les clés privées avant d’y copier un projet.

Résultats obtenus et limites

Vous obtenez des résultats candidats classés. Vous n’obtenez pas des vulnérabilités vérifiées. Le classement et la déduplication déterminent l’ordre de votre file de triage. Ils ne prouvent pas qu’une entrée est réelle. Les post-scripts peuvent tenter une validation et construire une preuve de concept. C’est le signal le plus fort fourni par l’outil. Cependant, l’échec d’un post-script ne prouve pas que le résultat est faux. Une personne doit toujours examiner chaque candidat. Cette différence entre un candidat et une preuve explique pourquoi demander à un agent des éléments que vous pouvez reproduire vous-même est utile ici : un résultat que vous pouvez reproduire à la demande vaut plus qu’un résultat classé que vous devez accepter sans vérification.

Ce guide ne prétend pas indiquer combien de bugs réels open-kritt détecte, car nous ne l’avons pas mesuré. Quiconque cite un taux de détection pour votre codebase ne l’a pas exécuté sur votre codebase. Analysez d’abord un dépôt que vous connaissez déjà bien : les résultats que vous pouvez évaluer vous-même constituent le moyen de calibration le moins coûteux.

L’autorisation est encore plus importante ici qu’avec la plupart des outils auto-hébergés. Les agents compilent et exécutent du code, et accèdent au réseau. Une étape de preuve de concept peut donc toucher des systèmes en production. Utilisez l’outil uniquement sur du code qui vous appartient ou que vous êtes autorisé à tester dans le cadre d’un contrat, et définissez par écrit le périmètre cible avant toute exécution. Si vous configurez ANTHROPIC_API_KEY et utilisez le moteur Claude Code, les pratiques de sandboxing décrites dans exécuter Claude Code en toute sécurité sur un VPS s’appliquent également à ces agents.

FAQ

Pourquoi open-kritt a-t-il besoin de son propre VPS ?

Parce que ses agents d’analyse s’exécutent en tant que root dans des conteneurs de tâches jetables, avec des copies inscriptibles de votre code et un accès direct à Internet. Le service moteur monte également le socket Docker de l’hôte afin de lancer un conteneur par tâche. Tout processus qui accède à ce socket peut démarrer un conteneur montant le système de fichiers de l’hôte. Il faut donc considérer toute la stack comme disposant des privilèges root sur son hôte. Sur un VPS dédié, ce compromis est acceptable et la reconstruction du serveur ne vous coûte rien. Sur votre poste de travail quotidien, vos clés SSH et vos profils de navigateur se retrouvent dans la même limite de confiance que le code analysé.

Puis-je exposer le port 5173 au lieu d’utiliser un tunnel SSH ?

Vous ne devriez pas le faire. Le backend est livré sans authentification applicative. Le port est donc la seule protection entre Internet, vos résultats d’analyse et votre crédit fournisseur. Le fichier Compose lie tous les services à 127.0.0.1 pour cette raison. Exécutez plutôt ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip, puis ouvrez http://localhost:5173 localement. Une règle ufw ne suffit pas, car un port Docker publié est traité avant l’application de la stratégie par défaut d’ufw.

Comment empêcher open-kritt de dépasser le montant prévu ?

Définissez une limite stricte dans la console de votre fournisseur de modèles avant la première analyse, car open-kritt ne possède pas de réglage de budget. Conservez les valeurs de concurrence fournies par défaut pour les premières exécutions, ENGINE_WORKER_COUNT=2 et ENGINE_MAX_CONCURRENT_SCANS=1. Gardez à l’esprit qu’un compte fournisseur autorise par défaut jusqu’à 15 appels concurrents au modèle root, tandis qu’une session Codex peut exécuter jusqu’à cinq agents enfants. ENGINE_WORKER_COUNT=0 suspend la prise en charge de nouvelles tâches. C’est le moyen d’arrêt local le plus rapide.

Quelle version dois-je extraire ?

Un tag, jamais main. git fetch --tags suivi de git tag --list affiche les versions disponibles. v1.3.0, publié le 4 August 2026, est le plus récent au moment de la rédaction. Épingler une version garantit qu’une reconstruction effectuée plusieurs mois plus tard produira la même stack. La mise à niveau devient ainsi une décision prise après lecture des notes de version, plutôt qu’un effet secondaire du clonage effectué un autre jour.

Une analyse ne démarre jamais. Que dois-je vérifier ?

Vérifiez d’abord l’espace disque disponible. Le moteur ne lance pas de conteneur d’analyse par tâche lorsque l’espace libre est inférieur à ENGINE_MIN_FREE_STORAGE_GB, dont la valeur par défaut est de 20 GB. Vérifiez ensuite que ENGINE_WORKER_COUNT n’est pas égal à 0, car cette valeur suspend la prise en charge de nouvelles tâches. Confirmez enfin qu’un identifiant de modèle est réellement configuré en exécutant ./kritt setup, car un GITHUB_TOKEN seul ne peut pas exécuter d’analyse. docker compose logs engine indique la raison pour laquelle la tâche a été ignorée.