LLM Security

Quels logs collecter sur un système LLM pour un SOC

Logs LLM pour SOC : schéma JSON 50 champs, format OCSF, MITRE ATLAS tagging, intégration Splunk/Sentinel, règles détection. Volume, rétention, RGPD.

Naim Aouaichia
14 min de lecture
  • SOC
  • logs
  • SIEM
  • OCSF
  • threat hunting

Pour qu'un SOC (Security Operations Center) surveille efficacement un système LLM en 2026, la collecte de logs doit être structurée selon un schéma précis (50 champs en 8 sections), formaté en standard OCSF (Open Cybersecurity Schema Framework) pour intégration SIEM native, taggé avec MITRE ATLAS techniques et OWASP LLM classes, et intégré aux stacks Splunk / Sentinel / Elastic via OTel Collector central. Cet article documente le schéma de log complet (identification, acteur, source, modèle, contenu, métriques, sécurité, conformité), format OCSF avec exemples JSON, top 10 règles de détection Sigma/SPL/KQL prêtes à déployer, stratégie d'intégration par SIEM, gestion conformité RGPD (PII redaction, pseudonymisation, sampling, rétention), modèle d'organisation SOC 3 niveaux avec KPIs (MTTD < 15 min, MTTR < 1h HIGH, TPR > 50%, coverage ATLAS > 60%). Cible : SOC analysts montant en compétence LLM, ingénieurs SIEM préparant intégration, RSSI structurant la surveillance LLM enterprise.

Pour la couche logging applicative : logging et observabilité d'un système LLM en production. Pour la détection comportementale : détecter un abus de LLM en temps réel.

Schéma de log, 50 champs en 8 sections

Vue d'ensemble

{
  // Section 1, Identification (5)
  "event_id": "evt_018f...",
  "ts": "2026-05-01T10:23:45.123Z",
  "request_id": "req_abc123",
  "trace_id": "0af7651916cd43dd8448eb211c80319c",
  "parent_span_id": "b7ad6b7169203331",
  
  // Section 2, Acteur (5)
  "user_id_hash": "sha256_a1b2c3...",
  "user_role": "customer",
  "org_id": "org_zeroday",
  "session_id": "sess_xyz789",
  "source_ip_hash": "sha256_d4e5f6...",
  
  // Section 3, Source (5)
  "app_name": "zerodaysupport-chatbot",
  "app_version": "2.4.1",
  "environment": "production",
  "region": "eu-west-3",
  "hostname": "chatbot-prod-7f9b",
  
  // Section 4, Modèle (6)
  "model": {
    "provider": "openai",
    "name": "gpt-4o",
    "version": "2026-04-15",
    "temperature": 0.3,
    "max_tokens": 1500,
    "finish_reason": "stop"
  },
  
  // Section 5, Contenu (8)
  "content": {
    "prompt_redacted": "Bonjour, [EMAIL_REDACTED] commande #1234...",
    "response_redacted": "Votre commande sera livrée le...",
    "prompt_tokens": 245,
    "completion_tokens": 187,
    "total_tokens": 432,
    "rag_doc_ids": ["doc_42", "doc_91"],
    "tool_calls": [
      {"name": "search_order", "args_hash": "sha256_g7h8i9..."}
    ],
    "message_history_length": 3
  },
  
  // Section 6, Métriques (6)
  "metrics": {
    "duration_ms": 1850,
    "latency_breakdown_ms": {
      "guardrail_input": 78,
      "rag_retrieval": 145,
      "llm_call": 1320,
      "tool_exec": 250,
      "guardrail_output": 32
    },
    "cost_usd": 0.018,
    "cache_hit": false,
    "retry_count": 0,
    "queue_time_ms": 25
  },
  
  // Section 7, Sécurité (8)
  "security": {
    "guardrail_input_score": 0.05,
    "guardrail_input_action": "allow",
    "guardrail_output_alerts": [],
    "anomaly_flags": [],
    "rate_limit_dimension_hit": null,
    "mitre_atlas_techniques": [],
    "owasp_llm_classes": [],
    "severity": "informational"
  },
  
  // Section 8, Conformité (7)
  "compliance": {
    "data_classification": "internal",
    "retention_class": "security_1y",
    "deletion_eligible_after": "2027-05-01T10:23:45Z",
    "gdpr_lawful_basis": "legitimate_interest",
    "dpia_reference": "DPIA-2026-014",
    "audit_trail_id": "audit_chatbot_v2",
    "schema_version": "1.3"
  }
}

Détail par section

Section 1, Identification : permet corrélation cross-system. request_id lie tous les events d'une requête utilisateur. trace_id (W3C Trace Context) lie distributed tracing.

Section 2, Acteur : user_id_hash permet agrégation sans re-identification. user_role (customer / admin / employee / api) permet règles de détection role-based.

Section 3, Source : crucial pour distinguer environnements et investigations multi-régions.

Section 4, Modèle : permet détecter changements modèle (qualité régression) et bascule premium (abus DoW).

Section 5, Contenu : prompt_redacted après PII redaction. tool_calls avec args_hash plutôt que args en clair (réduit volume + protection PII). rag_doc_ids permet retrouver les documents impactés en investigation.

Section 6, Métriques : latency_breakdown essentiel pour identifier hotspots. cost_usd first-class metric anti-DoW.

Section 7, Sécurité : mitre_atlas_techniques et owasp_llm_classes permettent corrélation avec menaces classiques au SOC. severity aligné OCSF (informational / low / medium / high / critical).

Section 8, Conformité : gdpr_lawful_basis (consent / contract / legal_obligation / vital_interest / public_interest / legitimate_interest). dpia_reference pour traçabilité.

Format OCSF (Open Cybersecurity Schema Framework)

Pourquoi OCSF en 2026

OCSF v1.x publié 2022 par AWS, Splunk, IBM, Cloudflare et autres. Adopté par Splunk, Microsoft Sentinel, Elastic Security, Sumo Logic, IBM QRadar.

Bénéfices vs JSON ad hoc :

  • Vocabulaire normalisé cross-vendor
  • Ingestion native SIEM sans transformation custom
  • Corrélation cross-source (logs LLM + auth + network + endpoint)
  • Extensible pour custom attributes

Mapping LLM event vers OCSF

{
  "metadata": {
    "version": "1.2.0",
    "product": {
      "vendor_name": "ZerodaySupport",
      "name": "ChatBot SAV",
      "version": "2.4.1"
    },
    "log_name": "llm_application_event",
    "log_version": "1.3"
  },
  
  "category_uid": 7,
  "category_name": "Application Activity",
  "class_uid": 7000,
  "class_name": "AI Application Activity",
  "type_uid": 700001,
  "type_name": "AI Inference",
  
  "time": 1746104625123,
  "severity_id": 1,
  "severity": "Informational",
  
  "actor": {
    "user": {
      "uid": "sha256_a1b2c3",
      "type": "User",
      "type_id": 1
    },
    "session": {
      "uid": "sess_xyz789"
    }
  },
  
  "src_endpoint": {
    "ip": "203.0.113.42",
    "hostname_hash": "sha256_d4e5f6"
  },
  
  "device": {
    "name": "chatbot-prod-7f9b",
    "region": "eu-west-3"
  },
  
  // Custom attributes for AI/LLM
  "gen_ai": {
    "system": "openai",
    "request": {
      "model": "gpt-4o",
      "temperature": 0.3,
      "max_tokens": 1500
    },
    "response": {
      "model": "gpt-4o-2026-04-15",
      "finish_reasons": ["stop"]
    },
    "usage": {
      "prompt_tokens": 245,
      "completion_tokens": 187,
      "total_tokens": 432
    },
    "content": {
      "prompt_redacted": "Bonjour, [EMAIL_REDACTED] commande #1234...",
      "response_redacted": "Votre commande sera livrée..."
    },
    "tools": [
      {"name": "search_order", "args_hash": "sha256_g7h8i9"}
    ],
    "guardrails": {
      "input_score": 0.05,
      "input_action": "allow",
      "output_alerts": []
    },
    "cost": {
      "amount": 0.018,
      "currency": "EUR"
    }
  },
  
  // Pour findings sécurité (events anormaux)
  "finding": {
    "title": null,
    "uid": null,
    "atlas_techniques": [],
    "owasp_llm_classes": []
  },
  
  // Compliance
  "compliance": {
    "data_classification": "internal",
    "retention_class": "security_1y",
    "deletion_eligible_after": 1777640625000
  }
}

Pour event sécurité (finding)

{
  "metadata": { "version": "1.2.0", "product": {...} },
  "category_uid": 2,
  "category_name": "Findings",
  "class_uid": 2007,
  "class_name": "Detection Finding",
  "type_uid": 200701,
  "type_name": "AI Behavioral Anomaly Detected",
  
  "time": 1746104825000,
  "severity_id": 4,
  "severity": "High",
  
  "actor": { "user": { "uid": "sha256_a1b2c3" } },
  
  "finding": {
    "title": "DoW Suspected, User cost > 3× baseline",
    "uid": "finding_018g4h",
    "details": "User accumulated 45 € in 1 hour vs baseline 4.5 €/h",
    "types": ["Cost Anomaly", "Possible DoW"],
    "atlas_techniques": ["AML.T0034"],
    "owasp_llm_classes": ["LLM10"]
  },
  
  "raw_data": {
    "cost_1h_actual": 50.23,
    "cost_1h_baseline": 5.20,
    "ratio": 9.66,
    "request_count_1h": 234
  }
}

Top 10 règles de détection

Règle 1, Cost spike per user

Sigma rule :

title: LLM Cost Anomaly Per User
id: 018f2a3b-c4d5-6e7f-8901-2345abcdef01
status: experimental
description: User cost > 3× baseline → DoW potential
author: ZerodaySupport SOC
date: 2026-05-01
logsource:
  product: zerodaysupport
  service: llm_application
detection:
  selection:
    class_name: AI Application Activity
  timeframe: 1h
  condition: |
    sum(gen_ai.cost.amount) by actor.user.uid 
    > 3 * avg_over_time(sum(gen_ai.cost.amount) by actor.user.uid, 7d)
falsepositives:
  - Legitimate burst usage (verify with user manager)
level: high
tags:
  - attack.impact
  - atlas.AML.T0034
  - owasp.llm10

Splunk SPL :

index=llm sourcetype="llm:application:json" 
| bin _time span=1h
| stats sum(gen_ai.cost.amount) as cost_1h by actor.user.uid, _time
| eventstats avg(cost_1h) as baseline_avg, stdev(cost_1h) as baseline_stdev by actor.user.uid
| where cost_1h > (baseline_avg + 3*baseline_stdev) AND cost_1h > 5
| table _time, actor.user.uid, cost_1h, baseline_avg, ratio

KQL Sentinel :

LLMEvents_CL
| where TimeGenerated > ago(1h)
| summarize cost_1h = sum(cost_usd_d) by user_id_hash_s, bin(TimeGenerated, 1h)
| join kind=inner (
    LLMEvents_CL
    | where TimeGenerated between (ago(7d) .. ago(1h))
    | summarize baseline = avg(cost_usd_d) by user_id_hash_s
) on user_id_hash_s
| where cost_1h > 3 * baseline and cost_1h > 5.0
| project TimeGenerated, user_id_hash_s, cost_1h, baseline, ratio = cost_1h / baseline

Règle 2, Cross-tenant data leak

index=llm sourcetype="llm:application:json"
| where actor.user.org_id != "" AND finding.types contains "cross_tenant"
OR (rag_doc_ids contains "*" AND tenant_filter_applied=false)
| eval severity="critical"
| table _time, actor.user.uid, source_tenant, target_tenant, rag_doc_ids

Règle 3, Recursive tool calling

detection:
  selection:
    class_name: AI Application Activity
    tool_calls.count: ">10"
  condition: selection
level: medium
tags:
  - atlas.AML.T0034
  - owasp.llm06
  - owasp.llm10

Règle 4, Failed auth burst (credential stuffing)

index=auth source=llm-app
| stats count by src.ip.hash, _time span=1m
| where count > 10
| join src.ip.hash [
    search index=auth event=login_failed
    | stats count by src.ip.hash
]

Règle 5, Prompt injection signature

title: LLM Prompt Injection Pattern Detected
detection:
  selection:
    class_name: AI Application Activity
    gen_ai.guardrails.input_action: block
    gen_ai.guardrails.input_score: ">0.95"
  condition: selection
level: medium
falsepositives:
  - Legitimate research/security testing
tags:
  - atlas.AML.T0051
  - owasp.llm01

Règle 6, System prompt extraction

index=llm sourcetype="llm:application:json"
| where match(gen_ai.content.response_redacted, "(?i)Eva|ZerodaySupport|INSTRUCTION HIERARCHY")
| eval finding="system_prompt_leak"

Règle 7, Markdown image exfiltration

index=llm sourcetype="llm:application:json"
| where match(gen_ai.content.response_redacted, "!\[.*\]\(https?://(?!zerodaysupport\.com)")
| eval finding="markdown_image_external_url"
| eval severity="high"

Règle 8, Multi-turn jailbreak (Crescendo)

LLMEvents_CL
| where TimeGenerated > ago(15m)
| summarize 
    refusal_rate = countif(response_contains_refusal_b) * 1.0 / count(),
    msg_count = count()
  by session_id_s
| where refusal_rate > 0.3 and msg_count > 5
| project session_id_s, refusal_rate, msg_count

Règle 9, Sensitive tool call without HITL

index=llm sourcetype="llm:application:json"
| spath gen_ai.tools{}.name output=tool_names
| where tool_names IN ("refund", "send_email_external", "delete_file", "modify_permissions")
| where human_approval=false
| table _time, actor.user.uid, tool_names, status

Règle 10, Anomaly query volume per user

index=llm sourcetype="llm:application:json"
| bin _time span=1h
| stats count by actor.user.uid, _time
| eventstats avg(count) as baseline_avg by actor.user.uid
| where count > 10 * baseline_avg AND count > 100
| eval finding="volume_anomaly"

Intégration SIEM par stack

Splunk

# Application : envoyer logs via HEC (HTTP Event Collector)
import httpx
import os
import json
 
SPLUNK_HEC_URL = os.environ["SPLUNK_HEC_URL"]
SPLUNK_HEC_TOKEN = os.environ["SPLUNK_HEC_TOKEN"]
 
async def send_to_splunk(event: dict):
    async with httpx.AsyncClient() as client:
        await client.post(
            SPLUNK_HEC_URL,
            headers={"Authorization": f"Splunk {SPLUNK_HEC_TOKEN}"},
            json={
                "time": event["time"] / 1000,
                "host": event["device"]["name"],
                "source": event["metadata"]["product"]["name"],
                "sourcetype": "llm:application:json",
                "index": "llm",
                "event": event,
            },
        )
# Splunk : data model AI Activity custom
| pivot AI_Activity llm_application_activity
| eventstats avg(gen_ai.cost.amount) as avg_cost by actor.user.uid
| ...

Microsoft Sentinel

# Application : envoyer logs vers Log Analytics workspace
from azure.monitor.ingestion import LogsIngestionClient
from azure.identity import DefaultAzureCredential
 
client = LogsIngestionClient(
    endpoint=os.environ["DCE_ENDPOINT"],
    credential=DefaultAzureCredential(),
)
 
async def send_to_sentinel(events: list):
    client.upload(
        rule_id=os.environ["DCR_IMMUTABLE_ID"],
        stream_name="Custom-LLMEvents_CL",
        logs=events,
    )
// Sentinel : Analytics rule custom
LLMEvents_CL
| where TimeGenerated > ago(1h)
| where cost_usd_d > 50.0
| project TimeGenerated, user_id_hash_s, cost_usd_d, severity_s
| extend MitreAttackTactics = "Impact"
| extend AtlasAttackTechniques = "AML.T0034"

Elastic Security

# Filebeat config
filebeat.inputs:
  - type: filestream
    paths:
      - /var/log/llm-app/*.log
    parsers:
      - ndjson:
          target: ""
          add_error_key: true
 
processors:
  - add_fields:
      target: event
      fields:
        category: ai_activity
        type: llm_inference
  
output.elasticsearch:
  hosts: ["https://elastic:9200"]
  index: "llm-events-%{+yyyy.MM.dd}"
# Elastic Detection Rule (YAML)
description: LLM cost anomaly detected
risk_score: 65
severity: high
type: threshold
language: kuery
query: |
  event.category : "ai_activity" and gen_ai.cost.amount : > 5
threshold:
  field: actor.user.id
  value: 1
  cardinality:
    - field: actor.user.id
      value: 1
risk_score_mapping: []
threat:
  - framework: MITRE ATLAS
    technique:
      - id: AML.T0034
        name: Cost Harvesting

OTel Collector central (recommandé)

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
 
processors:
  batch:
    timeout: 5s
    send_batch_size: 1000
  
  attributes:
    actions:
      - key: gen_ai.content.prompt_redacted
        action: hash
        regex_pattern: ".*"
 
exporters:
  splunk_hec:
    token: ${SPLUNK_HEC_TOKEN}
    endpoint: ${SPLUNK_HEC_URL}
    source: llm-app
    sourcetype: llm:application:json
  
  azuremonitor:
    instrumentation_key: ${AZURE_MONITOR_KEY}
  
  elasticsearch:
    endpoints: ["https://elastic:9200"]
    index: llm-events
 
service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [batch, attributes]
      exporters: [splunk_hec, azuremonitor, elasticsearch]

Architecture : application → OTel SDK → OTel Collector → fan-out vers SIEM(s) cibles. Évite couplage lock-in vendor.

Conformité RGPD et volume

Stratégie par couche

# Application : redaction + pseudonymisation + sampling
import hmac
import hashlib
import random
from presidio_analyzer import AnalyzerEngine
 
PSEUDO_KEY = os.environ["PSEUDO_HMAC_KEY"].encode()
analyzer = AnalyzerEngine()
 
def pseudonymize_user_id(user_id: str) -> str:
    return hmac.new(PSEUDO_KEY, user_id.encode(), hashlib.sha256).hexdigest()
 
def redact_pii(text: str, language: str = "fr") -> str:
    results = analyzer.analyze(
        text=text,
        language=language,
        entities=["EMAIL_ADDRESS", "PHONE_NUMBER", "PERSON", "FR_NIR", "IBAN_CODE"],
    )
    for r in sorted(results, key=lambda x: x.start, reverse=True):
        text = text[:r.start] + f"[{r.entity_type}_REDACTED]" + text[r.end:]
    return text
 
 
def should_log_full(event_severity: str, event_type: str) -> bool:
    """Sampling intelligent."""
    # 100% events sécurité
    if event_severity in {"high", "critical"}:
        return True
    # 100% events sensibles
    if event_type in {"tool_call_sensitive", "guardrail_block", "anomaly_flag"}:
        return True
    # 10% events normaux (informational)
    return random.random() < 0.1
 
 
async def emit_log(event: dict):
    # 1. Redaction
    if "prompt" in event.get("gen_ai", {}).get("content", {}):
        event["gen_ai"]["content"]["prompt_redacted"] = redact_pii(
            event["gen_ai"]["content"]["prompt"]
        )
        del event["gen_ai"]["content"]["prompt"]
    
    if "response" in event.get("gen_ai", {}).get("content", {}):
        event["gen_ai"]["content"]["response_redacted"] = redact_pii(
            event["gen_ai"]["content"]["response"]
        )
        del event["gen_ai"]["content"]["response"]
    
    # 2. Pseudonymisation
    if "user_id" in event.get("actor", {}).get("user", {}):
        event["actor"]["user"]["uid"] = pseudonymize_user_id(
            event["actor"]["user"]["user_id"]
        )
        del event["actor"]["user"]["user_id"]
    
    # 3. Sampling
    if not should_log_full(event["severity"], event["class_name"]):
        return
    
    # Send
    await siem_emit(event)

Rétention par classe

RETENTION_POLICIES = {
    "security_critical": "1825d",   # 5 ans (audit, incidents)
    "security_1y": "365d",           # 1 an (events sécurité standard)
    "informational": "90d",          # 3 mois (events normaux)
    "debug": "14d",                  # 14 jours (debug only)
}

EU AI Act Art. 12 obligations

Pour systèmes haut risque :

  • Logging automatique tout au long du cycle de vie
  • Conservation minimum 6 mois (souvent plus selon activité)
  • Garantir traçabilité et audit ex-post

→ Class security_1y minimum est conforme. Pas négociable pour high-risk.

Right to erasure

async def erase_user_logs(user_id: str):
    """
    Process RGPD right to erasure.
    Identifier tous les events log par user_id_hash et delete.
    """
    user_id_hash = pseudonymize_user_id(user_id)
    
    # Splunk
    await splunk_delete_query(f'user_id_hash="{user_id_hash}"')
    
    # Sentinel
    await sentinel_delete_query(f'user_id_hash_s == "{user_id_hash}"')
    
    # Elastic
    await elastic_delete_by_query("llm-events-*", {"term": {"user_id_hash": user_id_hash}})
    
    # Audit trail de la deletion
    await audit_log({
        "action": "rgpd_erasure",
        "user_id_hash": user_id_hash,
        "timestamp": datetime.utcnow().isoformat(),
        "operator": current_user_id,
    })

Modèle d'organisation SOC 3 niveaux

Niveau 1, SOC tier 1 (24/7)

Profil : analyst SOC général, formé sur top 10 règles + cheat sheet LLM.

Tâches :

  • Monitoring dashboards principaux
  • Triage alertes critiques selon playbooks
  • Escalade vers tier 2 sur cas complexes

Formation : 30 min initiale + cheat sheet. Pas spécialisé LLM.

Niveau 2, SOC tier 2 (heures bureau)

Profil : cybersec senior + montée en compétence LLM.

Tâches :

  • Analyse incidents complexes
  • Threat hunting proactif
  • Ajustement règles, faux positifs review
  • Collaboration AI engineers

Formation : 1-2 semaines (OWASP LLM Top 10, MITRE ATLAS, formation LLM Security).

Niveau 3, AI Security specialist

Profil : équipe dédiée 1-3 ETP en grandes orgs, parfois mutualisé chez ETI.

Tâches :

  • Threat intel LLM (papers, conférences, communautés)
  • Red team interne (PyRIT, custom)
  • Architecture sécurité conseil aux AI engineers
  • Veille évolutions OWASP / EU AI Act

Formation continue : participation événements (DEF CON AI Village, Black Hat AI), formations avancées.

KPIs SOC LLM

KPICible 2026
MTTD (Mean Time To Detect)< 15 min pour cost spike, < 5 min pour cross-tenant
MTTR (Mean Time To Respond) HIGH< 1h
MTTR MEDIUM< 4h
TPR (True Positive Rate)> 50%
FPR (False Positive Rate)< 30% (alertes humaines)
Volume alertes/jour T1< 30 par analyst
Coverage MITRE ATLAS techniques> 60%
Coverage OWASP LLM Top 10100% (toutes classes monitorées)

Cadence opérationnelle

CadenceAction
Continu T1Alertes critiques 24/7 + réponse
Quotidien T2Review dashboards, top alerts non-triées
Hebdo T2+T3Analyse trends, ajustement règles
MensuelRapport SOC IA pour CISO + AI Officer
TrimestrielThreat hunt proactif + red team interne
AnnuelAudit externe + benchmark maturité

Erreurs récurrentes

Erreur 1, Logger prompts en clair

Volume PII massif, RGPD violation. Toujours redaction Presidio avant emit.

Erreur 2, JSON ad hoc sans schema

Maintenance ingérable côté SIEM. OCSF ou ECS standard.

Erreur 3, Pas de pseudonymisation user_id

Si SIEM compromis, leak users. HMAC user_id systématique.

Erreur 4, Logs sans cost / tokens

Impossible d'investiguer DoW. Cost dans tous les logs.

Erreur 5, Pas de sampling

Volume explose, coûts SIEM explosent. Sampling intelligent (100% sécurité, 10% normal).

Erreur 6, Pas de règles MITRE ATLAS taggées

Pas de corrélation avec menaces classiques. Mapping ATLAS + OWASP tagging.

Erreur 7, Pas de procédure right-to-erasure

RGPD violation potentielle. Procédure delete by user_id_hash.

Erreur 8, Pas de formation SOC

Analyst T1 ne sait pas trier alertes LLM. Cheat sheet + formation 30 min minimum.

Ce que vous devriez retenir

  1. Schéma 50 champs en 8 sections (id, acteur, source, modèle, contenu, métriques, sécurité, conformité)
  2. Format OCSF pour intégration SIEM native cross-vendor
  3. Top 10 règles Sigma/SPL/KQL prêtes à déployer
  4. OTel Collector central pour fan-out multi-SIEM
  5. Conformité RGPD : redaction PII + pseudonymisation + sampling
  6. MITRE ATLAS + OWASP LLM tagging systématique
  7. 3 niveaux SOC (T1 24/7, T2 heures bureau, T3 specialist)
  8. KPIs mesurables : MTTD < 15 min, MTTR HIGH < 1h, TPR > 50%

Sans collecte de logs structurée, le SOC ne peut pas surveiller un LLM efficacement. C'est l'infrastructure invisible qui rend possible toute la suite (détection, threat hunting, audit, conformité).


Pour aller plus loin : pour la couche détection comportementale au-delà des règles statiques : détecter un abus de LLM en temps réel : signaux faibles, patterns. Pour le mapping menaces : MITRE ATLAS : matrice d'attaques sur systèmes IA.

Questions fréquentes

  • Quel schéma de log minimum collecter pour un SOC qui surveille un LLM ?
    Schéma 50 champs structuré en 8 sections. **(1) Identification (5)** : event_id, ts, request_id, trace_id, parent_span_id. **(2) Acteur (5)** : user_id_hash, user_role, org_id, session_id, source_ip_hash. **(3) Source (5)** : app_name, app_version, environment, region, hostname. **(4) Modèle (6)** : provider, model_name, model_version, temperature, max_tokens, finish_reason. **(5) Contenu (8)** : prompt_redacted, response_redacted, prompt_tokens, completion_tokens, total_tokens, rag_doc_ids, tool_calls, message_history_length. **(6) Métriques (6)** : duration_ms, latency_breakdown_ms, cost_usd, cache_hit, retry_count, queue_time_ms. **(7) Sécurité (8)** : guardrail_input_score, guardrail_input_action, guardrail_output_alerts, anomaly_flags, rate_limit_dimension_hit, mitre_atlas_techniques, owasp_llm_classes, severity. **(8) Conformité (7)** : data_classification, retention_class, deletion_eligible_after, gdpr_lawful_basis, dpia_reference, audit_trail_id, schema_version. **Format** : JSON structuré, schéma versionné. Convention OCSF (Open Cybersecurity Schema Framework) pour intégration SIEM. **Volume** : 5-50 KB par event (~100× log REST classique). Plan storage 50-500 GB/mois pour 10M req/mois.
  • Pourquoi format OCSF plutôt que JSON ad hoc ?
    **OCSF (Open Cybersecurity Schema Framework)** = standard cross-vendor pour logs sécurité, lancé par AWS+Splunk+autres en 2022, adopté par Splunk, Microsoft Sentinel, Elastic Security, Sumo Logic, IBM QRadar. Bénéfices vs JSON ad hoc : (1) **Ingestion native SIEM** sans transformation custom, réduit l'effort intégration. (2) **Vocabulaire normalisé** : 'actor', 'src_endpoint', 'finding', 'severity_id', partagé entre tous les vendors. (3) **Corrélation cross-source** : logs LLM corrélables avec logs auth, network, endpoint via SIEM SOC. (4) **Schéma extensible** : on peut ajouter `gen_ai_*` attributes custom tout en gardant base OCSF. **Pour LLM en 2026** : OCSF a publié extensions GenAI/AI events 2024-2025. Class IDs spécifiques pour AI Detection Finding. **Alternative** : ECS (Elastic Common Schema) si stack Elastic. CEF (Common Event Format) si vieux SIEM. **Recommandation 2026** : OCSF si stack moderne (Splunk Cloud, Sentinel, Sumo). ECS si Elastic-only. Convertir si besoin via OTel Collector. **Anti-pattern** : custom JSON sans schéma, chaque ajout d'un nouveau type d'event = changement schéma SIEM. Maintenance ingérable.
  • Quelles règles de détection (Sigma, Splunk SPL) coder en priorité pour LLM ?
    Top 10 règles à déployer. **(1) Cost spike per user** : `count(cost_usd) by user_id WHERE > 3× baseline_per_user_per_hour` → DoW potential. **(2) Cross-tenant query** : `event WHERE source_tenant != target_tenant_data_returned` → exfiltration. **(3) Recursive tool calling** : `count(tool_calls) by request_id WHERE > 10` → loop ou attaque. **(4) Failed auth burst** : `count(auth_failed) by source_ip WHERE > 10/min` → credential stuffing. **(5) Prompt injection signature** : `prompt_redacted MATCHES regex_injection_patterns` AND `guardrail_input_action = 'block'` → mass attack visible. **(6) System prompt extraction** : `response CONTAINS system_prompt_fingerprint` → leak detected. **(7) Markdown image external in output** : `response_redacted MATCHES '!\[.*\]\(https?://(?!allowed_domain)'` → exfiltration. **(8) Multi-turn jailbreak** : `count(events) by session_id WHERE refusal_rate > 0.3 AND messages > 5` → Crescendo en cours. **(9) Tool call without HITL on sensitive tool** : `tool_call IN sensitive_tools AND human_approval = false` → bypass HITL. **(10) Anomaly query volume** : `count(events) by user_id WHERE > 10× baseline` → scraping ou DoW. **Format** : Sigma rules YAML pour portabilité, ou SPL/KQL pour Splunk/Sentinel direct. **Maintenance** : trimestrielle, ajuster seuils selon faux positifs observés.
  • Comment intégrer ces logs avec Splunk / Sentinel / Elastic ?
    Stratégie d'ingestion par SIEM. **Splunk** : (1) Logs JSON envoyés via HEC (HTTP Event Collector) ou stdout → Splunk Universal Forwarder. (2) Sourcetype dédié `llm:application:json` avec parsing automatique. (3) Data model 'AI Activity' custom basé sur OCSF. (4) Apps Splunkbase : 'AI Security' (en émergence 2025-2026). **Microsoft Sentinel** : (1) Logs vers Log Analytics workspace via Azure Monitor agent ou API HTTP Data Collector. (2) Custom table `LLMEvents_CL` avec schéma OCSF. (3) Sentinel Analytics rules KQL pour détection. (4) Workbooks pour dashboards. (5) Native si Azure OpenAI : Azure logs déjà présents. **Elastic Security** : (1) Filebeat ou OTel Collector → Elasticsearch. (2) Index `llm-events-*` avec mapping ECS extension. (3) Elastic Detections rules YAML. (4) Kibana dashboards. **Stack 2026 recommandée** : OTel Collector central qui normalise events → fan-out vers SIEM(s) cible. Évite couplage lock-in vendor. **Coûts** : ingestion logs SIEM facturée au volume (Splunk/Sentinel/Elastic Cloud). Plan budget : 50-500GB/mois pour app moyenne. À sampler si volume très élevé (logs sécurité 100%, logs informationnels 10%).
  • Comment équilibrer logging exhaustif et conformité RGPD / volume ?
    Trois techniques empilées. (1) **Redaction PII automatique** : avant écriture log, prompt et response passent par Presidio detector. Email, téléphone, IBAN, NIR, noms remplacés par `[REDACTED]`. Cf article logging du cluster défense. (2) **Pseudonymisation** : user_id remplacé par hash HMAC (clé env-specific). Permet agrégation sans re-identification directe. Si breach SIEM, pas de leak users. (3) **Sampling intelligent** : 100% des events sécurité (guardrail blocks, anomalies, errors) + 100% des events sensibles (tool calls, cross-tenant attempts) + 10% des events normaux (chat normal). Réduit volume × 5-10 sans perte signal sécurité. **Rétention par classe** : security events 1 an minimum (audit, conformité), informational 30-90j, debug 7-14j. Auto-purge programmée. **Right to erasure RGPD** : si user demande deletion, mécanisme delete par user_id_hash dans logs (techniquement complexe sur SIEM, à anticiper). **DPIA** : logger fait partie du périmètre traitement → documenter dans DPIA. **EU AI Act Art. 12** : haut risque → logging obligatoire 6 mois minimum. Pas négociable. **Anti-pattern** : logger prompts/responses en clair pendant 5 ans 'pour avoir tout'. Violation RGPD + cost storage explose + SIEM ralenti.
  • Quelle cadence et organisation SOC pour exploiter ces logs ?
    Modèle 3 niveaux. **Niveau 1, SOC tier 1 (24/7)** : monitoring dashboards, triage alertes selon playbooks. Pas spécialisé LLM, mais formé sur top 10 règles + escalation criteria. ~30 min formation initiale + cheat sheet. **Niveau 2, SOC tier 2 (heures bureau)** : analyse incidents complexes, threat hunting, ajustement règles. Profil cybersec senior + montée en compétence LLM (1-2 semaines de formation : OWASP LLM Top 10, MITRE ATLAS). **Niveau 3, AI Security specialist (équipe dédiée)** : threat intel LLM, red team interne, collaboration AI engineering. Profil rare 2026 (former en interne souvent meilleur ROI). **Cadence** : (1) Continu T1 : alertes critiques 24/7. (2) Quotidien T2 : review dashboards, top alerts non-triées, anomalies. (3) Hebdo T2+T3 : analyse trends, ajustement règles, faux positifs review. (4) Mensuel : rapport SOC IA pour CISO + AI Officer (volume incidents, MTTD, MTTR, top patterns). (5) Trimestriel : threat hunt proactif (nouveaux TTPs émergents), red team interne pour valider couverture. (6) Annuel : audit externe + benchmark maturité. **KPIs** : MTTD (mean time to detect, cible &lt; 15 min), MTTR (mean time to respond, cible &lt; 1h pour HIGH), TPR (true positive rate, cible > 50%), coverage MITRE ATLAS (cible > 60% techniques observables).

Écrit par

Naim Aouaichia

Cyber Security Engineer et fondateur de Zeroday Cyber Academy

Ingénieur cybersécurité avec un parcours hybride : développement, DevOps Capgemini, DevSecOps IN Groupe (sécurité des documents d'identité régaliens), audits CAC 40. Fondateur de Hash24Security et Zeroday Cyber Academy. Présence LinkedIn 43 000 abonnés, Substack Zeroday Notes 23 000 abonnés.