MENATER Sécurité opérationnelle
EnglishEN FrançaisFR
Accueil GitHub

Thème

Documentation

Tout ce que fait MENATER, et pourquoi il le fait ainsi.

La page d'accueil est la version courte. Voici la longue : ce que fait chaque partie, ce qu'elle refuse de faire, et le raisonnement derrière les deux. Lisez dans l'ordre ou allez droit à ce qui vous intéresse — rien ici ne dépend de ce qui précède.

Ce qu'est MENATER

MENATER est une console de sécurité opérationnelle que vous installez sur votre propre machine. Elle prend les alertes que remontent vos outils de détection, détermine lesquelles comptent, et met devant une personne celles qui demandent une décision. C'est gratuit, open source, et il n'y a aucune société derrière.

Elle a deux moitiés qui partagent un même écran. Le côté alertes traite ce qui a déjà eu lieu — une alerte est un fait accompli. Le côté code traite ce qui est sur le point d'arriver : une faille dans votre code source, avant qu'elle ne parte en production. Elles partagent une interface et une connexion ; elles ne s'alimentent pas encore l'une l'autre.

L'idée de conception, en une phrase. Une IA qui lit une alerte de sécurité lit un texte écrit par un attaquant : l'IA a donc le droit de lire et de proposer, et une personne est la seule chose autorisée à agir.

Trois programmes tournent : une base de données, la console elle-même, et l'analyseur de code. Rien d'autre n'est nécessaire, et rien ne quitte votre machine hormis les requêtes que vous avez configurées — vers le fournisseur d'IA dont vous avez fourni la clé, et vers les services de réputation que vous avez choisi d'activer.

L'installer

Docker est la façon normale d'installer MENATER, pas une option parmi d'autres. Il vous faut Docker et rien de plus : pas de base de données à configurer, pas de schéma à appliquer à la main, pas de deuxième machine.

# renseignez les deux mots de passe demandés
cp .env.example .env

# base de données + console + analyseur de code
docker compose up -d --build

→ http://localhost:4400

Utile ensuite : docker compose logs -f console suit ce que fait la console, docker compose down arrête tout en gardant vos données, et docker compose down -v efface tout, base de données comprise.

La base de données et l'analyseur de code ne sont joignables que depuis l'intérieur de la pile. Un seul port est publié, et il sert à la fois l'interface et l'API — un second point d'entrée voudrait dire une serrure qui ne protège que la moitié de l'application.

Vous voulez le faire tourner sans Docker ? npm run dev dans dashboard/ démarre les trois processus avec rechargement à chaud. C'est un mode de développement : il suppose que vous avez déjà Node, une base de données en marche et le schéma appliqué.

Le rendre opérationnel

Elle démarre en trois minutes et ne trie rien. C'est délibéré : chacun des quatre points ci-dessous est une décision que la console refuse de prendre à votre place. Une liste de contrôle en haut de la page de réglages les suit tous les quatre jusqu'à ce qu'ils soient faits.

# Ce que vous devez faire Ce qui arrive si vous le sautez
1Définir un secret partagé pour le point d'entrée des alertesLa porte reste fermée. Un secret vide la ferme au lieu de l'ouvrir — « aucune authentification configurée » ne doit jamais se lire « aucune authentification requise ».
2Activer le point d'entréeToutes les alertes sont refusées.
3Lui donner une clé pour un modèle d'IAChaque alerte atterrit chez un humain avec une confiance de zéro, et dit pourquoi. Rien n'est perdu ; rien n'est trié.
4Pointer un outil de détection vers luiAucune alerte n'arrive.

Les clés des services de réputation et les notifications de messagerie sont facultatives. Un service auquel vous n'avez pas donné de clé s'affiche Pas interrogé — une question que personne n'a posée, ce qui n'est pas la même chose qu'une question restée sans réponse.

Le résultat du test de connectivité : un bandeau rouge indiquant « au moins un maillon est rompu, 9 vérifications au vert, 5 à surveiller, 1 en échec, 0 indéterminée — en 14 ms », puis les lignes par vérification pour la base de données, le schéma SQL, la clé du modèle de tri et quatre sources d'enrichissement.
Le test de connectivité. Neuf au vert, cinq à surveiller, une en échec, zéro indéterminée — quatre états, si bien que « en cours de vérification » n'est jamais annoncé comme « rompu ». Chaque ligne nomme la conséquence puis le remède.

L'onglet Santé teste à la demande chaque maillon de la chaîne et nomme, pour chacun, la conséquence puis le remède. Il rapporte quatre états et non deux, si bien que « vérification en cours » n'est jamais annoncé comme « rompu ».

Les cinq étapes

MENATER exécute son propre moteur. Il n'y a aucune plateforme de workflows à installer et aucun second produit qui devrait être joignable pour qu'une alerte soit triée — un workflow ne peut donc pas être à moitié déployé, renommé dans un éditeur, ou laissé non publié. La console lit son propre registre de ce qui s'est exécuté.

  1. 01 · Réception Vérifiée et dédoublonnée Champs obligatoires vérifiés, doublons écartés, et l'émetteur informé de ce qui s'est réellement passé : refusée, déjà vue, ou acceptée.
  2. 02 · Contexte Réputation et étiquetage Réputation de l'adresse, localisation, étiquetage des techniques connues. Un service sans clé est marqué pas interrogé, et l'IA en est informée.
  3. 03 · Avis L'IA décide Un verdict, une confiance, et son raisonnement. Sans clé, elle renvoie needs_human à confiance 0 — sûre en échouant, jamais ouverte en échouant.
  4. 04 · Décision Humain Approbation et routage La demande part vers la console et vers Slack ou Discord. Sous le seuil de notification, personne n'est sollicité — rien n'attend donc, et l'alerte remonte aussitôt.
  5. 05 · Registre Scellée dans le journal Une ligne à laquelle on ajoute et que l'on ne modifie jamais, scellée à la précédente sous un verrou.

Un sixième existe et ne s'exécute jamais dans la séquence. Le gestionnaire d'erreurs est déclaré sur les cinq autres et appelé seulement depuis leurs branches d'échec. Aucune panne n'est silencieuse : chaque branche journalise, notifie, ou les deux.

Trois conséquences à connaître

  • Une jonction attend Une étape à plusieurs entrées ne démarre pas dès que l'une d'elles a répondu. L'étape 02 assemblerait sinon un tiers de ses sources — sans erreur, sans trace, et avec un résultat plausible.
  • Réessayer, puis échouer en le nommant Chaque appel externe réessaie avec un délai croissant, en traitant toute attente suggérée par l'autre bout comme un plancher plutôt qu'en la raccourcissant. Quand il échoue quand même, il dit quel service et pourquoi : une source que personne n'a pu joindre n'est pas une source qui n'a rien dit.
  • La vue non réduite La file recoud les exécutions en dossiers, et deux formes de panne disparaissent dans cette couture. L'onglet Suivi les montre brutes : chaînes rompues, exécutions rattachées à aucune alerte, journal cherchable, et un rejeu qui refuse quand l'alerte d'origine est inconnue, plutôt que de rejouer une reconstitution.
L'onglet Suivi : 120 exécutions inspectées, 118 rattachées à une alerte, un avertissement disant que la fenêtre observée est pleine, et trois sous-onglets pour les chaînes de traitement, les exécutions orphelines et le journal.
La vue non réduite. Elle compte les exécutions que la file n'a pas pu vous montrer, et prévient quand la fenêtre observée est pleine — au-delà, la console ne sait pas — plutôt que de laisser une lecture bornée passer pour une lecture complète.

Comment les alertes entrent

Il y a deux façons de livrer une alerte, et elles échouent différemment. Votre outil peut la pousser vers MENATER à l'instant où elle survient, ou MENATER peut demander à votre outil les nouvelles alertes à intervalle régulier. Aucune n'est meilleure.

Pousser

Un seul saut réseau : l'alerte arrive instantanément — et vous êtes exactement aussi fiable que la politique de réessai de votre outil. Une alerte que personne n'a reçue est une alerte dont personne ne sait rien.

Interroger

En moyenne, la moitié d'un intervalle d'attente — et rien n'est perdu à cause d'un appel qui n'est jamais arrivé, parce que le signet est resté où il était.

Le réglage par défaut utilise les deux, parce que le coût ne tombe pas sur les mêmes alertes. Une alerte critique contenue quatre minutes trop tard n'a pas été contenue ; une alerte de faible priorité triée quatre minutes trop tard reste de faible priorité. Les deux niveaux urgents prennent donc le chemin instantané et les deux autres sont interrogés. Une alerte dont la priorité n'a pas pu être lue prend le chemin rapide — garer discrètement quelque chose qui pourrait être critique est précisément l'échec que ce produit existe pour empêcher.

L'onglet Ingestion : trois architectures de livraison côte à côte avec leurs coûts énoncés, l'hybride sélectionnée, et un tableau associant P1 à P4 au webhook ou à l'interrogation régulière avec le délai que chacune implique.
Choisir un mode de livraison. Chaque option dit ce qu'elle apporte et ce qu'elle coûte, et le tableau annonce la moitié d'un intervalle d'interrogation — le délai moyen ajouté, pas l'intervalle, parce que c'est ce chiffre-là qu'on met en balance avec une alerte critique.

Les règles que suit le transport

  • Rien n'est refusé pour avoir pris le mauvais chemin Une alerte de faible priorité envoyée au point d'entrée instantané est acceptée et triée ; la réponse dit quel chemin la politique attendait. Jeter une détection pour une préférence de routage la remplace par rien.
  • Le signet n'avance que sur des données livrées Pas sur des données lues, et jamais après une interrogation vide ou en échec — une source en panne ressemble exactement à une source où rien ne s'est passé. Chaque interrogation revient aussi un peu en arrière du signet, parce qu'un outil qui horodate une alerte à la détection et la range une seconde plus tard perdrait sinon cette seconde pour toujours.
  • Une interrogation qui n'a rien placé est une interrogation en échec Savoir si la requête réseau a fonctionné n'est pas la question posée. Elle rapporte combien d'alertes elle a lues, combien elle en a placées, et nomme la cause quand les deux diffèrent.
  • Les interrogations ne s'empilent pas Une seule en cours par source. Une source plus lente que l'intervalle est simplement interrogée moins souvent, ce qui est la conséquence honnête d'être lente ; l'alternative accumule les requêtes jusqu'à saturer la mémoire.
  • Une source qui nous refuse est mise en attente, et c'est annoncé L'attente double à chaque échec consécutif jusqu'à trente minutes, et elle est affichée à l'écran — une source sautée est autrement indiscernable d'un collecteur arrêté. Le bouton « interroger maintenant » ignore l'attente, parce qu'un contrôle de diagnostic qui répond pas encore, attendez huit minutes est un contrôle sur lequel personne n'appuie deux fois.

Ce que doit contenir une alerte

Deux niveaux, et la différence entre eux est celle qui sépare on ne peut rien en faire de cette détection n'avait tout simplement pas d'adresse de destination.

Niveau Champs Règle
Identité alert_id · rule_name · severity · timestamp · raw_log Obligatoire. Un champ manquant vaut refus — et le refus nomme les champs.
Observables source_ip · dest_ip · user · host · process · file_path · url Facultatif. Absent reste absent : null, jamais une chaîne vide, jamais inventé. La plupart des détections réelles n'ont pas d'adresse de destination.
Tout le reste ce que votre outil envoie Conservé intégralement, sur le dossier et dans la ligne d'audit. Rien de ce qu'envoie votre outil n'est jeté.

La conséquence à retenir. Isoler une machine refuse de s'exécuter quand il n'y a aucune machine à nommer. Une action dont la cible est inconnue n'est pas une action.

Les alertes arrivent sur POST /api/ingest/<source>, et c'est la route qui décide comment le contenu est lu — jamais le contenu lui-même, si bien qu'un émetteur ne peut pas se faire passer pour un autre. L'intégration Wazuh ne convertit rien : elle transmet l'alerte telle quelle et la console traduit.

Les dix onglets

Regroupés plutôt qu'amputés. Dix boutons identiques coûtent une décision chaque fois qu'on les regarde ; le remède, ce sont des catégories, pas un second menu à l'intérieur du premier.

Onglet Ce qu'on y trouve
AlertsLa file et la fiche d'incident. Cinq colonnes portent huit informations : la gravité est à l'intérieur de ce que c'est, et la confiance à l'intérieur du verdict, parce que 0,58 ne veut rien dire sans le verdict qu'il qualifie. Chaque valeur d'une alerte porte un raccourci vers Recherche avec la question déjà posée.
CodeLancer une analyse de code et lire le rapport. L'onglet est chargé à la première ouverture puis gardé en mémoire — changer d'onglet pendant une analyse ne la coupe pas.
IngestionComment les alertes entrent : la politique de livraison, les sources sur chaque chemin, et le pipeline tel qu'il s'exécute, avec ses variables modifiables.
RulesDéclarez ce qui est normal chez vous — le scanner autorisé, la fenêtre de sauvegarde — avec un essai à blanc qui répond quelle règle correspondrait à cette alerte sans toucher au pipeline. Huit modèles sont livrés désactivés et sans propriétaire.
TrackingLa vue non réduite : chaînes rompues, exécutions rattachées à aucune alerte, journal cherchable, rejeu. Les orphelines attendues — la sonde de diagnostic envoie exprès une alerte invalide — sont listées et jamais comptées, sinon l'onglet clignoterait après chaque test de connectivité, et une alarme permanente cesse d'être lue.
MetricsDeux taux, jamais additionnés. Voir Le mode observation.
HealthUn bouton qui teste chaque maillon de la chaîne, et neuf alertes de test à y faire passer — une par chemin de code plutôt qu'une par scénario : sans destination, avec une empreinte, malformée, en double.
LookupPoser une question sur une valeur — une adresse, un domaine, une adresse web, une empreinte de fichier, un e-mail — plus une vérification de mot de passe compromis dont l'empreinte ne quitte jamais votre navigateur. Les formats obfusqués (1.2.3[.]4, hxxp://) sont acceptés, et les deux formes sont affichées.
GuideLa documentation intégrée à la console, cherchable — et la recherche lit aussi le glossaire, si bien qu'un mot cherché dans le mauvais vocabulaire trouve quand même sa section.
SettingsClés, sources de journaux, la table qui relie machines et code, les moteurs d'analyse, l'assistant — et la liste de ce qui manque encore.
L'onglet Recherche après interrogation de 8.8.8.8 : un verdict « rien contre elle », la ligne « 1 source sur 4 a répondu », et deux fiches de source marquées « pas interrogée ».
Un verdict qui énonce sa propre portée. Une source a répondu, et le panneau le dit à côté du verdict ; les deux sources sans clé sont pas interrogées — une question que personne n'a posée, pas un trou dans ce qu'on sait.

Deux règles auxquelles l'onglet Recherche se tient

  • « Rien à signaler » exige une source qui a répondu Sans aucune clé configurée, tous les services sont sautés, et afficher rien trouvé à propos d'une valeur que personne n'a regardée, c'est bâtir une réassurance sur un trou. Le nombre de services qui ont réellement répondu est à côté du verdict, jamais plus bas.
  • Toute non-réponse n'est pas un échec Plusieurs services disent cette adresse n'apparaît dans aucune fuite avec un code HTTP 404, ce qui est la meilleure nouvelle que ce service ait à donner. Une règle générale « tout ce qui n'est pas 200 est cassé » masquerait derrière le mot indisponible le résultat le plus fréquent et le plus rassurant : chaque service déclare donc ses propres codes de réponse.

L'assistant intégré

Un panneau de discussion ancré sur le côté de l'écran où vous êtes. Il répond aux questions sur cette installation — explique-moi l'alerte 1234 simplement, pourquoi attend-elle encore ?, que reste-t-il à configurer ? — et il reçoit la page où vous vous trouvez, si bien que « cette alerte » ne demande rien à taper.

Tout son modèle de sécurité tient dans le fait qu'il ne peut pas agir. Sa liste d'outils est fermée à sept consultations en lecture seule : la file, une alerte, une chaîne, les règles, les mesures, la santé, et l'état de configuration. Il n'y a rien qui approuve, isole, clôt, rejoue, modifie une règle ou écrit un réglage.

Ce n'est pas de la prudence pour la forme. Qui pose une question sur une alerte pose une question sur un journal qu'un attaquant a composé, et un accès sans restriction d'un modèle au contenu des journaux se mesure à 87 % de réussite d'injection de consignes. Trois couches y répondent, dans l'ordre où elles tiennent réellement :

  • Aucune écriture dans la liste Une consigne cachée dans un journal arrive à un modèle qui ne détient que sept lectures. C'est celle-là qui compte.
  • Le texte non fiable est encadré, pas supprimé Le contenu des journaux voyage entre des marqueurs portant un nombre généré pour cette requête-là, de sorte qu'un journal ne peut pas fabriquer une balise de fermeture pour quelque chose qui n'existait pas au moment où il a été écrit. Rien n'est retiré : réécrire une preuve est la même erreur que combler un blanc par une supposition.
  • Les consignes disent ce qu'un encadrement signifie Indicatif, et en troisième position pour une raison : une consigne n'est pas une frontière.

Quatre fournisseurs d'IA sont pris en charge, une clé chacun, choisis dans les réglages. Rien n'est conservé : la conversation voyage avec chaque question et n'est stockée nulle part. Garder les fils créerait une quatrième copie du contenu des alertes, hors du registre d'audit, sans politique de conservation. Chaque réponse montre ce qu'elle a consulté — une réponse que vous ne pouvez pas vérifier est une réponse crue pour de mauvaises raisons.

Brancher votre propre IA

Ces mêmes consultations en lecture seule peuvent être exposées à un assistant IA que vous faites tourner vous-même — Claude Desktop, Claude Code, Cursor, VS Code — via le protocole MCP. C'est désactivé par défaut, et éteint ou sans jeton, l'adresse répond comme si elle n'existait pas.

Les réglages contiennent une page d'installation en quatre étapes : l'activer, générer un jeton, copier le bloc pour votre client, appuyer sur le bouton de test. L'adresse dans ce bloc vient de l'adresse par laquelle vous avez atteint la console, pas d'un document — installez-la sur la machine d'un collègue et le bloc nomme leur machine. Le jeton est affiché une seule fois, et le test s'exécute sur le serveur, parce que le navigateur est délibérément refusé par la même protection qui empêche une page web hostile d'atteindre un service tournant chez vous.

Ce qui est exposé : 14 outils, 8 questions toutes prêtes, 9 ressources, tous en lecture seule. Les questions toutes prêtes comptent plus qu'il n'y paraît — un client qui voit dix noms d'outils voit dix lectures et aucune raison de s'en servir, alors que explique cette alerte, à quel point est-ce dangereux, pourquoi ça attend et rédige-moi une passation d'équipe sont les questions que cette console existe pour répondre, proposées plutôt que devinées.

Le jeton constitue tout le contrôle d'accès. Quiconque peut joindre la console et le détient peut lire la file, les alertes et les règles. Traitez-le comme le mot de passe de la console. Il ne peut rien modifier : il n'y a aucune écriture dans la liste.

Thèmes et lisibilité

Six jeux de couleurs, changeables depuis l'en-tête de cette page aussi. Chacun redéfinit la palette entière : hériter trois couleurs d'un autre thème produit un accident que la relecture ne rattrape pas, comme un gris foncé resté sur un fond crème.

Le contraste est mesuré, pas jugé à l'œil. Un test calcule les rapports de contraste standard et refuse une palette qui passe en dessous — 4,5:1 pour le texte sur chaque surface, pour le texte posé sur la couleur d'accent, et pour les couleurs de risque à l'intérieur de leurs propres pastilles. Il a rattrapé un rouge d'échec à 2,5:1, sur l'écran qui dépend le plus du rouge, et un gris resté depuis toujours à 2,77:1 dans le thème d'origine.

  • Un accent, un rôle La couleur d'accent signifie exactement une chose — une personne est bloquée ici — plus le bouton principal. Le rouge dit critique ou en échec, l'orange mérite un coup d'œil, le vert traité. Un bouton rouge apprendrait à un analyste à ignorer le rouge sur le seul écran où le rouge fait gagner du temps.
  • La couleur ne porte jamais le sens seule Chaque couleur de risque est doublée d'un mot, si bien que la console fonctionne encore pour quelqu'un qui ne les distingue pas.
  • La densité est une fonctionnalité Le tableau d'alertes est fait pour afficher quarante lignes. Une police à chasse fixe veut dire cette chaîne vient de la machine et elle est exacte ; la prose autour d'une valeur n'y est pas, la valeur si. Un analyste qui fait défiler est un analyste qui a perdu la vue d'ensemble.
  • Ce qui explique se replie, ce qui rapporte non Une définition ou une note de méthode passe derrière un repli qui dit ce qu'il contient. Un état, un décompte, une panne ou une action en attente d'approbation reste à l'écran. Ranger une panne derrière un repli silencieux reproduit exactement le défaut que l'onglet Suivi existe pour exposer.

L'interface fonctionne sur téléphone : la barre d'onglets défile latéralement et le dit, le tableau d'alertes se replie en fiches, les zones tactiles font 44 px, et les champs de formulaire font 16 px pour qu'iOS ne zoome pas quand on les touche.

Les quatre listes fermées

Quatre listes, dans ce produit, sont fermées — on ne peut rien y ajouter, pas même derrière une approbation. Chacune l'est pour la même raison : un opérateur pointe cette console sur du texte écrit par un attaquant toute la journée, et une liste ouverte est à une consigne près d'être celle de quelqu'un d'autre.

Liste Taille Ce que la fermeture empêche
Actions 4 Isoler temporairement une machine (avec une expiration et une annulation automatique), ouvrir un ticket, escalader, clore en faux positif. Aucune règle de réglage ne peut passer outre cette liste non plus.
Outils de l'assistant 7 en lecture Le panneau de discussion peut lire la file, une alerte, une chaîne, les règles, les mesures, la santé et l'état de configuration, et n'écrire rien. Une consigne injectée arrive à un modèle qui n'a rien pour y obéir.
Noms de secrets liste nommée Les deux coffres à clés n'acceptent que des noms figurant sur une liste fixe. Un nom arbitraire transformerait la page de réglages en moyen d'injecter n'importe quelle variable d'environnement dans le processus, PATH compris.
Services de réputation 7 Le point d'entrée de recherche prend une valeur et un type — jamais une adresse web. Une route qui irait chercher ce qu'on lui tend serait une faille de falsification de requête avec un bouton dessus.
Une fiche d'incident pour une alerte critique de rançongiciel : verdict de repli à confiance 0, quatre étapes de pipeline avec leurs durées, et un bloc d'approbation proposant une escalade.
Une fiche d'incident. Le verdict nomme sa propre cause, la destination est — parce que la détection n'en a consigné aucune, et l'action proposée est derrière Approbation requise. Rien n'a été exécuté.

Une cinquième limite pèse sur les règles de réglage. Une équipe peut déclarer ce qui est normal chez elle — le scanner autorisé, la fenêtre de sauvegarde — et la console refuse une autorisation permanente fondée sur un seul champ d'identité, une mise en sourdine sans expiration, et toute règle sans propriétaire ou sans raison énoncée.

Le mode observation

Une installation neuve n'exécute rien. Elle consigne la décision qu'elle aurait prise et poursuit. Sortir de ce mode n'est pas un interrupteur à basculer le premier jour : cela attend un chiffre mesuré sur de vraies alertes passées par les vrais garde-fous.

Deux taux sont mesurés, et ils ne sont jamais additionnés, parce qu'ils répondent à des questions différentes :

À quelle fréquence l'IA a dit « faux positif »

Une mesure de répartition, pas de justesse. Un modèle qui qualifierait tout de faux positif obtiendrait ici un score magnifique.

À quelle fréquence une personne a dit non

La part des décisions soumises à un humain qu'il a rejetées. C'est celui-ci qui ouvre la porte — c'est le seul substitut à la justesse disponible sans vérité de terrain.

Deux choses à ne pas comparer. Deux appels au même modèle sur la même alerte renvoient 0,88 et 0,91 — les comparer mesure le bruit du modèle, pas quoi que ce soit de votre installation. Et comparer un dossier que le pipeline n'a pas produit — une alerte de test injectée à mi-parcours, un verdict de repli écrit faute de clé — produit des désaccords qui n'en sont pas, et bloque la porte pour rien.

Le comportement par défaut est sûr en échouant. Une configuration absente ne peut pas autoriser une exécution, et seul le mot exact false désactive le mode observation. Une approbation qui expire n'exécute rien — le silence ne vaut jamais accord.

Le registre d'audit

Chaque décision écrit une ligne dans une table à laquelle on ajoute et que l'on ne modifie jamais. Chaque ligne est scellée à la précédente : retirer ou altérer une ligne, où que ce soit dans la chaîne, se voit à la vérification suivante. C'est la seule preuve d'intégrité du produit.

Un vérificateur qui crie au loup est un vérificateur qu'un auditeur cesse de croire — ce qui masquerait une vraie suppression dans le bruit. Une fausse alerte coûte donc ici plus cher que pas d'alerte du tout.

Ce n'est pas théorique. Une passe de charge a trouvé le vérificateur signalant des maillons rompus sur 22 lignes parfaitement saines sur 3 195. La cause : le numéro de ligne était attribué avant le verrou qui ordonne le scellement, si bien que sous charge deux transactions pouvaient sceller dans un ordre en portant des numéros dans l'autre. La chaîne était une liste intacte qui n'était simplement plus dans l'ordre des numéros, et le vérificateur la parcourt par numéro. Corrigé en déplaçant le numéro à l'intérieur du verrou ; revérifié sur ~500 lignes écrites 40 à la fois, sans une seule rupture.

Les lignes scellées avant ce correctif gardent leurs maillons rompus. La table est en ajout seul et immuable par conception, ce qui est le bon compromis : elles ne peuvent pas être réécrites, et le vérificateur continue de les nommer honnêtement.

Les chiffres mesurés

Exécuté contre un simple docker compose up — base de données, console, analyseur de code, rien d'autre. C'est une passe de qualité sur une machine, pas un banc d'essai publié ; ce qui compte est que ce soit reproductible et que les conditions soient dites.

400 / 400 alertes acceptées en charge 50 en parallèle · ~134 par seconde · 95 % répondues en moins de 424 ms · chaque chaîne réglée, rien laissé en cours
1 of 12 doublons acceptés 12 copies simultanées d'une même alerte → 1 acceptée, 11 déjà vues, zéro erreur
0 maillons rompus dans la chaîne d'audit revérifié sur 2 644 lignes écrites sous charge concurrente
1,278 tests au vert 913 console · 365 analyseur de code · vérification de types propre

Cette passe a trouvé huit défauts et ils ont été corrigés. Trois méritent d'être nommés, parce que chacun est une panne qui ressemblait à un succès :

  • Des alertes refusées rapportées comme acceptées Le point d'entrée renvoyait « accepté » pour toute alerte qu'il parvenait à démarrer, y compris celles que le pipeline avait rejetées pour champs manquants — l'émetteur n'avait donc aucune raison de corriger quoi que ce soit, et la raison, déjà calculée, ne quittait jamais le serveur.
  • La détection de doublons n'était pas sûre en rafale « Insérer sauf si une ligne existe » se lit comme une étape atomique et n'en est pas une : deux transactions voyaient toutes deux la ligne absente, inséraient toutes deux, et l'une mourait. Douze copies simultanées d'une alerte produisaient une erreur serveur — et une erreur serveur dit à l'émetteur de réessayer une alerte déjà acceptée.
  • Le vérificateur d'audit criait au loup Voir Le registre d'audit.

Ce qu'il ne fait pas

Dit ici pour la même raison que la console le dit : une page qui n'énumère que ce qui marche est un vert qui n'a pas été gagné.

  • Les deux moitiés ne se parlent pas Une analyse de code ne crée aucune alerte dans la file, et une alerte ne lance aucune analyse. Ce qui les relie, c'est une table que vous remplissez pour associer des noms de machines au code qui y tourne, afin qu'une fiche d'incident puisse nommer le projet et le transmettre à l'analyseur en un clic — elle remplit un formulaire, elle ne lance jamais rien. La correspondance est exacte, et une entrée ambiguë est refusée à l'enregistrement plutôt que devinée.
  • La connexion n'identifie personne L'accès est un simple mot de passe. Il protège la console ; il ne distingue pas un approbateur d'un autre, et la ligne d'audit le dit exactement, plutôt que de sous-entendre un nom qu'elle n'a pas.
  • L'autonomie attend une mesure Sortir du mode observation dépend d'un taux de désaccord mesuré sur de vraies alertes, pas d'une date. Voir Le mode observation.
  • C'est un projet, pas un produit Auto-hébergé, open source, sans contrat de support et sans société derrière. Lisez le code avant de le pointer sur quoi que ce soit d'important — ce qui est de toute façon la bonne chose à faire avec n'importe quel outil de cette catégorie.

Les mots employés ici

La page d'accueil les évite exprès. Ils apparaissent sur cette page et dans la console : ils sont donc définis une fois, ici.

Alerte
Un avertissement unique remonté par un outil de détection : ce fichier a été bloqué, ce compte a échoué douze fois à se connecter. C'est un fait déjà survenu, pas une prédiction.
Tri (triage)
Décider, vite, quelles alertes méritent le temps d'une personne. Emprunté à l'hôpital, et le sens est le même ici.
Faux positif
Une alerte qui s'avère n'être rien. La plupart le sont. Se tromper coûte cher dans les deux sens, d'où la prudence de la console avec ce mot.
SIEM
L'outil qui collecte les journaux de tout ce que vous faites tourner et en tire des alertes. C'est lui qui alimente MENATER. Wazuh est celui contre lequel ce projet est testé.
Enrichissement
Ajouter du contexte à une alerte avant que quiconque ne la juge — cette adresse est-elle connue pour des attaques, où se trouve-t-elle, à quelle technique connue cela correspond-il.
Mode observation
Le comportement par défaut. La console note ce qu'elle aurait fait et ne fait rien. Appelé shadow mode dans le code source.
Observable
Une valeur concrète dans une alerte, sur laquelle on peut aller se renseigner : une adresse, un nom de machine, une empreinte de fichier, un utilisateur.
Webhook
Une adresse web que vous donnez à un autre outil pour qu'il vous pousse des données à l'instant où quelque chose se produit, au lieu que vous ayez à demander.
Interrogation régulière (polling)
L'inverse : demander à un autre outil s'il y a du nouveau, à intervalle régulier.
Injection de consignes
Cacher des instructions dans un texte qu'une IA va lire, pour qu'elle les suive à la place des vôtres. Un journal dans lequel un attaquant peut écrire en est le cas d'école, et c'est la raison pour laquelle l'IA de cette console a le droit de lire et pas d'agir.