Assets OCSF
Chaque jour, chaque communauté qui tourne envoie à son espace Sekoia un inventaire de sa population, au format OCSF que reçoivent les connecteurs d'assets de Sekoia : les équipements — postes des utilisateurs et serveurs —, les utilisateurs, les vulnérabilités, les logiciels installés, et les rapports propres à l'agent Sekoia : sa conformité et l'inventaire de ses logiciels.
Cet inventaire n'est pas une seconde population tirée à côté de la première. C'est la projection de celle dont la communauté envoie déjà les journaux : le nom d'hôte, l'adresse, l'OS, l'identifiant d'agent, le fabricant et le modèle d'un équipement sont ceux de l'entité que les journaux nomment. Un analyste qui passe d'une alerte à l'asset retrouve la machine dont parlent les journaux — pas un homonyme.
Rien n'est tiré
Ce que la population ne porte pas — pare-feu activé, chiffrement du disque, MFA, date d'enrôlement, heure de démarrage, dernière connexion — est dérivé de l'entité, jamais tiré. Deux exécutions rendent donc les mêmes valeurs. Un inventaire dont le pare-feu changerait d'état chaque matin décrirait un parc que personne n'administre, et rien n'y serait comparable d'un jour à l'autre.
Il en va de même pour la suite : les CVE qu'un équipement porte et les logiciels qu'il déclare sont dérivés, eux aussi.
Les connecteurs
Le catalogue est fixé en code : ce qu'un format produit, c'est le connecteur Sekoia qui le reçoit qui le décide, pas l'opérateur. Seule son instance se règle — quel format, quel connecteur de l'espace, actif ou non.
| Format | Catégorie | Produit |
|---|---|---|
HarfangLab EDR | Postes et serveurs | HarfangLab EDR |
HarfangLab EDR Software | Logiciels | HarfangLab EDR |
Crowdstrike Falcon Devices | Postes et serveurs | CrowdStrike Falcon |
SentinelOne Devices | Postes et serveurs | SentinelOne |
Tenable vulnerability management | Vulnérabilités | Tenable |
Microsoft Entra ID | Utilisateurs | Microsoft Entra ID |
HarfangLab EDR Software est le connecteur logiciel HarfangLab de Sekoia : il envoie un item par
équipement et par application.
L'identifiant d'un équipement prend la forme des journaux de cet EDR, pour que l'asset s'en rapproche : l'identifiant d'agent brut pour HarfangLab et l'agent Sekoia, 32 caractères hexadécimaux pour CrowdStrike et SentinelOne. Un identifiant d'une autre forme décrirait la bonne machine sans jamais rencontrer ses journaux.
La conformité de l'agent Sekoia
Le rapport de conformité de l'agent Sekoia (Sekoia Agent compliance) n'est pas un connecteur qu'on
ajoute : comme dans le projet d'origine, il part d'office pour toute communauté dont la
technologie Sekoia Agent est activée avec sa clé d'intake. Une requête par équipement, vers
api/v1/xdr-agent/compliance — le point d'entrée propre à l'agent, pas l'API de gestion des
assets —, authentifiée par cette clé d'intake, deux requêtes étant séparées du
délai de l'agent.
Son firewall_enabled est la même valeur que l'enrichissement de conformité de l'équipement : les
deux rapports ne peuvent pas se démentir sur la même machine.
L'inventaire logiciel de l'agent Sekoia
À côté de sa conformité, l'agent Sekoia envoie ses logiciels installés (Sekoia Agent software),
aux mêmes conditions : d'office, pour toute communauté dont la technologie Sekoia Agent est activée
avec sa clé d'intake, sans connecteur à ajouter. Une requête par équipement, vers
api/v1/xdr-agent/software, authentifiée par cette clé d'intake et nommant l'agent dans
Sekoia-Agent-ID :
{
"hostname": "PC-JDOE-01",
"software": [
{
"uid": "6f1c…",
"name": "Google Chrome",
"version": "149.0.7827.53",
"vendor_name": "Google LLC",
"path": "C:\\Program Files\\Google\\Chrome\\Application",
"install_time": 1780466112.214,
"architecture": "x64",
"purl": "pkg:windows/google-chrome@149.0.7827.53",
"binary_name": "chrome.exe"
}
]
}
- Les applications sont celles de
HarfangLab EDR Softwarepour le même équipement, champ pour champ — l'uiddu paquet, le nom, la version, l'éditeur, le répertoire, l'exécutable et l'architecture. Deux sources qui décrivent un même poste ne peuvent pas se démentir sur ce qu'il porte. - Sans le système d'exploitation : un inventaire de paquets ne liste pas le système. Un
équipement qui ne déclare que son OS — un poste Linux, un serveur dont le rôle n'installe rien —
poste quand même, avec
"software": []. install_timeest dérivé, jamais tiré : après l'enrôlement de l'équipement et après la sortie de la version qu'il porte, dans les deux semaines, en secondes epoch. Deux exécutions rendent la même date.purlse compose du nom et de la version de l'application (pkg:windows/<nom>@<version>, sans version quand elle est inconnue).- Au plus 500 paquets par requête : un équipement qui en porte davantage en envoie plusieurs, toutes à son nom.
- Deux requêtes sont séparées du délai de l'agent, le même que pour la conformité.
Son exécution se relève et s'audite comme les autres, une requête par équipement.
Régler : l'onglet Assets
Tout se passe dans l'onglet Assets d'une communauté (/communautes/<id>) —
sauf l'accès à l'API, réglé dans son onglet Réglages : une ligne qui dit cet accès, trois cartes
et un aperçu.
API Sekoia
L'accès vit dans la carte API Sekoia de l'onglet Réglages. L'onglet Assets le dit en une ligne — le masque de la clé, ou son absence, et la base d'API que viseront les exécutions —, avec un lien vers cette carte.
Le champ Clé d’API Sekoia porte une clé propre à la communauté — chacune envoie vers son propre
espace —, qui part en Authorization: Bearer. C'est la seule clé Sekoia de la communauté : la
même crée ses intakes et ses
connecteurs d'assets, si bien qu'il lui faut les droits des
assets et ceux de configuration des intakes et des connecteurs. Ce n'est pas la clé de
Configuration → Configuration générale, qui n'alimente que le
catalogue d'indicateurs.
Son contrat est celui des clés d'intake : enregistrée, elle n'est plus jamais réaffichée, seul son
masque revient (••••1a2b) ; laisser le champ vide la conserve, cocher la case d'effacement
l'efface, saisir une valeur la remplace. Elle n'est pas chiffrée en base, et l'écran le dit — la
clé de déchiffrement vivrait sur le même hôte que PostgreSQL. Et elle est lue à l'instant de
poster, jamais avant : une exécution peut attendre dans la file, et la clé dormirait dans Redis
tout ce temps.
La base de l'API suit la destination de la communauté. Pour une région Sekoia, elle se déduit, et il n'y a rien à saisir :
| Région | Base de l'API |
|---|---|
| FRA1 | https://app.sekoia.io/ |
| FRA2 | https://fra2.app.sekoia.io/ |
| MCO1 | https://mco1.app.sekoia.io/ |
| SGP1 | https://app.sgp1.sekoia.io/ |
| UAE1 | https://app.uae1.sekoia.io/ |
| USA1 | https://app.usa1.sekoia.io/ |
| TEST | https://app.test.sekoia.io/ |
Une intake reçoit des journaux, l'API reçoit des assets, et les deux n'ont ni le même hôte ni le même chemin : l'adresse d'un webhook personnalisé ne dit rien de l'endroit où vit l'API. Pour une destination personnalisée, et pour elle seule, le champ Base de l’API Sekoia (destination personnalisée) est donc proposé. Laissé vide, chaque exécution est écartée, et dit pourquoi.
Connecteurs d’assets
Dans la carte Connecteurs d’assets, choisir un format et renseigner son UUID du connecteur
Sekoia — le dernier segment de l'adresse du connecteur chez Sekoia,
api/v2/asset-management/asset-connector/{uuid} —, cocher Actif, puis Enregistrer les
connecteurs. Un format ne figure qu'une fois par communauté.
Chaque ligne porte aussi un Espacement (ms) : l'attente entre deux requêtes d'une exécution, de 0 — d'affilée — à 60 000 millisecondes. Un connecteur neuf naît à 1 000, et un HarfangLab EDR Software neuf à 10 000 : le logiciel est le seul inventaire à envoyer des dizaines de requêtes, une par groupe d'hôtes, là où les autres connecteurs envoient des lots de 1 000 items. Un champ vidé garde la valeur enregistrée, et un connecteur enregistré avant ces défauts garde les siennes. L'espacement se lit au départ de l'exécution : un changement vaut dès la suivante, et l'audit d'une exécution affiche celui qu'elle a joué.
La ligne du logiciel ajoute Hôtes / requête : combien d'hôtes l'inventaire logiciel regroupe dans une même requête, 10 pour un connecteur neuf, de 1 à 1 000. Une requête ne porte toujours pas plus de 1 000 items, et un hôte n'est jamais coupé pour la remplir : elle part plus tôt, avec moins d'hôtes. 120 devices par dix font douze requêtes au lieu de 120, si bien que l'espacement compte douze fois et non 120 — mais un lot que Sekoia refuse pour son contenu l'est pour tous les hôtes qu'il porte, là où un hôte par requête désigne le seul fautif. Le champ suit le contrat de l'espacement — vidé, il garde la valeur enregistrée ; lu au départ de l'exécution —, et l'audit affiche le regroupement qu'une exécution a joué. Les autres connecteurs partent en lots fixes de 1 000 et n'ont pas ce champ.
Enregistrer les connecteurs ne replanifie pas la journée simulée. L'inventaire ne change rien à ce que contiennent les journaux du jour : l'enregistrement laisse donc intacte la date de modification de la communauté — le canal par lequel la configuration prévient l'ordonnanceur que son plan du jour est périmé.
Créer un connecteur dans Sekoia
Plutôt que de créer chaque connecteur à la main dans Sekoia puis d'en recopier l'UUID, SekoiaCraft peut le créer. Un format sans connecteur offre un bouton Créer dans Sekoia à côté de son champ d'UUID dès que sa case est cochée — inutile d'enregistrer d'abord. Il se sert de la clé d'API Sekoia de la communauté — celle avec laquelle partent les inventaires et se créent les intakes —, si bien que cette clé doit aussi avoir le droit de configurer les connecteurs dans l'espace de la communauté : le refus de Sekoia le dit sinon. Un clic :
- lit le compte de la clé (
GET /v1/me) pour connaître sa communauté Sekoia ; - crée une configuration de module (
POST /v1/symphony/module-configurations), dont les identifiants sont factices et recopiés tels quels ; - crée le connecteur (
POST /v1/symphony/connector-configurations, typeasset) qui la référence, et pose l'UUID que rend Sekoia — la ligne est enregistrée aussitôt, active, aux réglages par défaut de son format (10 000 ms et 10 hôtes par requête pour l'inventaire logiciel) ; - arrête sa collecte cinq secondes plus tard
(
POST /v1/symphony/connector-configurations/<uuid>/stop) : SekoiaCraft envoie lui-même les inventaires. Comme pour les intakes, un connecteur qui démarre encore est attendu, quinze secondes au plus, et un arrêt manqué ne fait pas échouer la création — un avertissement dit de l'arrêter dans Sekoia.
Tous deux sont nommés d'après le format et la communauté — HarfangLab EDR Software Asset Connector Team3 —, si bien qu'on ne les confond jamais avec l'intake du même format. Quelques règles :
- Pas de bouton tant qu'un UUID est enregistré. Pour en recréer un, décocher la ligne, enregistrer, puis la recocher.
- Rien n'est retenté. Si le connecteur est refusé, la configuration de module reste dans Sekoia : le motif la nomme, avec son UUID, pour l'y supprimer. Le clic suivant en crée une autre.
- Le refus se lit dans la carte, avec l'étape que Sekoia a refusée et sa réponse, la clé caviardée.
- Entrée dans un champ enregistre les connecteurs, n'en crée jamais : les boutons appartiennent à un autre formulaire.
- Un geste de configuration à la fois par communauté : une création attend une intake en cours de création sur la même communauté, dont l'arrêt du connecteur peut la retenir de cinq à quinze secondes.
- Créer un connecteur ne recalcule pas la journée simulée, comme enregistrer les connecteurs.
Les UUID des six connecteurs et modules viennent de requêtes relevées dans Sekoia. Deux UUID de
connecteur — SentinelOne Devices (f47ac10b-…, l'UUID d'exemple de la RFC 4122) et Microsoft Entra
ID (b6e2e2e2-…) — restent à confirmer sur un appel réel.
Sur un pool, la grille de livraison offre le même bouton pour chaque équipe, et crée d'un geste les connecteurs cochés d'une équipe, ou de toutes — voir Créer tous les connecteurs d'assets d'un geste.
Agent Sekoia
La carte Agent Sekoia dit si les deux envois de l'agent — sa conformité et son inventaire logiciel — partiront, selon la règle même de l'ordonnanceur : la technologie Sekoia Agent activée avec sa clé d'intake. Ils n'ont pas de ligne de connecteur, et leur seul réglage vit donc ici : le Délai entre deux requêtes (ms), commun aux deux envois.
- 2 000 ms par défaut, pour toutes les communautés — y compris celles créées avant le réglage : ces envois partaient d'affilée. 0 envoie d'affilée ; 60 000 est le maximum.
- Une requête par équipement, puis le délai avant la suivante : cent vingt équipements prennent environ quatre minutes par envoi. Le délai se lit au départ de l'exécution, et l'audit montre celui qu'elle a joué.
- Dans un pool, chaque équipe règle le sien : le délai dit comment une équipe livre, pas ce qu'elle reçoit.
- Enregistrer écrit la communauté, et seulement si la valeur a changé : contrairement aux connecteurs, cela touche sa date de modification, si bien que l'ordonnanceur reconstruit son plan du jour — identique, un plan étant déterministe.
Dernières exécutions
La carte Dernières exécutions liste les 20 dernières exécutions. Une exécution est un
relevé, quel que soit son nombre de lots, et à part de l'historique des envois de journaux de
/envois.
Chaque ligne porte un lien Auditer, qui ouvre ce que l'exécution a construit et posté — tous ses items, conservés 24 heures ; Toutes les exécutions de cette communauté, dans Débug → Inventaires les liste toutes.
Le tableau se met à jour seul, pendant l'envoi. Une exécution apparaît En file dès sa mise
en file, passe à Envoi en cours quand sa première requête part, puis à son issue quand elle se
termine — sans recharger la page. Pendant l'envoi, la ligne la suit requête après requête : Items
envoyés monte, Requêtes se lit émises sur prévues (37 / 120) au-dessus d'une barre de
progression, les lots déjà refusés se comptent en rouge, et la dernière colonne donne l'heure de son
début. Un inventaire logiciel de cent vingt hôtes, dix par requête toutes les dix secondes, n'est
plus deux minutes d'une ligne figée. Sans JavaScript, la page reste complète, mais seul un rechargement montre le
changement.
| Statut | Ce qu'il dit |
|---|---|
| En file | L'exécution attend une place — trois partent de front, communautés confondues |
| Envoi en cours | Ses requêtes partent ; la ligne montre où elle en est |
| Envoyé | Tous les items ont été acceptés |
| Échec | Ce qui a refusé et quoi vérifier — le reste se déplie sous Détail |
| Écarté | Une abstention délibérée, avec son motif |
L'avancement s'écrit au plus une fois par seconde, la première requête toujours. Dès une
seconde d'espacement — un connecteur logiciel neuf en attend dix, l'agent Sekoia deux —, c'est à chaque requête ; un connecteur ou un délai d'agent réglé pour envoyer d'affilée
avance alors par pas d'une seconde. Le relevé est la vérité, et l'écran
ne fait que le relire : une mise à jour perdue laisse la ligne en retard d'un pas, jamais fausse.
Requêtes garde son prévu une fois l'exécution terminée, si bien qu'un envoi arrêté en chemin se
lit 21 / 25.
Écarté n'est pas un échec. Un échec appelle un diagnostic ; une abstention appelle un geste, et son motif le nomme :
- la communauté n'a pas de clé d'API Sekoia ;
- la destination est personnalisée et n'a pas de base d'API ;
- le connecteur a été retiré, ou désactivé après la mise en file de l'exécution ;
- la technologie Sekoia Agent n'a pas de clé d'intake, ou n'est plus activée ;
- il n'y a rien à inventorier.
Un échec se lit en deux temps. La première ligne dit ce qui a refusé et quoi vérifier — la clé d'API Sekoia de la communauté, l'UUID du connecteur, la région. Détail déplie le reste : le point d'entrée appelé, le nombre de tentatives, puis la réponse de Sekoia caviardée de toute clé — un message borné à 500 caractères, ou, quand des items sont refusés, une erreur de validation par ligne, avec la valeur reçue et le nombre d'items concernés. Un lot refusé dit aussi sa place — et son hôte, pour le logiciel —, combien de lots ont été refusés, par statut, et quels hôtes ; quand l'exécution s'est arrêtée, il dit combien de lots ne sont pas partis. Un envoi refusé de l'agent Sekoia — conformité ou logiciels — compte ses refus par statut et nomme le premier agent refusé.
Envoyer maintenant met aussitôt une exécution de plus en file, même si la communauté est arrêtée ou le connecteur désactivé : on la demande précisément pour renvoyer ce qui est déjà parti.
Aperçu
L'Aperçu montre ce que la prochaine exécution enverrait, sans rien envoyer : le nombre d'items et de lots, les trois premiers items en entier, et ce qui a été laissé de côté — nommé, jamais seulement compté, parce que chaque liste appelle un geste différent.
| Nommé dans l'aperçu | Ce que cela veut dire |
|---|---|
| Entités sans identifiant d'agent ni e-mail | Aucune identité exploitable : elles ne sont pas inventoriées |
| Systèmes sans produit connu | Aucune vulnérabilité ne peut leur être rattachée |
| Entités sans archétype | Leur inventaire logiciel se réduit à l'OS — sauf si leur tranche déclare des rôles |
| Rôles que la population ne décrit pas | Leurs entités n'ont que le socle de leur tranche |
| Entités sans rôle | Elles n'ont que le socle de leur tranche |
| Binaires non classés | Déclarés sous leur propre nom, hors de toute application |
| Postes Linux | Le moteur leur prête des processus Windows ; ils ne déclarent que leur OS |
Quand l'inventaire part
Une fois par jour local, à partir de 08:00 dans le fuseau de la communauté (révise le 08:00 UTC du projet d'origine). La source servait des communautés françaises ; ici chaque communauté vit dans son fuseau, et c'est à 8 h chez elle qu'un inventaire se relève.
À partir de, et non à. L'ordonnanceur vérifie toutes les cinq minutes si l'exécution du jour existe. Un backend redémarré à 15 h rattrape donc la journée — un seul mécanisme, comme pour le plan d'une journée simulée.
« Activer la génération » envoie aussitôt l'inventaire du jour, et « Activer le pool » celui de chaque équipe, toutes décrivant le même instant. L'activation n'attend ni le passage suivant ni 8 h : elle met en file l'exécution que l'ordonnanceur aurait lancée, sous le même identifiant, si bien que le passage de 8 h la trouve faite et n'envoie rien de plus. Activée avant 8 h, l'inventaire du jour part plus tôt, pas deux fois ; réactivée le même jour, rien n'est renvoyé — Envoyer maintenant reste le moyen d'envoyer à nouveau. Une communauté sans clé d'API Sekoia à ce moment s'abstient pour la journée, comme elle le ferait à 8 h : posez la clé avant d'activer.
Seules les communautés actives sont planifiées : une communauté arrêtée — à la main, ou parce que toutes ses technologies sont tombées — ne tourne pas, et son inventaire non plus. Rien n'est planifié sans connecteur actif ni agent Sekoia éligible.
Les items partent dans un corps {version: 1, items} : des hôtes entiers pour le logiciel,
autant par requête que le dit Hôtes / requête du connecteur — dix pour un connecteur neuf — et jamais au-delà
de 1 000 items — un poste n'est jamais à cheval sur deux requêtes, et un hôte refusé se nomme ; un
hôte au-delà de 1 000 applications, le plafond de l'API, est recoupé et part seul —, des lots de
1 000 pour les autres connecteurs. Un inventaire logiciel de H hôtes regroupés par G fait donc
environ H / G requêtes. Deux requêtes d'une exécution sont séparées
par l'espacement du connecteur — jamais avant la première, ni après la dernière —, si bien qu'une
exécution de N requêtes dure au moins (N − 1) × l'espacement ; la conformité et l'inventaire
logiciel de l'agent Sekoia, qui n'ont pas de ligne de connecteur, s'espacent du
délai de l'agent de la communauté, deux secondes par défaut. Chaque requête dispose de 30 secondes et de cinq
tentatives au plus, avec un backoff exponentiel de 1 à 10 secondes qui s'ajoute à l'espacement ; sur
un 429, le Retry-After est honoré, borné à une minute. Un inventaire est quotidien et n'a aucune
urgence, et l'API qui le reçoit limite son débit.
Jusqu'à trois exécutions jouent de front, toutes communautés confondues : un inventaire logiciel espacé ne retient pas les autres. Dans une exécution, les requêtes partent toujours l'une après l'autre ; deux formats d'une même communauté peuvent en revanche poster en même temps, sous la même clé.
Un lot refusé pour son propre contenu n'arrête pas l'exécution : des items que Sekoia rejette, ou un lot trop lourd, ne disent rien du lot suivant, si bien que les lots suivants partent quand même et que l'audit nomme les refusés — avec tous les hôtes qu'ils portaient. Une clé refusée, un connecteur introuvable, un point d'entrée faux ou une API qui reste indisponible valent pour tous les lots, et arrêtent l'exécution.
Retrouver un envoi dans le journal
Chaque requête qu'une exécution poste s'écrit dans le journal d'api-asset, sous le contexte
[AssetSenderService] — une ligne par lot, ou par rapport de l'agent Sekoia, dès qu'elle a sa
réponse :
docker compose -f infrastructure/docker/docker-compose.dev.yml logs -f api-asset | grep AssetSenderService
Sur un hôte déployé, la même commande logs vise le fichier compose de l'environnement, comme pour
le mot de passe initial. Une ligne se lit ainsi :
« Acme » HarfangLab EDR Software · lot 3/120 · pc-jdoe-01 · 42 items → HTTP 200 en 184 ms · exécution a.<communauté>.harfanglab-edr-software.2026-09-15 · POST https://app.sekoia.io/api/v2/asset-management/asset-connector/<uuid>
« Acme » HarfangLab EDR Software · lot 4/120 · pc-mdupont · 38 items → tentative 1/5 : HTTP 503, nouvel essai dans 1 s · exécution … · POST …
« Acme » HarfangLab EDR Software · lot 4/120 · pc-mdupont · 38 items → HTTP 200 en 1293 ms, 2 tentatives · exécution … · POST …
« Acme » HarfangLab EDR Software · lot 2/12 · 10 hôtes (pc-adurand, pc-bmartin, pc-clefebvre, +7) · 412 items → HTTP 200 en 640 ms · exécution … · POST …
« Acme » Sekoia Agent compliance · rapport 2/80 · PC-JDOE-01 · agent <agentId> → refusé HTTP 404 en 95 ms · exécution … · POST https://app.sekoia.io/api/v1/xdr-agent/compliance
« Acme » Sekoia Agent software · inventaire 3/80 · PC-JDOE-01 · agent <agentId> · 18 paquets → HTTP 200 en 120 ms · exécution … · POST https://app.sekoia.io/api/v1/xdr-agent/software
- La communauté et le format — donc le connecteur à regarder dans l'onglet Assets.
- La requête — son rang dans l'exécution ; pour le logiciel, l'hôte qu'elle porte — ou, regroupés, le nombre d'hôtes et les trois premiers — ; pour l'agent Sekoia, le poste et son agent — et, pour son inventaire logiciel, le nombre de paquets ; puis le nombre d'items.
- L'issue — le statut HTTP, et la durée de la requête, tentatives et attentes comprises. Une requête acceptée est une ligne d'information ; une requête refusée, ou restée sans réponse, un avertissement. Quand elle arrête l'exécution, la ligne dit combien de requêtes ne sont pas parties.
- Chaque tentative relancée — un avertissement à elle seule, avec ce qu'elle a reçu et l'attente
avant la suivante : une requête retenue par un
Retry-Afterse voit pendant qu'elle attend, et non une fois finie. - L'exécution — l'identifiant de son relevé, qui départage les lignes de trois exécutions de front ; puis le point d'entrée appelé.
Une ligne ne porte jamais la clé, ni la réponse de Sekoia : le motif d'un refus, clé masquée, se
déplie sous Détail dans la carte Dernières exécutions. Une fois le relevé écrit, le worker
clôt la série sous son propre contexte [AssetDispatchWorker] : Inventaire <format> de <identifiant de la communauté> : <statut>.
Les vulnérabilités
Les vulnérabilités d'un équipement se choisissent sur son OS réel. Le projet d'origine
appliquait à tous les équipements les CVE d'un seul produit codé en dur, Windows 11 ; ici un
Windows Server 2022 reçoit des CVE de serveur, et un poste Ubuntu celles d'Ubuntu.
Les produits connus : Windows 7 SP1, Windows 8.1, Windows 10 22H2, Windows 11 22H2 et 23H2, Windows Server 2016, 2019 et 2022, Ubuntu 22.04 et 24.04, RHEL 9, Debian 12.
Chaque équipement reçoit de 0 à 3 CVE de son OS, stables par équipement. Un OS sans produit dans cette liste n'en reçoit aucune — et l'aperçu le nomme, plutôt que de laisser une liste vide passer pour une machine à jour.
Une application en retard porte les CVE réelles de sa version — la version que
l'inventaire logiciel déclare. Une ou deux par application en retard, sur un
budget à part : les CVE d'OS d'un équipement ne changent pas quand ses applications en gagnent. Une
application à jour n'en porte aucune, parce que le catalogue ne retient que des CVE qu'une version
ultérieure corrige, et le constat le dit (is_fix_available). Le modèle Sekoia n'a pas de champ pour
le paquet touché : l'éditeur de l'application (vendor_name) et le titre de la CVE, qui nomme le
produit, disent lequel.
Le catalogue de CVE
Les CVE viennent d'un catalogue au plancher semé de CVE réelles, chacune vérifiée auprès de NVD
et portant son lien NVD : 31 pour les systèmes d'exploitation, et 32 pour les applications dont les
fiches NVD nomment une version corrigée — Adobe Acrobat, Google Chrome, Microsoft Edge et Mozilla
Firefox. C'est un jeu de données — « Vulnérabilités (CVE) », slug cve-catalogue —, éditable depuis
/datasets comme n'importe quel autre.
Une installation semée plus tôt reçoit les nouvelles lignes. Le plancher est créé une fois et
jamais réécrit ; chaque semis ajoute les CVE qui lui manquent, et donne leurs plages de versions aux
lignes semées qui n'en ont pas. Une ligne écrite par le feed ou depuis /datasets n'est jamais
touchée.
Microsoft 365 Apps, OneDrive, AnyDesk, Chocolatey, Zscaler, Intune et Edge Update n'ont aucune CVE applicative : NVD n'en porte aucune qu'une version du catalogue corrige — Microsoft 365 Apps, par exemple, n'y est jamais versionné.
Il peut être rafraîchi chaque jour depuis NVD, par l'API CVE 2.0 publique — sans clé. Dans Configuration → Configuration générale, carte Feed CVE (NVD) : cocher Rafraîchir chaque jour le catalogue de CVE depuis NVD, ou cliquer sur Rafraîchir maintenant. Le rafraîchissement tourne en arrière-plan et prend une à deux minutes : le quota public de NVD — cinq requêtes par trente secondes — espace les interrogations.
Deux règles le rendent sûr :
- le feed ne remplace que les lignes qu'il a écrites. Une ligne semée, ou saisie depuis
/datasets, survit à chaque rafraîchissement ; - un rafraîchissement vide ou en échec laisse le catalogue en l'état. Remplacer un catalogue daté par un catalogue vide serait strictement pire — la règle que suit déjà le feed d'indicateurs.
Une CVE n'est rattachée à un produit que si NVD désigne ce produit lui-même comme vulnérable. NVD liste aussi les plateformes sur lesquelles tourne un composant vulnérable : une faille d'application peut nommer Windows comme plateforme, et la compter donnerait à chaque équipement Windows une CVE qui n'est pas celle de Windows.
Les logiciels
L'inventaire logiciel d'un équipement est ce que son rôle installe, tel que sa population le décrit — les rôles de l'unité d'organisation d'un utilisateur ou du rôle d'un serveur, par-dessus le socle de la tranche. La même liste borne les processus que ses journaux nomment, si bien que l'inventaire et les journaux ne peuvent pas se démentir : une application dont les journaux montrent le processus est une application que l'inventaire déclare.
- l'inventaire déclare le système, puis exactement les applications du rôle, avec les compagnons que leur installateur pose (Chrome apporte Google Update) ;
- une application que ses gestes lancent se décrit par le chemin que montrent les journaux ; une autre — SQL Server sur un serveur de bases de données, Wireshark sur un poste informatique — par l'exécutable que son installateur pose. Installé n'est pas lancé ;
- les binaires des répertoires propres à Windows appartiennent au paquet de l'OS.
Une tranche de la population qui ne déclare aucun rôle garde la dérivation d'avant : l'inventaire est ce que le moteur peut faire exécuter aux gestes de l'équipement — les tables de processus mêmes où puisent les journaux —, regroupé en applications. Les six populations de démonstration déclarent des rôles pour leurs deux tranches.
Chaque application est décrite par l'exécutable qu'un inventaire cite : son fichier, son
répertoire, son architecture et sa signature viennent tous de ce même chemin. Les colonnes que
Sekoia affiche se remplissent depuis l'objet software de l'item — celui que le connecteur
HarfangLab de Sekoia n'envoie pas, et c'est pourquoi elles restaient vides tant que SekoiaCraft
l'imitait :
| Colonne | Rempli depuis |
|---|---|
| Publisher | la société qui édite l'application (software.vendor_name) |
| Version | la version du poste (software.version, et sbom.package.version) |
| Architecture | le chemin : le _x64 d'un paquet Store, Program Files (x86) pour du 32 bits — sauf Edge |
| Filename | l'exécutable (software.binary_name) ; son répertoire va dans software.path |
| Signed | un signataire qu'une source publique atteste (software.signature.state) |
| SignedBy | le sujet du certificat, quand son autorité est attestée aussi (certificate.subject) |
| CPE | le produit que le dictionnaire de NVD nomme, à la version du poste (sbom.package.cpe_name) |
Le rattachement des colonnes aux champs se lit sur les noms des champs du modèle Sekoia ; Sekoia ne le documente pas.
Les versions sont réelles. Elles viennent de l'historique officiel de chaque éditeur — Chrome,
Edge, Firefox, Microsoft 365 Apps, OneDrive, Acrobat, AnyDesk, Chocolatey, Zscaler, Edge Update,
Teams, Visual Studio Code, Git for Windows, Docker Desktop, Notepad++, 7-Zip, PuTTY, WinSCP,
Wireshark, KeePass, Zoom, SQL Server 2022 et Veeam —, une par trimestre depuis 2024. La plupart des postes portent la dernière version sortie le jour de
l'inventaire ; environ 15 % des couples (poste, application) ont une à trois versions de retard.
Cette part est un choix de modélisation, stable d'un inventaire à l'autre et tirée par application :
un poste peut être en retard sur Chrome et à jour sur Firefox. Une application qu'aucune source ne
date garde unknown.
Le CPE nomme le produit, à la version du paquet. sbom.package.cpe_name est le champ que le
connecteur HarfangLab de Sekoia mappe depuis son cpe_prefix, et le seul identifiant normalisé
qu'un inventaire porte. La chaîne vient du dictionnaire CPE de NVD, et une seule règle la remplit :
la version du poste remplace le slot version quand — et seulement quand — la chaîne relevée l'y
laisse libre (*). Un - dit que NVD déclare ce produit sans version — Microsoft 365 Apps,
OneDrive sous Windows, l'extension Intune —, et y poser la nôtre inventerait un produit. Une version
unknown laisse le slot libre. Rien d'autre n'est touché, si bien que l'édition continuous
d'Acrobat et la plate-forme windows de OneDrive survivent telles quelles. Le paquet de l'OS porte
l'identité de son produit telle que le dictionnaire l'écrit, jamais la chaîne élargie qu'interroge
le feed de CVE, et son build n'y est jamais substitué : un build n'est pas une version CPE, et la
release est déjà dans le nom du produit (windows_11_23h2).
Les journaux montrent la même version. Edge, OneDrive et quelques autres écrivent leur version
dans un répertoire (…\Edge\Application\122.0.2365.92\…). Ce répertoire prend la version du poste
dans les journaux aussi — chemin, ligne de commande et empreinte —, si bien qu'un poste en retard sur
Edge montre l'ancienne version des deux côtés.
Le signataire est partagé avec les journaux. SentinelOne, Cortex et HarfangLab nomment le même
signataire que l'inventaire, lu dans le même catalogue — SentinelOne écrit le sujet du certificat en
majuscules (MICROSOFT WINDOWS), Cortex la société (Microsoft Corporation). Un binaire de Windows
n'est signé « Microsoft Windows » que dans les répertoires propres au système (System32,
SysWOW64, WinSxS, …), jamais pour la seule raison qu'il se trouve sous C:\Windows\. L'autorité
du certificat dépend de la version : Edge, Edge Update et Firefox en ont changé pendant la période,
et chaque poste reçoit celle de sa version.
Les binaires de menace ne sont jamais déclarés. Le processus d'un implant qui tourne hors inventaire est exactement ce qu'un analyste doit remarquer ; le déclarer le cacherait parmi les logiciels légitimes.
Ce que le lot ne fait pas
- Les utilisateurs Entra ID se rapprochent de leurs journaux par l'UPN, pas par l'identifiant.
Les journaux Entra ID tirent encore un
userIdau hasard ; c'est l'e-mail que les deux portent. - L'identifiant d'agent numérique de SentinelOne reste tiré au hasard. Un équipement SentinelOne ne rencontre ses journaux que par l'identifiant de 32 caractères.
- Les postes Linux ne déclarent que leur OS, alors que le moteur leur prête encore des processus Windows dans les journaux. L'aperçu les nomme.
- Sans rôles, l'ensemble des applications est presque uniforme d'un poste Windows à l'autre : les tables de processus sont partagées. Déclarer les rôles de la population est ce qui distingue les postes.
- Une application déclarée mais jamais lancée n'apparaît pas dans les journaux. Les pools de processus ne portent que les applications que le corpus montrait ; SQL Server et Veeam apparaissent dans le journal d'écoute d'un serveur, les autres dans l'inventaire seulement.
- Les destinations ne sont pas filtrées. Un geste de messagerie dont le client (Outlook) n'est pas installé garde sa destination et ne nomme aucun processus.
- Un rôle sans Microsoft 365 ou sans navigateur vide le pool correspondant : ouvrir une application, ou naviguer, ne nomme alors aucun processus, et chaque technologie retombe sur son propre échantillon. Les populations semées portent toujours les deux.
- Le journal d'écoute d'un serveur suit son rôle, pas sa liste. Le 5154 d'un serveur de bases de données nomme SQL Server quoi que son rôle installe : retirer SQL Server de ce rôle fait nommer au journal une application que l'inventaire ne déclare pas.
- Le catalogue des versions est figé en code. Il porte une version par trimestre jusqu'au jour où il a été relevé ; au-delà, les postes restent sur la dernière version connue. Le rafraîchir, c'est y ajouter des lignes.
- Google Update, l'agent des machines virtuelles Azure, Phone Link et Courrier gardent la version que leur répertoire écrit. Aucune source ne date leurs versions — et le répertoire de l'agent Azure porte aussi sa date d'installation, qu'une version réécrite démentirait.
- Certaines applications sont signées sans certificat. Microsoft 365 Apps, les applications du Store et Intune montrent un signataire dont aucune source ne nomme l'autorité ; Adobe, Zscaler, OneDrive, l'agent Azure, SAP GUI et Veeam n'en montrent aucun, et 7-Zip n'est pas signé par son éditeur. Edge 145 à 147 tombent entre deux autorités relevées ; Git for Windows dès 2.55, Wireshark dès 4.6.5 et SQL Server avant sa mise à jour de septembre 2026 sont signés par des autorités qui changent d'une version à l'autre, ou qu'aucune source ne date.
- SAP GUI garde
unknown. Ses dates de publication sont derrière un compte SAP, et son chemin d'installation n'est attesté que par un tiers — comme celui de Zoom. - Sept applications n'ont pas de CPE. Le dictionnaire de NVD ne nomme aucun produit pour
Google Update (il ne connaît que
google:updater2.4.x, un autre produit), le service de mise à jour d'Acrobat, Phone Link, Courrier et Calendrier, Chocolatey et l'agent Azure VM ; il nomme Git sans le suffixe.windows.Nque Git for Windows déclare. Leurs items partent sans le champ plutôt qu'avec un quasi-homonyme, qui ferait apparier les CVE d'un autre logiciel. - Aucune empreinte ne part avec un logiciel. Un binaire sans répertoire de version (
chrome.exe) garde la même empreinte dans les journaux d'une version à l'autre ; le déclarer avec une version ancienne le démentirait. - Les CVE applicatives viennent du seul plancher semé. Le rafraîchissement NVD couvre toujours les seuls systèmes d'exploitation.
- Le rattachement des colonnes Sekoia aux champs de l'item est déduit des noms des champs de son modèle ; seul un envoi réel le confirme.
last_logonne relit pas la journée simulée : il se dérive de l'entité, pas des ouvertures de session que montrent les journaux.