
Modélisation du monde de la défense contre les cybermenaces
Système de modélisation mondiale de la défense contre les cybermenaces
Bandjacks est un système complet de renseignement sur les cybermenaces (CTI) qui :
| Guide | Description |
|---|---|
| Démarrage rapide | Lancez-vous en 5 minutes |
| Configuration complète | Configuration complète de l'environnement |
| Utilisation CLI | Guide de l'interface en ligne de commande |
| Référence API | Documentation de l'API REST |
| Analytiques de co-occurrence | Documentation des analytiques |
| Génération AttackFlow | Guide de génération de flux |
| Système de révision | Révision avec intervention humaine |
git clone https://github.com/yourusername/bandjacks.git cd bandjacks
uv sync
pip install -e .
cd ui && npm install && cd ..
### Configuration de l'environnement
**IMPORTANT :** Vous devez configurer les variables d'environnement avant de démarrer l'application. L'application nécessite que `NEO4J_PASSWORD` soit défini.
Créez un fichier `.env` à la racine du projet :```bash
# Copy the sample file
cp infra/env.sample .env
# Edit .env and set your actual passwords
nano .env
Configuration requise dans .env :```bash
NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=your-actual-neo4j-password # MUST BE SET - no default provided
OPENSEARCH_URL=http://localhost:9200 OPENSEARCH_USER=admin OPENSEARCH_PASSWORD=your-opensearch-password # Optional if security is disabled
LOCAL_LLM_API_BASE=http://192.168.1.100:8080/v1 # Base URL of your local server LOCAL_LLM_MODEL=mistral-nemo # Model name as the server reports it LOCAL_LLM_API_KEY=no-key # Most local servers accept any value
PRIMARY_LLM=gemini GOOGLE_API_KEY=your-gemini-api-key
OPENAI_API_KEY=your-openai-api-key
ATTACK_INDEX_URL=https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/index.json ATTACK_COLLECTION=enterprise-attack ATTACK_VERSION=latest
REDIS_URL=redis://localhost:6379
**Note:** L'application ne démarrera pas si `NEO4J_PASSWORD` n'est pas défini. Consultez [Environment Variables Fix](https://github.com/blevene/bandjacks/blob/main/ENV_VARIABLES_FIX.md) pour plus de détails.
### Démarrage des services```bash
# Start the FastAPI backend server
uv run uvicorn bandjacks.services.api.main:app --reload --port 8000
# In another terminal, start the Next.js frontend
cd ui && npm run dev
# Access the applications
open http://localhost:8000/docs # API documentation
open http://localhost:3000 # Frontend UI
Bandjacks comprend une CLI complète pour les opérations de renseignement sur les menaces :```bash
uv run python -m bandjacks.cli.main --help
> **Note :** La CLI nécessite que les variables d'environnement soient définies (NEO4J_PASSWORD, etc.). Exécutez depuis la racine du projet où se trouve `.env`.
### Commandes de requête```bash
# Search for threat intelligence
uv run python -m bandjacks.cli.main query search "ransomware encryption techniques" --top-k 10
# Explore graph relationships
uv run python -m bandjacks.cli.main query graph "attack-pattern--abc123" --depth 2
uv run python -m bandjacks.cli.main review queue --status pending --limit 20
uv run python -m bandjacks.cli.main review approve "candidate-123" --reviewer analyst-1
uv run python -m bandjacks.cli.main review reject "candidate-456" --reviewer analyst-1 --reason "False positive"
### Extraction de documents```bash
# Extract CTI from a document
uv run python -m bandjacks.cli.main extract document ./report.pdf --confidence-threshold 80 --show-evidence
Note : Les commandes d'analyse nécessitent des données
AttackEpisodedans Neo4j pour renvoyer des résultats.```bash
uv run python -m bandjacks.cli.main analytics top-cooccurrence --limit 25 --min-episode-size 2
uv run python -m bandjacks.cli.main analytics conditional "attack-pattern--abc123" --limit 25
uv run python -m bandjacks.cli.main analytics actor "intrusion-set--xyz789" --metric npmi
uv run python -m bandjacks.cli.main analytics bundles --min-support 3 --min-size 3 --max-size 5 --format json --output bundles.json
uv run python -m bandjacks.cli.main analytics global --min-support 2 --limit 50 --format csv --output pairs.csv
### Commandes de workflow```bash
# Process a directory of reports with analytics
uv run python -m bandjacks.cli.main workflow process-reports ./reports/ --workers 3 --analyze --export-dir ./results/
# Bulk export all analytics data
uv run python -m bandjacks.cli.main workflow bulk-export --export-dir ./analytics_export/
uv run python -m bandjacks.cli.main admin health
uv run python -m bandjacks.cli.main admin cache-stats
uv run python -m bandjacks.cli.main admin cache-clear --pattern "search:*"
uv run python -m bandjacks.cli.main admin optimize
## Interface frontale
Le frontend Next.js offre une interface moderne pour travailler avec le système.
### Gestion des rapports (`/reports`)
- **Liste des rapports** : Afficher tous les rapports ingérés avec leur statut et le nombre de techniques
- **Nouveau rapport** (`/reports/new`) : Téléverser des fichiers PDF/TXT ou coller le contenu du rapport
- **Détail du rapport** (`/reports/[id]`) : Afficher les techniques, entités et preuves extraites
- **Interface de révision** (`/reports/[id]/review`) : Workflow de révision avec intervention humaine
### Analyses de cooccurrence (`/analytics/cooccurrence`)
> **Remarque :** Ces pages nécessitent des données `AttackEpisode` dans Neo4j. Traitez d'abord les rapports via le pipeline d'extraction, ou utilisez `POST /v1/flows/build` pour générer des épisodes à partir des données d'ensembles d'intrusion.
- **Page Hub** : Aperçu avec le nombre d'épisodes/techniques/acteurs
- **Paires principales** (`/pairs`) : Paires de techniques cooccurrentes avec les métriques NPMI/Lift
- **Conditionnel** (`/conditional`) : Probabilités conditionnelles P(B|A)
- **Regroupements** (`/bundles`) : Regroupements de techniques fréquemment cooccurrentes
- **Acteurs** (`/actors`) : Modèles de techniques spécifiques aux acteurs
- **Pontage** (`/bridging`) : Techniques utilisées chez plusieurs acteurs
### Santé du système (`/health`)
- Statut de santé en temps réel de tous les composants (Neo4j, OpenSearch, Redis)
- Statistiques du cache et utilisation mémoire
- Points d'accès de santé compatibles Kubernetes
### Démarrage du Frontend```bash
cd ui
npm run dev # Development mode with hot reload
npm run build # Production build
npm run start # Start production server
# Ensure backend is running
# API_URL defaults to http://localhost:8000/v1
Tout d'abord, chargez le framework MITRE ATT&CK dans votre graphe de connaissances :```bash
curl -X POST "http://localhost:8000/v1/stix/load/attack"
-H "Content-Type: application/json"
-d '{
"collection": "enterprise-attack",
"version": "latest",
"adm_strict": false
}'
### 2. Extraction de techniques à partir de rapports
Extrayez les techniques MITRE ATT&CK à partir de rapports de renseignement sur les menaces :```python
import httpx
import time
# For small reports (<5KB) - synchronous processing
response = httpx.post(
"http://localhost:8000/v1/reports/ingest",
json={
"content": "APT29 used spearphishing emails with malicious attachments...",
"title": "APT29 Campaign Analysis",
"config": {
"use_optimized_extractor": True,
"span_score_threshold": 0.7,
"top_k": 5
}
}
)
result = response.json()
print(f"Extracted {len(result['extraction']['techniques'])} techniques")
# For large reports (>5KB) - asynchronous processing
response = httpx.post(
"http://localhost:8000/v1/reports/ingest_async",
json={
"content": large_report_text,
"title": "Large Report Analysis"
}
)
job_id = response.json()["job_id"]
# Check job status
status = httpx.get(f"http://localhost:8000/v1/reports/jobs/{job_id}/status")
while status.json()["status"] == "processing":
time.sleep(2)
status = httpx.get(f"http://localhost:8000/v1/reports/jobs/{job_id}/status")
# Get results from completed job
result = status.json()["result"]
print(f"Extracted {result['techniques_count']} techniques in {result['elapsed_time']} seconds")
Pour un accès programmatique sans l'API :```python from bandjacks.llm.extraction_pipeline import run_extraction_pipeline
config = { "use_optimized_extractor": True, # Use optimized pipeline "span_score_threshold": 0.7, # Minimum span confidence "max_spans": 20, "top_k": 5, "chunk_size": 2000, # For large documents "max_chunks": 100 }
result = run_extraction_pipeline( report_text, config, source_id="report_123", neo4j_config=neo4j_config )
techniques = result["techniques"] # Dict of technique_id -> details bundle = result.get("bundle") # STIX 2.1 bundle if configured entities = result.get("entities") # Extracted entities
for tech_id, info in techniques.items(): print(f"{tech_id}: {info['name']}") print(f" Confidence: {info['confidence']}%") print(f" Evidence: {info['evidence']}")
## Architecture du Pipeline d'Extraction
Le pipeline d'extraction de Bandjacks utilise une architecture multi-agents pour extraire des renseignements structurés sur les menaces :
### Composants du Pipeline
Le pipeline d'extraction utilise 9 agents spécialisés en séquence :
#### 1. **EntityExtractionAgent** - Reconnaissance d'Entités
- Extrait les acteurs de menace, malwares, outils et campagnes
- S'exécute en premier pour fournir le contexte de l'extraction des techniques
- Utilise un amorçage par quelques exemples avec validation de schéma JSON
- Gère les documents découpés avec une extraction progressive par fenêtre
#### 2. **SpanFinderAgent** - Détection de Texte Comportemental
- Détecte les segments de texte contenant des comportements de menace à l'aide de 14 motifs regex spécifiques aux tactiques
- Identifie les ID de technique explicites (T1566.001) et les motifs comportementaux
- Score les segments par confiance avec un index de mots-clés
- Aucun appel LLM — pure correspondance de motifs pour la rapidité
#### 3. **BatchRetrieverAgent** - Récupération de Candidats
- Utilise la recherche vectorielle KNN d'OpenSearch pour trouver des techniques candidates par segment
- Déduplique les textes de segments identiques avant encodage pour éviter les embeddings redondants
- Renvoie les top-k candidats avec des scores de similarité pour chaque segment
#### 4. **Pré-filtre** - Réduction des Segments
- Limite les segments à `max_spans_per_technique` (par défaut 2) par technique candidate
- Conserve les segments les mieux notés par candidat pour maintenir la qualité des preuves
- Réduit les appels LLM du mappeur d'environ 46 % avec une perte minimale de techniques
#### 5. **DiscoveryAgent** - Découverte LLM (conditionnel)
- Déclenché lorsque la confiance du récupérateur est faible (moyenne < 0.7)
- Utilise le LLM pour découvrir des techniques manquées par la recherche vectorielle
- Un seul appel par lot pour tous les segments à faible confiance
#### 6. **BatchMapperAgent** - Mappage de Techniques (LLM)
- Traite par lots les segments en groupes allant jusqu'à 10 (`MAX_MAPPER_BATCH_SIZE`, par défaut abaissé de 25 en mai 2026 pour limiter la troncature du LLM cloud)
- Extrait TOUTES les techniques pertinentes par segment avec des scores de confiance
- Utilise la validation de schéma JSON pour une sortie structurée
#### 7. **EvidenceVerifierAgent** - Validation de Preuves
- Vérification basée sur des motifs des citations et des références de lignes
- Score la qualité des preuves sur une échelle de 40 à 100 points
- Aucun appel LLM — regex et correspondance textuelle
#### 8. **ConsolidatorAgent** - Consolidation des Preuves
- Fusionne les techniques en double trouvées dans plusieurs segments
- Agrège les preuves en utilisant la similarité de Jaccard (seuil >85 %)
- Produit une liste finale de techniques avec des scores de confiance consolidés
#### 9. **AttackFlowSynthesizer** - Génération de Séquences (LLM)
- Analyse les marqueurs temporels ("d'abord", "ensuite", "après")
- Infère les relations causales à partir du récit
- Crée des objets Attack Flow STIX avec des arêtes probabilistes
- Repli sur la modélisation de co-occurrence lorsque la séquence n'est pas claire
### Optimisations de Performances
- **Découpage intelligent** : Documents divisés en morceaux de 2 Ko avec chevauchement
- **Traitement par lots** : Le mappeur traite jusqu'à 25 segments par appel LLM
- **Traitement parallèle** : Les morceaux traités simultanément sur plusieurs threads de travail
- **Mise en cache des réponses** : Les réponses LLM mises en cache pour éviter les appels en double
- **Terminaison anticipée** : Les extractions à haute confiance sautent la vérification
- **TechniqueCache** : Toutes les techniques ATT&CK chargées au démarrage pour des recherches en O(1)
- **Pré-filtre** : Limite les segments par technique candidate avant le mappeur LLM (46 % d'appels en moins)
- **Embedding par lots** : Embeddings de techniques générés par lots (2 à 5 fois plus rapide)
- **Pool de connexions** : Connexions Neo4j/OpenSearch partagées entre les requêtes
- **Lots UNWIND** : Écritures Neo4j regroupées via UNWIND (30-40 requêtes → 6-7)
- **Préchauffage du modèle** : Modèle d'embedding chargé au démarrage pour éviter la latence de démarrage à froid
### Temps de Traitement
| Taille du Document | Temps de Traitement | Techniques Extraites |
|-------------------|---------------------|----------------------|
| Petit (<5 Ko) | 10-20 secondes | 5-10 techniques |
| Moyen (5-15 Ko) | 20-40 secondes | 10-15 techniques |
| Grand (>15 Ko) | 30-60 secondes | 15-25 techniques |
## Analyses de Co-occurrence
Bandjacks fournit des analyses pour comprendre les relations entre les techniques.
> **Remarque :** Les analyses nécessitent des données `AttackEpisode` et `AttackAction` dans Neo4j. Celles-ci sont créées lorsque :
> - Les rapports sont traités via le pipeline d'extraction
> - Les flux d'attaque sont construits via `/v1/flows/build`
> - Les bundles STIX avec des épisodes d'attaque sont ingérés
>
> Si aucun épisode n'existe, les analyses renverront des résultats vides.
### Co-occurrence Globale
Calculez quelles techniques apparaissent fréquemment ensemble dans tous les épisodes d'attaque :```python
# Via API
response = httpx.post(
"http://localhost:8000/v1/analytics/cooccurrence/global",
json={"min_support": 2, "min_episodes_per_pair": 2, "limit": 50}
)
for pair in response.json()["pairs"]:
print(f"{pair['name_a']} + {pair['name_b']}: NPMI={pair['npmi']:.3f}")
Calculez P(B|A) - étant donné que la technique A a été utilisée, quelle est la probabilité de la technique B :```python response = httpx.get( "http://localhost:8000/v1/analytics/cooccurrence/conditional", params={"technique_id": "attack-pattern--abc123", "limit": 25} )
### Regroupements de techniques
Identifiez les regroupements de techniques fréquemment co-occurrents (3-5 techniques) :```python
response = httpx.post(
"http://localhost:8000/v1/analytics/cooccurrence/bundles",
json={"min_support": 3, "min_size": 3, "max_size": 5}
)
Analyser les schémas techniques pour des acteurs de menace spécifiques :```python response = httpx.post( "http://localhost:8000/v1/analytics/cooccurrence/actor", json={"intrusion_set_id": "intrusion-set--xyz789", "min_support": 1} )
## Système de révision avec intervention humaine
Bandjacks inclut un système de révision complet pour valider les renseignements extraits :
### Interface de révision unifiée
Le système de révision présente tous les éléments extraits dans une seule interface :```typescript
// Review workflow
1. Upload/ingest report → Extraction pipeline runs
2. Navigate to /reports/{id}/review
3. Review extracted items across three tabs:
- Entities (threat actors, malware, tools)
- Techniques (ATT&CK mappings with evidence)
- Attack Flow (sequenced steps)
4. Take actions on each item:
- Approve: Accept as correct
- Reject: Mark as incorrect
- Edit: Modify details (name, confidence, etc.)
5. Submit all decisions atomically
response = httpx.post( f"http://localhost:8000/v1/reports/{report_id}/unified-review", json={ "decisions": [ { "item_id": "technique-0", "action": "approve", "confidence_adjustment": 5, "notes": "Confirmed via external CTI" }, { "item_id": "entity-malware-1", "action": "edit", "edited_value": { "name": "Corrected Malware Name", "confidence": 95 } } ], "global_notes": "Review completed by analyst-1" } )
### 4. Recherche de techniques
Recherchez des techniques ATT&CK en langage naturel :```python
# Vector search for similar techniques
response = httpx.post(
"http://localhost:8000/v1/search/ttx",
json={
"query": "ransomware that encrypts files and demands payment",
"top_k": 5
}
)
techniques = response.json()["results"]
for tech in techniques:
print(f"{tech['external_id']}: {tech['name']} (score: {tech['score']:.2f})")
Interrogez le graphe de connaissances pour les relations :```python
response = httpx.get( "http://localhost:8000/v1/graph/group/G0016/techniques" )
response = httpx.get( "http://localhost:8000/v1/defense/technique/T1566.001" )
### 6. Génération des modèles AttackFlow
Créez des modèles de co-occurrence qui montrent comment les acteurs de menace utilisent les techniques ensemble :```python
# Generate flow for a specific intrusion set (e.g., APT29)
response = httpx.post(
"http://localhost:8000/v1/flows/build",
json={
"intrusion_set_id": "intrusion-set--899ce53f-13a0-479b-a0e4-67d46e241542"
}
)
flow = response.json()
print(f"Generated flow '{flow['name']}' with {len(flow['steps'])} techniques")
print(f"Co-occurrence edges: {len(flow['edges'])}")
Génération en masse : Générer des flux pour tous les acteurs malveillants avec techniques :```bash
uv run python scripts/build_intrusion_flows_simple.py
AttackFlow models utilisent la **co-occurrence** plutôt qu'un ordre séquentiel, car les ensembles d'intrusion ne contiennent pas d'information de séquence inhérente. Les techniques sont reliées par :
- **Arêtes intra-tactique** : entre techniques de la même tactique de kill chain
- **Arêtes inter-tactique** : entre techniques de tactiques adjacentes
- **Motifs hub-and-spoke** : pour les grands ensembles de techniques afin d'éviter une explosion d'arêtes
Consultez le [Guide de génération AttackFlow](https://github.com/blevene/bandjacks/blob/main/docs/ATTACKFLOW_GENERATION.md) pour une utilisation détaillée.
## Formats d'entrée pris en charge
Le pipeline d'extraction prend en charge plusieurs formats d'entrée :
- **Texte brut** - Contenu textuel direct
- **Markdown** - Documents markdown formatés
- **PDF** - Via l'extraction pdfplumber
- **HTML** - Via l'analyse BeautifulSoup
- **JSON** - Extraction de données structurées
### Extraire à partir de texte brut```python
# Direct text extraction
plaintext_report = """
The threat actors used spearphishing emails with malicious attachments.
After gaining access, they deployed Mimikatz to harvest credentials and
used RDP for lateral movement across the network.
"""
result = asyncio.run(run_agentic_v2_async(plaintext_report, {
"cache_llm_responses": True,
"single_pass_threshold": 500
}))
markdown_report = """
| Tool | Purpose |
|---|---|
| Mimikatz | Credential dumping |
| PsExec | Remote execution |
| Cobalt Strike | C2 communications |
| """ |
result = run_extraction_pipeline(markdown_report, { "use_optimized_extractor": True, "span_score_threshold": 0.7 }, source_id="markdown_report")
### Extrait d'un PDF```python
import pdfplumber
from bandjacks.llm.extraction_pipeline import run_extraction_pipeline
# Read PDF with pdfplumber (recommended)
with pdfplumber.open("threat_report.pdf") as pdf:
text = ""
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
# Extract techniques using extraction pipeline
result = run_extraction_pipeline(text, {
"use_optimized_extractor": True,
"span_score_threshold": 0.7,
"chunk_size": 2000
}, source_id="threat_report")
print(f"Found {len(result['techniques'])} techniques")
from pathlib import Path import json
reports_dir = Path("./reports") results = []
for pdf_file in reports_dir.glob("*.pdf"): # Extract text and techniques # ... (see above)
results.append({
"file": pdf_file.name,
"techniques": list(result["techniques"].keys()),
"count": len(result["techniques"])
})
with open("extraction_summary.json", "w") as f: json.dump(results, f, indent=2)
### Construction de flux d'attaque```python
# Generate attack flow from extracted techniques
response = httpx.post(
"http://localhost:8000/v1/flows/build",
json={
"source_id": "report-123",
"technique_ids": ["T1566.001", "T1059.001", "T1003.001"]
}
)
flow = response.json()
print(f"Generated flow with {len(flow['steps'])} steps")
Exécutez la suite de tests pour vérifier votre installation :```bash
uv run pytest
python tests/test_optimized_extraction.py
python tests/test_graph_upsert.py
python tests/test_bundle_validation.py
cd ui && npm test
## Points d'accès API
### Points d'accès principaux
- `POST /v1/stix/load/attack` - Charger les données MITRE ATT&CK
- `POST /v1/reports/ingest` - Ingestion synchrone de rapports (<5 Ko)
- `POST /v1/reports/ingest_async` - Ingestion asynchrone de rapports (>5 Ko)
- `POST /v1/reports/ingest/upload` - Télécharger des fichiers PDF/TXT
- `GET /v1/reports/jobs/{id}/status` - Vérifier l'état d'un traitement
- `POST /v1/reports/{id}/unified-review` - Soumettre des décisions de révision
- `POST /v1/search/ttx` - Rechercher des techniques
- `GET /v1/graph/technique/{id}` - Obtenir les détails d'une technique
### Flux d'attaques
- `POST /v1/flows/build` - Générer des modèles de cooccurrence AttackFlow
- `GET /v1/flows/{flow_id}` - Récupérer les détails d'un AttackFlow spécifique
- `POST /v1/flows/search` - Rechercher des flux d'attaque similaires
- `GET /v1/flows/dump` - Export en masse des flux avec pagination et filtrage
### Analytiques
- `GET /v1/analytics/cooccurrence/global` - Métriques globales de cooccurrence
- `GET /v1/analytics/cooccurrence/conditional` - Probabilités conditionnelles
- `GET /v1/analytics/cooccurrence/bundles` - Lots de techniques
- `GET /v1/analytics/cooccurrence/actor` - Schémas propres à un acteur
- `GET /v1/coverage/gaps` - Lacunes de couverture des techniques
### Défense & Détection
- `GET /v1/defense/technique/{id}` - Obtenir des recommandations défensives
- `GET /v1/detections/technique/{id}` - Stratégies de détection
- `POST /v1/sigma/validate` - Valider des règles Sigma
### Surveillance
- `GET /health` - Vérification basique de l'état
- `GET /health/live` - Sonde de vivacité Kubernetes
- `GET /health/ready` - Sonde de disponibilité Kubernetes
- `GET /health/components/{component}` - État d'un composant individuel
- `GET /v1/costs/stats` - Suivi des coûts LLM (agrégat quotidien par modèle)
- `GET /v1/cache/stats` - Obtenir les statistiques du cache LLM
- `POST /v1/cache/clear` - Vider le cache LLM
- `GET /v1/compliance/report` - Métriques de conformité
- `GET /v1/drift/status` - État de la détection de dérive
- `GET /v1/ml-metrics/performance` - Métriques du modèle ML
### Acteurs & Provenance
- `GET /v1/actors` - Lister les acteurs de menace
- `GET /v1/actors/{id}` - Obtenir les détails d'un acteur
- `GET /v1/provenance/{object_id}` - Provenance d'un objet
- `GET /v1/provenance/{object_id}/lineage` - Chaîne de lignée complète
- `GET /v1/provenance/{object_id}/evidence` - Extraits de preuve
### Fonctionnalités exclusives à l'API (ni UI, ni CLI)
Ces points d'accès sont pleinement fonctionnels mais accessibles uniquement via l'API REST (pas de pages frontend ni de commandes CLI) :
#### Simulation de chemins d'attaque
- `POST /v1/simulation/paths` - Simuler des chemins d'attaque à partir d'une technique/groupe de départ
- `POST /v1/simulation/predict` - Prédire les techniques suivantes probables compte tenu de l'état actuel
- `POST /v1/simulation/whatif` - Analyse « what-if » pour des scénarios défensifs
- `POST /v1/simulation/scenario` - Simuler à partir d'ensembles de groupes/logiciels/techniques
- `GET /v1/simulation/statistics/{technique_id}` - Statistiques d'utilisation d'une technique
- `GET /v1/simulation/groups/{group_id}/patterns` - Schémas d'attaque d'un groupe
- `POST /v1/simulation/compare` - Comparer plusieurs chemins d'attaque
#### Politique MDP & Déploiement
- `POST /v1/simulate/rollout` - Simulation de déploiement PTG
- `POST /v1/simulate/mdp` - Calculer la politique de défense optimale MDP
- `GET /v1/simulate/models` - Lister les modèles PTG disponibles
#### Détection de dérive & Surveillance
- `GET /v1/drift/status` - État actuel de la dérive sur toutes les métriques
- `POST /v1/drift/analyze` - Exécuter une analyse de dérive avec des seuils personnalisés
- `GET /v1/drift/alerts` - Obtenir les alertes actives de dérive
- `POST /v1/drift/alerts/{alert_id}/acknowledge` - Accuser réception d'une alerte
- `GET /v1/drift/metrics/{metric_name}` - Obtenir une métrique de dérive spécifique
#### Suivi des métriques ML
- `POST /v1/ml-metrics/prediction` - Enregistrer une prédiction du modèle pour suivi
- `POST /v1/ml-metrics/review` - Enregistrer les métriques de décision de révision
- `POST /v1/ml-metrics/coverage-gap` - Enregistrer un écart de couverture
- `GET /v1/ml-metrics/performance` - Obtenir les métriques de performance du modèle
- `GET /v1/ml-metrics/dashboard` - Exporter les métriques du tableau de bord
#### Notifications
- `GET /v1/notifications/history` - Obtenir l'historique des notifications
- `POST /v1/notifications/clear-history` - Effacer l'historique des notifications
- `GET /v1/notifications/config` - Obtenir la configuration des notifications
- `POST /v1/notifications/test` - Envoyer une notification de test
#### Gestion des mises à jour de vecteurs
- `GET /v1/vectors/status` - État du système de mise à jour des vecteurs
- `GET /v1/vectors/metrics` - Métriques détaillées de mise à jour des vecteurs
- `POST /v1/vectors/update` - Déclencher manuellement une mise à jour des vecteurs
- `POST /v1/vectors/process-batch` - Forcer le traitement par lots
- `DELETE /v1/vectors/queue` - Vider la file d'attente des mises à jour en attente
- `GET /v1/vectors/health` - Vérification de l'état du système de vecteurs
#### Liste d'ignorance des entités
- `GET /v1/ignorelist` - Obtenir l'état actuel de la liste d'ignorance
- `POST /v1/ignorelist/add` - Ajouter une entité à la liste d'ignorance
- `DELETE /v1/ignorelist/remove` - Supprimer une entité de la liste d'ignorance
- `POST /v1/ignorelist/reload` - Recharger la liste d'ignorance depuis le disque
#### Révision des motifs candidats
- `GET /v1/review/candidates` - Lister les motifs d'attaque candidats
- `POST /v1/review/candidates` - Créer un motif candidat
- `GET /v1/review/candidates/{id}` - Obtenir les détails d'un candidat
- `POST /v1/review/candidates/{id}/approve` - Approuver un candidat
- `POST /v1/review/candidates/{id}/reject` - Rejeter un candidat
- `GET /v1/review/candidates/{id}/similar` - Trouver des motifs similaires
- `GET /v1/review/candidates/stats/summary` - Statistiques des candidats
### Documentation complète de l'API
Accédez à la documentation complète de l'API à :
- Swagger UI : http://localhost:8000/docs
- ReDoc : http://localhost:8000/redoc
- OpenAPI JSON : http://localhost:8000/openapi.json
## Architecture
### Structure du projet```
bandjacks/
├── bandjacks/
│ ├── analysis/ # Graph analysis & interdiction
│ │ ├── graph_analyzer.py
│ │ └── interdiction.py
│ ├── analytics/ # Co-occurrence & clustering
│ │ ├── clustering.py
│ │ ├── cooccurrence.py
│ │ └── detection_bundles.py
│ ├── cli/ # Command-line interface
│ │ ├── main.py # CLI entry point
│ │ ├── batch_extract.py
│ │ ├── formatters.py
│ │ └── workflows.py
│ ├── config/ # Configuration files
│ │ └── entity_ignorelist.yaml
│ ├── core/ # Core utilities
│ │ ├── cache.py # Redis caching
│ │ ├── connection_pool.py
│ │ └── query_optimizer.py
│ ├── llm/ # Extraction pipeline
│ │ ├── extraction_pipeline.py
│ │ ├── agents_v2.py # Core extraction agents
│ │ ├── chunked_extractor.py
│ │ ├── optimized_chunked_extractor.py
│ │ ├── entity_extractor.py
│ │ ├── flow_builder.py
│ │ ├── cache.py # LLM response caching
│ │ └── experimental/ # Experimental features
│ ├── loaders/ # Data loading & indexing
│ │ ├── attack_catalog.py
│ │ ├── attack_upsert.py
│ │ ├── opensearch_index.py
│ │ ├── hybrid_search.py
│ │ └── sigma_loader.py
│ ├── monitoring/ # Metrics & monitoring
│ │ ├── compliance_metrics.py
│ │ ├── defense_metrics.py
│ │ ├── drift_detector.py
│ │ └── ml_metrics.py
│ ├── services/ # API & services
│ │ ├── api/ # FastAPI application
│ │ │ ├── main.py
│ │ │ ├── routes/ # API route handlers
│ │ │ └── middleware/
│ │ ├── technique_cache.py
│ │ └── actor_cache.py
│ ├── simulation/ # Attack simulation
│ │ ├── attack_simulator.py
│ │ ├── mdp_solver.py
│ │ └── ptg_rollout.py
│ └── store/ # Data stores
│ ├── report_store.py
│ ├── candidate_store.py
│ └── review_store.py
├── ui/ # Next.js frontend
│ ├── app/ # App Router pages
│ │ ├── reports/ # Report management
│ │ ├── analytics/ # Analytics dashboards
│ │ └── health/ # Health monitoring
│ ├── components/ # React components
│ └── hooks/ # Custom React hooks
├── tests/ # Test suite
├── samples/ # Sample reports
├── scripts/ # Utility scripts
└── docs/ # Documentation
Pipeline d'extraction (bandjacks/llm/)
extraction_pipeline.py - Orchestrateur d'extraction principalchunked_extractor.py - Traitement par lots standardoptimized_chunked_extractor.py - Traitement optimisé avancéagents_v2.py - Agents d'extraction principaux (SpanFinder, Mapper, Consolidator)entity_extractor.py - Agent de reconnaissance d'entitésflow_builder.py - Génération de flux d'attaquememory.py - Mémoire de travail partagéecache.py - Mise en cache des réponses LLMCouche de données (bandjacks/loaders/)
Couche API (bandjacks/services/api/)
Le système prend en charge les LLM cloud et toute API locale compatible OpenAI :```bash
LOCAL_LLM_API_BASE=http://192.168.1.100:8080/v1 LOCAL_LLM_MODEL=mistral-nemo LOCAL_LLM_API_KEY=no-key # optional — most local servers don't require a key
PRIMARY_LLM=gemini # "gemini" (default) or "openai" GOOGLE_API_KEY=your-key # Gemini OPENAI_API_KEY=your-key # OpenAI (used as fallback when Gemini is primary)
**Prioritée du fournisseur :** API locale > Gemini > OpenAI > proxy LiteLLM.
Lorsqu'un serveur local est configuré, les fournisseurs cloud sont automatiquement ajoutés comme solutions de repli.
#### Exemples courants de serveurs locaux
| Serveur | `LOCAL_LLM_API_BASE` | `LOCAL_LLM_MODEL` |
|--------|---------------------|-------------------|
| vLLM | `http://host:8000/v1` | `mistralai/Mistral-Nemo-Instruct-2407` |
| llama.cpp | `http://host:8080/v1` | `mistral-nemo` |
| Ollama | `http://host:11434/v1` | `mistral-nemo` |
| LM Studio | `http://host:1234/v1` | `mistral-nemo` |
| LocalAI | `http://host:8080/v1` | `mistral-nemo` |
### Configuration de l'extraction
Le système utilise un pipeline asynchrone unique et haute performance avec des options configurables :```python
{
"cache_llm_responses": True, # Enable LLM caching (default: True)
"single_pass_threshold": 500, # Max words for single-pass (default: 500)
"early_termination_confidence": 90, # Skip verification above this (default: 90)
"disable_discovery": False, # Disable LLM discovery agent
"max_spans": 20, # Maximum spans to process
"span_score_threshold": 0.7, # Minimum span quality
"top_k": 5, # Candidates per span
# Cost optimization options
"max_spans_per_technique": 2, # Pre-filter: max spans per candidate technique (0=disable, default=2)
"enable_span_dedup": False, # Text-based span dedup before mapping (default=False)
}
Le pipeline d'extraction suit les coûts LLM via litellm.completion_cost() avec des métriques par rapport et un point de terminaison agrégé quotidien.
Contrôles des coûts :
Surveillance :```bash
curl http://localhost:8000/v1/costs/stats
curl http://localhost:8000/v1/reports/{id} # -> extraction.metrics.cost_usd
### Seuils de confiance
Contrôlez la qualité d'extraction:```python
{
"confidence_threshold": 50.0, # Minimum confidence (0-100)
"auto_ingest": True # Auto-add high-confidence results
}
curl http://localhost:8000/health
curl http://localhost:8000/health/live
curl http://localhost:8000/health/ready
curl http://localhost:8000/health/components/neo4j curl http://localhost:8000/health/components/opensearch curl http://localhost:8000/health/components/redis curl http://localhost:8000/health/components/caches curl http://localhost:8000/health/components/system
### Exemple de réponse de santé```json
{
"status": "healthy",
"timestamp": "2025-01-28T17:43:30.184036Z",
"version": "1.0.0",
"components": {
"neo4j": {
"status": "healthy",
"latency_ms": 5
},
"opensearch": {
"status": "degraded",
"cluster_status": "yellow",
"indices": {
"attack_nodes": false,
"bandjacks_reports": true
}
},
"redis": {
"status": "healthy",
"latency_ms": 2,
"memory_mb": 1.69
},
"caches": {
"status": "healthy",
"technique_cache": {
"count": 993,
"loaded": true
},
"actor_cache": {
"count": 145,
"loaded": true
}
},
"system": {
"status": "healthy",
"memory": {
"available_gb": 8.84,
"percent_used": 72.4
},
"disk": {
"available_gb": 353.11,
"percent_used": 2.9
},
"cpu": {
"percent_used": 7.7
}
}
}
}
Pour les déploiements Kubernetes, configurez les sondes comme suit :```yaml livenessProbe: httpGet: path: /health/live port: 8000 initialDelaySeconds: 30 periodSeconds: 10
readinessProbe: httpGet: path: /health/ready port: 8000 initialDelaySeconds: 45 periodSeconds: 5
## Optimisation des performances
### Mise en cache
Le système inclut une mise en cache automatique des réponses LLM pour des performances améliorées :```python
# Check cache statistics
response = httpx.get("http://localhost:8000/v1/cache/stats")
stats = response.json()
print(f"Cache hit rate: {stats['hit_rate']}")
# Clear cache if needed
httpx.post("http://localhost:8000/v1/cache/clear")
Choisissez un profil en fonction de vos besoins :```python
fast_config = { "single_pass_threshold": 1000, "max_spans": 5, "skip_verification": True, "top_k": 3 }
balanced_config = { "single_pass_threshold": 500, "max_spans": 10, "early_termination_confidence": 90, "top_k": 5 }
quality_config = { "single_pass_threshold": 200, "max_spans": 20, "disable_discovery": False, "min_quotes": 3, "top_k": 10 }
## Sécurité
### Validation des entrées
- **Prévention des injections Cypher** : Tous les points de terminaison de requêtes de graphe valident les paramètres `relationship_types` fournis par l'utilisateur par rapport à une liste blanche de types de relations connus (USES, MITIGATES, HAS_TACTIC, etc.) ainsi qu'un motif regex strict (`^[A-Z][A-Z0-9_]*$`). Une entrée invalide retourne 400 avant la construction de la requête.
- **Validation par schéma JSON** : Les réponses LLM sont validées par rapport à des schémas JSON pour empêcher les données malformées d'entrer dans le pipeline.
- **Validation ADM** : Tout contenu STIX doit passer la validation du modèle de données ATT&CK avant ingestion.
### Authentification et autorisation
- **Authentification JWT** : Middleware optionnel pour l'authentification API (`JWTAuthMiddleware`)
- **Limitation de débit** : Limitation de débit par point de terminaison avec des seuils configurables
- **CORS** : Partage de ressources entre origines multiples configurable
## Fonctionnalités avancées
### Suivi de provenance
Chaque entité extraite inclut la provenance complète :```python
# Get provenance for an object
response = httpx.get(
"http://localhost:8000/v1/provenance/attack-pattern--abc123"
)
Le système inclut une file d'attente de révision pour améliorer l'extraction :```python
response = httpx.get("http://localhost:8000/v1/review_queue/next")
response = httpx.post( "http://localhost:8000/v1/feedback/extraction", json={ "extraction_id": "ext-123", "correct": True, "corrections": [] } )
### Analyse de la couverture
Analysez votre couverture de renseignement sur les menaces :```python
# Get coverage analysis
response = httpx.get("http://localhost:8000/v1/analytics/coverage")
coverage = response.json()
print(f"Summary: {coverage['summary']}")
for tactic in coverage['tactics']:
print(f" {tactic['tactic']}: {tactic['coverage_percentage']}%")
Note : La couverture des plateformes (
_analyze_platforms_coverage) renvoie actuellement des données provisoires. La couverture des tactiques et des groupes utilise de vraies requêtes Neo4j.
from bandjacks.simulation.attack_simulator import AttackSimulator from bandjacks.simulation.mdp_solver import MDPSolver
## État des fonctionnalités
Cette section fournit une transparence sur le statut d'implémentation de diverses fonctionnalités :
### Entièrement fonctionnel ✅
- **Pipeline d'extraction de rapports** - L'extraction de techniques basée sur LLM fonctionne de bout en bout
- **Chargement MITRE ATT&CK** - Charge les données ATT&CK enterprise/mobile/ICS dans Neo4j
- **Recherche vectorielle** - Recherche sémantique basée sur OpenSearch pour les techniques
- **Système de révision** - Workflow de révision humain-dans-la-boucle via API et UI
- **Surveillance de santé** - Vérifications de santé des composants et sondes Kubernetes
- **Commandes CLI Requête/Admin** - Recherche, parcours de graphe, gestion de cache
- **Génération de flux d'attaque** - Construction de flux basée sur la co-occurrence pour les ensembles d'intrusion
- **Simulation d'attaque** - Simulation de chemin basée sur MDP via `/simulation/*` et `/simulate/*`
- **Rapports de couverture** - Rapports JSON pour les vues exécutive, technique, tactique, opérationnelle
### Fonctionnel avec dépendances de données ⚠️
- **Analyses de co-occurrence** - Nécessite des nœuds `AttackEpisode` issus du traitement des rapports
- **Analyses d'acteurs** - Nécessite des épisodes attribués à des ensembles d'intrusion
- **Paquets de techniques** - Nécessite suffisamment de données d'épisodes pour l'extraction de motifs
- **Commandes CLI d'analyses** - Fonctionnent mais renvoient vide si aucun épisode n'existe
### API uniquement (pas d'UI/CLI) 🔌
Ce sont des fonctionnalités entièrement implémentées accessibles uniquement via l'API REST :
- **Simulation de chemin d'attaque** - Routes `/simulation/*` pour la prédiction de chemin et l'analyse de scénarios
- **Solveur de politique MDP** - `/simulate/mdp` pour le calcul de politique de défense optimale
- **Détection de dérive** - Routes `/drift/*` pour la surveillance de la dérive de la qualité des données
- **Métriques ML** - `/ml-metrics/*` pour le suivi des performances du modèle dans le temps
- **Gestion des vecteurs** - `/vectors/*` pour la gestion des embeddings vectoriels
- **Liste d'ignorance d'entités** - `/ignorelist/*` pour le filtrage des entités faussement positives
- **Motifs candidats** - `/review/candidates/*` pour les candidats de techniques nouvelles
- **Notifications** - `/notifications/*` pour la configuration et l'historique des alertes
- **Provenance** - `/provenance/*` pour le suivi de la lignée d'extraction
- **Conformité** - `/compliance/*` pour le reporting des métriques de conformité
### Expérimental (dans `llm/experimental/`) 🧪
- **PTG (Graphe de menace probabiliste)** - Logique centrale implémentée, tests limités
- **Intégration Judge** - Validation de séquence basée sur LLM
- **Simulateur de flux d'attaque** - Moteur de simulation basé sur les flux
- **Extracteur de séquences** - Extraire des séquences à partir de flux
### Supprimé/Nettoyé 🗑️
Les fonctionnalités fictives suivantes ont été supprimées de l'API :
- ~~Analyse de couverture de plateforme~~ - Renvoyait des données fictives codées en dur
- ~~Analyse de tendances~~ - Renvoyait des données synthétiques aléatoires
- ~~Export de rapport CSV/PDF~~ - Renvoyait 501 ; désormais uniquement JSON
- ~~Inférence de séquence Gemini~~ - Était un stub 501 ; utilisez `/sequence/propose` à la place
### Matrice de connectivité
| Domaine de fonctionnalité | Interface utilisateur frontend | CLI | API REST |
|--------------|-------------|-----|----------|
| Gestion des rapports | ✅ | ✅ | ✅ |
| Workflow de révision | ✅ | ✅ | ✅ |
| Recherche (TTX) | ✅ | ✅ | ✅ |
| Analyses de co-occurrence | ✅ | ✅ | ✅ |
| Analyses de couverture | ✅ | - | ✅ |
| Surveillance de santé | ✅ | - | ✅ |
| Détections/Sigma | ✅ | - | ✅ |
| Flux d'attaque | ✅ | - | ✅ |
| Superposition de défense | ✅ | - | ✅ |
| Séquences/PTG | ✅ | - | ✅ |
| Acteurs | ✅ | - | ✅ |
| Simulation d'attaque | - | - | ✅ |
| Détection de dérive | - | - | ✅ |
| Métriques ML | - | - | ✅ |
| Gestion des vecteurs | - | - | ✅ |
| Liste d'ignorance d'entités | - | - | ✅ |
| Motifs candidats | - | - | ✅ |
| Notifications | - | - | ✅ |
| Provenance | - | - | ✅ |
| Conformité | - | - | ✅ |
### Pages du frontend
| Page | Statut | Remarques |
|------|--------|-------|
| `/reports` | ✅ Fonctionne | Lister, créer, visualiser les rapports |
| `/reports/[id]/review` | ✅ Fonctionne | Workflow de révision complet |
| `/analytics/cooccurrence` | ⚠️ Dépendant des données | Affiche les KPI si des épisodes existent |
| `/analytics/cooccurrence/pairs` | ⚠️ Dépendant des données | Appelle l'API réelle |
| `/analytics/cooccurrence/bundles` | ⚠️ Dépendant des données | Appelle l'API réelle |
| `/analytics/cooccurrence/actors` | ⚠️ Dépendant des données | Appelle l'API réelle |
| `/health` | ✅ Fonctionne | Statut de santé en temps réel |
## Dépannage
### Problèmes courants
1. **Échec de connexion à OpenSearch**
- Assurez-vous qu'OpenSearch est en cours d'exécution : `curl http://localhost:9200`
- Vérifiez que l'index existe : `curl http://localhost:9200/bandjacks_attack_nodes-v1`
2. **Échec de connexion à Neo4j**
- Vérifiez que Neo4j est en cours d'exécution : `neo4j status`
- Vérifiez que `NEO4J_PASSWORD` est défini dans le fichier `.env`
- Assurez-vous que le mot de passe correspond à votre instance Neo4j
- Si vous voyez "NEO4J_PASSWORD environment variable is required", vous devez le définir dans votre fichier `.env`
3. **Faible rappel d'extraction**
- Assurez-vous d'utiliser la méthode `agentic_v2`
- Vérifiez que la clé API LLM est valide
- Vérifiez que le nom du modèle est correct (gemini-flash-latest)
4. **Erreurs de délai d'attente**
- Augmentez les paramètres de délai d'attente pour les documents volumineux
- Envisagez de diviser les très gros rapports en morceaux
5. **Le frontend ne se connecte pas à l'API**
- Assurez-vous que l'API est en cours d'exécution sur le port 8000
- Vérifiez les paramètres CORS dans la configuration de l'API
### Mode débogage
Activer la journalisation détaillée :```python
import logging
logging.basicConfig(level=logging.DEBUG)
# Run extraction with debug output
result = run_agentic_v2(text, config)
uv run pytest tests/unit
uv run pytest tests/integration
uv run pytest tests/test_agentic_v2.py::test_extraction
uv run pytest --cov=bandjacks
cd ui && npm test cd ui && npm run test:coverage
### Contribuer
1. Forkez le dépôt
2. Créez une branche de fonctionnalité
3. Apportez vos modifications
4. Exécutez les tests : `uv run pytest`
5. Exécutez le linting : `uv run ruff check`
6. Soumettez une demande d'extraction (pull request)
### Qualité du code```bash
# Format code
uv run ruff format
# Check linting
uv run ruff check
# Type checking
uv run mypy bandjacks
[Votre licence ici]
Frontend (ui/)
| Option | Défaut | Effet | Impact sur la qualité |
|---|
MAX_MAPPER_BATCH_SIZE (variable d'environnement) | 10 | Spans par appel LLM mapper (réduit de 25 en 2026-05 ; les réponses cloud plafonnent à ~800 jetons, ~12 % des lots plus grands renvoyaient du JSON tronqué) | Aucun |
max_spans_per_technique (config) | 2 | Pré-filtre : meilleurs N spans par technique candidate | ~19 % de techniques en moins, confiance plus élevée |
enable_span_dedup (config) | false | Supprimer le texte de span en double avant le mappage | ~15 % de techniques en moins |