Triage de alertas con LLMs sin filtrar datos sensibles
Patrón de redacción y enriquecimiento local antes de enviar contexto a un modelo. Compatible con n8n, Ollama y guardrails opensource.
El dilema del SOC moderno
Los analistas de tier 1 procesan entre 200 y 600 alertas al día. La mayoría son falsos positivos o variantes conocidas. Un LLM puede hacer triage inicial brillantemente — pero enviar logs crudos a una API externa expone PII, credenciales, hostnames internos, y a veces secretos en líneas de comando.
La solución no es no usar LLMs. Es construir una capa de redacción determinista antes del modelo, y validar con guardrails después.
Arquitectura de tres capas
Capa 2: redacción local
Usamos presidio de Microsoft (open-source) más un diccionario custom para detectar entidades específicas de la organización. La clave: la redacción es biyectiva — guardamos el mapping en memoria por la duración del triage para poder rehidratar la respuesta.
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
import hashlib
analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()
CUSTOM_PATTERNS = [
(r"\b10\.\d+\.\d+\.\d+\b", "INTERNAL_IP"),
(r"\b[a-z]+-prod-\d+\b", "PROD_HOST"),
(r"AKIA[0-9A-Z]{16}", "AWS_KEY"),
]
def redact(text: str) -> tuple[str, dict]:
mapping = {}
for pattern, label in CUSTOM_PATTERNS:
for match in re.finditer(pattern, text):
token = f"{label}_{hashlib.sha256(match.group().encode()).hexdigest()[:6]}"
mapping[token] = match.group()
text = text.replace(match.group(), token)
return text, mapping
Capa 3: el prompt
Mantenemos el prompt corto, estructurado, y forzamos JSON output. Para self-hosted, llama3.1:8b o mistral-nemo son suficientes para triage de tier 1.
SYSTEM: You are a SOC tier 1 analyst. Classify the alert.
Output strict JSON:
{
"severity": "low|medium|high|critical",
"category": "string",
"false_positive_probability": 0.0-1.0,
"next_action": "auto_close|enrich|escalate|isolate_host",
"reasoning": "string (max 80 words)"
}
USER: ${redacted_alert}
Capa 4: guardrails
Antes de mostrar la respuesta a un humano, validamos que: (1) no tenga tokens redactados sin rehidratar accidentalmente filtrados, (2) la acción sugerida esté en una allowlist explícita, (3) la confianza esté calibrada contra ground truth histórico.
Resultados reales
- Reducción de tiempo de triage tier 1: de 8 min a 90 segundos
- Acuerdo con analista humano: 87% en alertas low/medium
- Cero filtraciones de datos sensibles auditadas en 6 meses
- Costo: $0/mes usando Ollama local en GPU dedicada
El LLM no reemplaza al analista. Filtra el ruido para que el analista vea solo lo que importa.
¿Quieres implementar este patrón en tu SOC? Hacemos el diseño del workflow, redacción y guardrails sobre tu stack actual.