Aller au contenu

đŸ›Ąïž SENTRY — État global aprĂšs intĂ©gration M1–M6

Date : 03/10/2026 · Référence auditée : main = 266b46e (« Merge branch 'feature/phases-4-6' into 'main' ») · Auteur de l'audit : Claude (Cowork), pour Godwill FOKA Méthode : reconstitution du dépÎt depuis la copie locale (le bac à sable n'a pas accÚs à gitlab.com), CI rejouée sur trois environnements, base PostgreSQL neuve alimentée par de vraies sources, scénario SOC exécuté contre l'API réelle (uvicorn), analyses de sécurité outillées.


1. SynthĂšse

Les six modules sont intégrés dans main et fonctionnent ensemble sur données réelles : 3 867 IOC collectés depuis 3 sources publiques, 1 733 CVE du catalogue KEV officiel, un incident mené de l'ouverture à la clÎture avec post-mortem, des exports, deux sessions de chasse. Le scénario d'acceptation passe 40/40, la CI 388 tests verts sur trois environnements.

Ce qui sépare main d'une plateforme exploitable n'est plus du code fonctionnel :

  1. un défaut bloquant sur le poste Kali : mypy échoue avec SQLAlchemy 2.0 (corrigé, § 13) ;
  2. une faille d'intégrité : TRUNCATE contourne l'immuabilité de la chronologie (§ 7) ;
  3. la validation des sources sous clé (OTX, RedEye, NVD, EPSS), impossible depuis ce bac à sable et à faire sur Kali.

Verdict : baseline v0.1.1 acceptable aprÚs fusion de release/v0.1.1 (correctif + rapport). M7 « Production Hardening » est bien la priorité suivante ; la faille TRUNCATE et le verrouillage des dépendances en sont les deux premiers items.

2. Architecture actuelle

CLI (Click/Rich, 34 commandes)     API REST (FastAPI, 29 routes)
              └──────────────┬──────────────┘
                 Services métier (sentry/modules)
   threat_feeds · cve_tracker · incidents · dashboard · threat_hunting · foundation
                             │
           SQLAlchemy 2 async · Alembic (6 migrations, 1 seule head)
                             │
          PostgreSQL 16 (14 tables)        Redis 7 (verrous, limitation de débit)

Un processus API, un worker unique (sentry feeds worker) qui planifie flux, CVE et chasse sous verrou Redis. Couches respectées : aucun service n'importe FastAPI ; les contrÎleurs n'accÚdent pas à SQL directement.

3. État M1 → M6, sur quatre niveaux

Niveau Définition
CODE fonctionnalité développée et fusionnée dans main
TESTÉ tests automatisĂ©s verts (CI)
INTÉGRÉ exercĂ© contre des composants rĂ©els (PostgreSQL, Redis, API HTTP, sources Internet)
OPÉRATIONNEL critĂšre de jalon constatĂ© par sentry status sur donnĂ©es rĂ©elles, en continu
Module CODE TESTÉ INTÉGRÉ OPÉRATIONNEL Constat de l'audit
M1 Foundation ✅ ✅ ✅ ✅ API, auth, rĂŽles, migrations, CLI vĂ©rifiĂ©s en conditions rĂ©elles
M2 Threat Feeds ✅ ✅ ✅ ◐ 2/4 3 sources saines, 3 867 IOC ; OTX (clĂ©) et STIX/TAXII (jeton RedEye) non constatĂ©s
M3 CVE ✅ ✅ ◐ ✘ 0/4 KEV rĂ©el importĂ© (1 733) ; NVD et EPSS bloquĂ©s par le bac Ă  sable
M4 Incidents ✅ ✅ ✅ ◐ cycle complet sur donnĂ©es rĂ©elles ; faille TRUNCATE ; persistance du critĂšre Ă  constater sur Kali
M5 Dashboard ✅ ✅ ✅ ◐ synthĂšse, activitĂ©, 8 exports ; sĂ©ries 7 jours absentes
M6 Hunting ✅ ✅ ✅ ◐ chasse sur observables et sur 3 867 IOC ; RULE-01 (Tor) non testable ici

Avancement défendable

Mesure Valeur Calcul
Code du pĂ©rimĂštre v1.0 ≈ 88 % tĂąches du plan directeur livrĂ©es et testĂ©es (inchangĂ© depuis le 03/10 matin)
IntĂ©gration rĂ©elle ≈ 80 % 5 modules sur 6 intĂ©grĂ©s, M3 Ă  moitiĂ©
Jalons opérationnels 1 / 6 constaté, 4 partiels sentry status sur la base d'audit

Confiance : élevée pour les trois mesures sur le périmÚtre testé ici ; moyenne pour M3, dont la moitié NVD/EPSS n'a jamais reçu de vraie réponse.

4. Fonctionnalités implémentées

  • Renseignement : CSV, JSON, texte, STIX 2.1, TAXII 2.1 (taxii2-client durci), OTX ; normalisation, dĂ©duplication, provenance multi-sources, expiration par type ; sondes sentry feeds probe et sentry taxii discover.
  • VulnĂ©rabilitĂ©s : NVD 2.0 incrĂ©mental (filtre hasKev Ă  la premiĂšre synchro), KEV, EPSS, score composite 0–100, prioritĂ©s P0–P3, historique, alertes + webhook.
  • RĂ©ponse : machine d'Ă©tat NIST SP 800-61, assignation, notes, liens IOC/CVE, ouverture depuis une alerte (idempotente), post-mortem obligatoire, chronologie immuable.
  • Pilotage : synthĂšse temps rĂ©el, activitĂ© 24 h, MTTR, exports CSV/JSON en flux.
  • Chasse : 6 rĂšgles, deux modes, sessions enregistrĂ©es, chasse planifiĂ©e.
  • SĂ©curitĂ© transverse : JWT + Argon2id, RBAC 3 rĂŽles, anti-SSRF, secrets hors base, limitation des connexions, anti-injection CSV.

5. Tests et couverture

Environnement Python SQLAlchemy Résultat
Identique au job GitLab (dĂ©pendances les plus rĂ©centes) 3.12.3 2.1.3 388 ✅, 4 ignorĂ©s, 94 %
Matrice GitLab 3.14 3.14.7 2.1.1 388 ✅, 4 ignorĂ©s, 93 %
Simulation du poste Kali 3.12.3 2.0.54 mypy ✘ sur main → ✅ aprùs correctif ; 388 ✅

Les 4 tests ignorés sont les tests réseau réels (SENTRY_LIVE_TESTS=1), à lancer sur Kali.

Nouveau test d'acceptation : scripts/scenario_soc.py rejoue le parcours SOC complet contre une instance réelle et mesure les latences. Résultat : 40/40.

6. CI/CD

Le pipeline GitLab (qualitĂ© → tests matrice 3.12/3.14 → migrations aller-retour → image Docker → SAST, secrets, dĂ©pendances) est vert sur main d'aprĂšs les MR fusionnĂ©es. RejouĂ© ici : qualitĂ©, tests et migrations ✅. Non rejouĂ© : construction de l'image (dĂ©mon Docker absent du bac Ă  sable) et analyses natives GitLab.

Risque identifié : les dépendances ne sont bornées que par le bas (>=). La CI installe la derniÚre version publiée, le poste Kali une version antérieure : c'est exactement ce qui a produit l'écart mypy du § 13. Correctif prévu en M7 (fichier de contraintes partagé CI/Docker/Kali).

7. Sécurité

ContrÎle Résultat
pip-audit (dépendances installées) 0 vulnérabilité connue
bandit (code applicatif) 0 haut, 0 moyen, 2 faibles (faux positifs documentés : sentinelle de clé refusée en production, libellé "access")
Sans jeton / jeton altĂ©rĂ© / alg=none 401 / 401 / 401 ✅
RBAC : VIEWER crĂ©e un incident, lance une chasse ; ANALYST crĂ©e une source 403 ✅
SSRF : source vers 169.254.169.254 422 ✅ — rectifiĂ© le 04/10 : la premiĂšre version du scĂ©nario obtenait ce 422 pour une autre raison (type de flux en minuscules, schĂ©ma http). RejouĂ© avec une requĂȘte valide : refus par l'anti-SSRF confirmĂ© (« Adresse IP interne ou rĂ©servĂ©e interdite »).
Injection dans un identifiant de CVE 422 ✅
Force brute : 6ᔉ tentative 429 ✅
CORS depuis une origine inconnue refusĂ© (400) ✅
Secrets dans les journaux aucun ✅
UPDATE / DELETE sur la chronologie refusĂ©s par le dĂ©clencheur ✅
TRUNCATE incident_events acceptĂ© ✘ : un dĂ©clencheur de ligne ne voit pas TRUNCATE
PropriĂ©taire des tables = compte applicatif ✘ : ce compte peut aussi supprimer le dĂ©clencheur
Ports Compose ✘ : PostgreSQL (5433) et Redis (6379, sans mot de passe) Ă©coutent sur toutes les interfaces du poste
En-tĂȘtes de sĂ©curitĂ© HTTP absents (HSTS, nosniff, frame-ancestors, no-store)
Verrouillage de compte contournable en dĂ©ni de service : 5 Ă©checs depuis n'importe oĂč bloquent le vrai titulaire 15 min

Les cinq lignes ✘ deviennent le premier lot de M7.

8. Validation rĂ©elle — Threat Feeds (M2)

Source Résultat Lus Nouveaux Cause si échec
IPsum niveau 5 HEALTHY 3 528 3 528 —
C2IntelFeeds IP 30 j HEALTHY 252 252 —
C2IntelFeeds domaines 30 j HEALTHY 89 87 2 doublons internes
abuse.ch Feodo DEGRADED — — proxy du bac à sable (403), pas la source
abuse.ch URLhaus DEGRADED — — ABUSECH_AUTH_KEY absente (attendu)
AlienVault OTX DEGRADED — — OTX_API_KEY absente (attendu)
RedEye TAXII DEGRADED — — proxy du bac à sable ; jeton absent
DigitalSide ×2 inactives — — injoignables (constat du 29/09)
  • DĂ©duplication : seconde collecte d'IPsum → 0 nouveau, 3 528 mis Ă  jour ✅.
  • Provenance : chaque IOC expose sa source dans l'API ✅. Recouvrement entre sources : 0 (C2IntelFeeds et IPsum ne partagent aucune IP ce jour-lĂ ).
  • Expiration : 3 867 / 3 867 actifs, attendu le jour mĂȘme de la collecte.
  • Performance : collecte complĂšte en 20 s, pic mĂ©moire 111 Mo (cible 256 Mo).
  • CritĂšres M2 : volume ✅, 3 sources ✅, OTX ✘, STIX ✘ → non atteint ici, atteignable sur Kali avec la clĂ© OTX et le jeton RedEye.

9. Validation rĂ©elle — CVE (M3)

  • KEV : catalogue officiel 2026.10.02, 1 733 entrĂ©es, importĂ© en 3 s via le dĂ©pĂŽt GitHub cisagov/kev-data (mĂȘmes donnĂ©es que cisa.gov, inaccessible depuis le bac Ă  sable) ; le nouveau champ forensicTriage est tolĂ©rĂ© ✅.
  • NVD, EPSS : non joignables depuis le bac Ă  sable. À constater sur Kali (sentry cves sync).
  • Observation de scoring : sans CVSS ni EPSS, une CVE KEV liĂ©e au ransomware vaut 35 → P3. Situation transitoire (la premiĂšre synchro NVD rĂ©cupĂšre toutes les CVE KEV via hasKev), mais elle devient durable si ce filtre Ă©choue. Proposition pour M8, Ă  trancher par ADR : plancher « KEV ⇒ au moins P1 », cohĂ©rent avec les dĂ©lais de la directive CISA BOD 22-01.

10. Incident Management (M4)

Parcours rĂ©el : ouverture (ANALYST) → assignation → liaison d'un IOC IPsum et d'une CVE KEV → NOUVEAU→CLOTURE refusĂ© (409) → ANALYSE → CONFINEMENT → ERADICATION → RECUPERATION → note d'un second analyste → clĂŽture sans post-mortem refusĂ©e (422) → clĂŽture avec post-mortem. Chronologie : 10 Ă©vĂšnements. Latence mĂ©diane des appels incidents : 11,5 ms.

11. SOC Dashboard (M5)

SynthÚse 28 ms, activité récente 200 évÚnements, 8 exports valides (IOC CSV 654 Ko en 190 ms, CVE CSV 660 Ko en 105 ms). Fonctionnel techniquement ; pas encore une console SOC : ni série temporelle, ni file de triage, ni vue par analyste. Ces manques relÚvent de M9.

12. Threat Hunting (M6)

  • Sur observables (IOC rĂ©el, domaine duckdns.org, domaine alĂ©atoire, IP propre, valeur invalide) : 3 correspondances (RULE-02, RULE-03, RULE-06), 1 rejet, 12 ms.
  • Sur la base complĂšte (3 867 IOC) : 27 ms, 1 correspondance.
  • RULE-01 (Tor) non testĂ©e ici : liste torproject.org bloquĂ©e par le bac Ă  sable.

13. Dette technique

# Dette Gravité Traitement
D1 mypy Ă©choue avec SQLAlchemy 2.0 (Select[Any, Any]) — cause du stash local du 03/10 Moyenne corrigĂ© dans release/v0.1.1 (annotation Executable, valide en 2.0 et 2.1)
D2 Dépendances non verrouillées Moyenne M7
D3 Pas de test d'acceptation en CI (le scénario exige des données réelles) Moyenne M7/M11 : jeu de données figé + job dédié
D4 Image Docker jamais construite hors GitLab Faible job GitLab existant
D5 Heuristique DGA non calibrée sur corpus Faible M8
D6 RULE-05 par mots-clés, sans CPE Faible M8
D7 Six branches locales obsolÚtes, trois stash Faible nettoyage (§ 16)

14. Risques restants

Risque Niveau Parade
AltĂ©ration de la chronologie par TRUNCATE ou par le propriĂ©taire des tables ÉlevĂ© pour un usage probatoire M7 lot 1
Redis/PostgreSQL exposés sur le réseau local du poste Kali Moyen M7 lot 1
Dérive des dépendances entre poste et CI Moyen M7 lot 1
NVD/EPSS jamais éprouvés en réel Moyen sentry cves sync sur Kali cette semaine
Une seule source STIX, sous jeton Moyen jeton RedEye ; budget CrowdSec à évaluer
Verrouillage de compte exploitable en déni de service Faible M7 lot 1

15. Feuille de route

Étape Objectif État
M1–M6 Socle fonctionnel ✅ intĂ©grĂ© dans main
Audit global Validation M1–M6 ✅ ce rapport
v0.1.1 Baseline stable ⏳ fusion de release/v0.1.1, puis tag
M7 Production Hardening 🔄 lot 1 sur feature/m7-production-hardening
M8 Detection & Correlation ⏳
M9 SOC Operations (triage L1/L2/L3) ⏳
M10 CTI Intelligence (acteurs, campagnes, ATT&CK) ⏳
M11 Observability & Deployment ⏳
v0.2.0 Production Candidate ⏳

Détail et critÚres de sortie : docs/ROADMAP.md.

16. Prochaine phase — actions dans l'ordre

  1. Fusionner release/v0.1.1 → main (MR, pipeline vert). VĂ©rification : mypy sentry passe sur Kali sans le stash.
  2. Taguer : git tag -a v0.1.1 -m "SENTRY M1-M6 integrated baseline" && git push origin v0.1.1.
  3. Constater M2/M3 sur Kali : clĂ©s OTX, NVD, jeton RedEye dans .env, puis sentry feeds fetch-all && sentry cves sync && sentry status. VĂ©rification : M2 et M3 ✅.
  4. Rejouer le scĂ©nario sur Kali : python scripts/scenario_soc.py → 40/40.
  5. Nettoyer : git stash drop ×3 (contenu intĂ©grĂ© ou corrigĂ©), supprimer les branches locales fusionnĂ©es (git branch --merged main).
  6. Fusionner feature/m7-production-hardening (lot 1) aprĂšs revue.

17. Mise Ă  jour du 04/10/2026

M7 lots 1 et 2 sont codĂ©s et vĂ©rifiĂ©s sur feature/m7-production-hardening (bilans BILAN_M7_LOT1.md, BILAN_M7_LOT2.md). Les Ă©carts ✘ du § 7 sont fermĂ©s, y compris la limite « le propriĂ©taire des tables peut supprimer un dĂ©clencheur » : l'application se connecte dĂ©sormais avec un rĂŽle sans droit de structure.

Ligne du § 3 Avant AprÚs le 04/10
M3 INTÉGRÉ ◐ (KEV seul) ◐+ : KEV rĂ©el + CVSS NVD rĂ©el des 1 733 CVE KEV (import hors ligne) ; EPSS toujours Ă  constater
M6 INTÉGRÉ RULE-01 non testĂ©e RULE-01 validĂ©e sur 1 746 relais Tor rĂ©els
Image Docker jamais construite hors GitLab construite et exécutée en production (base de substitution)

Nouveau constat (§ 4 du bilan du lot 2) : sans EPSS, aucune CVE ne peut ĂȘtre P0. À traiter par ADR en M8.

18. Mise à jour du 04/10/2026 (réexécution complÚte, M7 lot 3)

Tout le processus a Ă©tĂ© rejouĂ© depuis des bases vierges (Rapport/BILAN_M7_LOT3.md). Sept erreurs ont Ă©tĂ© trouvĂ©es et corrigĂ©es, dont deux sĂ©rieuses : un journal d'audit rendu muet par une migration exĂ©cutĂ©e dans le mĂȘme processus, et une remise Ă  zĂ©ro des tests qui faisait tomber toute la suite au changement de branche. Le contrĂŽle SSRF du scĂ©nario initial n'Ă©tait pas probant ; le § 7 est rectifiĂ© et le refus par l'anti-SSRF confirmĂ©.

M7 (lots 1 à 3) est codé : TLS par Caddy, migrations isolées, analyse d'image, entretien quotidien. CritÚre de sortie restant : préproduction sur VPS UE.

Mesure 03/10 04/10
Tests (baseline / M7) 388 / 410 388 / 437
Scénario (baseline / M7) 40 / 44 40 / 48, rejouables
Jalons opérationnels 1 / 6 1 / 6 (M2, M3 attendent les clés sur Kali)