Por Qué los Agentes Genéricos de IA Fallan en Seguridad
La mayoría de las demos de seguridad con IA se enfocan en un solo repositorio o benchmark curado. En la realidad, los codebases empresariales abarcan decenas de lenguajes, miles de dependencias y millones de líneas de código. Un enfoque de agente único choca con tres paredes fundamentales:
- Agotamiento de contexto — Después de una hora, la ventana de contexto se llena y el modelo olvida bugs que encontró antes.
- Hipótesis única — Los agentes exploran un camino de ataque a la vez, perdiendo el panorama general.
- Sin persistencia — Un fallo o timeout pierde todo el progreso.
El viaje de Cloudflare comenzó con un skill de auditoría de seguridad de 450 líneas que corría en un repo. Funcionaba, pero una sola ejecución encontraba solo la mitad de los bugs. La solución no fue un mejor modelo — fue una capa de orquestación agnóstica a modelos que trata a los LLMs como motores de cómputo intercambiables.
![]()
Arquitectura: Pipeline de Dos Etapas
El sistema de Cloudflare divide la gestión de vulnerabilidades en dos etapas independientes, cada una usando un modelo diferente:
Etapa 1: Harness de Descubrimiento de Vulnerabilidades (VDH)
| Agente | Rol | Detalles |
|---|---|---|
| Recon | Mapea arquitectura y vectores de amenaza | 3 agentes paralelos escriben architecture.md |
| Hunt | Ataques por clase | Crea agentes hermanos, usa binarios en sandbox |
| Validate | Verificación mecánica + refutación adversarial | Dos pasadas: chequeo de schema, luego agente intenta refutar |
| Gapfill | Genera nuevas tareas para áreas descubiertas | Encola nuevas cacerías para celdas de cobertura vacías |
| Dedup | Consolida hallazgos superpuestos | Agrupa por causa raíz |
| Trace | Recorre grafo de dependencias | Crea tareas en repositorios consumidores |
| Feedback | Aprende de ejecuciones pasadas | Reescribe prompts basado en fallos de validación |
| Report | Renderiza salida legible para humanos | Ningún modelo necesario |
Etapa 2: Sistema de Validación de Vulnerabilidades (VVS)
| Agente | Rol | Detalles |
|---|---|---|
| Dedup | Identifica duplicados entre todas las fuentes | Índice determinístico + razonamiento probabilístico |
| Judgment | Alcanzabilidad en producción y puntuación de riesgo | Consulta MCP, Jira, git, config |
| Fixer | Genera parches + ejecuta pruebas de regresión | Requiere fallo→pase limpio; nunca hace merge sin humano |
# Ejemplo simplificado: orquestando etapas con backend de base de datos
import sqlite3
from enum import Enum
class Stage(Enum):
RECON = "recon"
HUNT = "hunt"
VALIDATE = "validate"
class Harness:
def __init__(self, db_path: str):
self.conn = sqlite3.connect(db_path)
self.conn.execute("""
CREATE TABLE IF NOT EXISTS findings (
run_id TEXT,
repo TEXT,
stage TEXT,
data TEXT,
status TEXT DEFAULT 'pending'
)
""")
def run_stage(self, run_id: str, repo: str, stage: Stage, task: callable):
# Verifica si ya se completó
cursor = self.conn.execute(
"SELECT status FROM findings WHERE run_id=? AND repo=? AND stage=?",
(run_id, repo, stage.value)
)
row = cursor.fetchone()
if row and row[0] == 'completed':
return
result = task()
self.conn.execute(
"INSERT OR REPLACE INTO findings VALUES (?,?,?,?,?)",
(run_id, repo, stage.value, result, 'completed')
)
self.conn.commit()
![]()
Lecciones Críticas de Producción
1. Persistencia Antes del Paralelismo
Cada etapa escribe en una base SQLite claveada por (run_id, repo, stage). Los hallazgos se transmiten y guardan conforme ocurren — un fallo cuesta solo la tarea en vuelo. Esto es innegociable para ejecuciones que pueden tomar 14+ horas.
2. Cuidado con Errores Silenciosos de API
A veces, un error transitorio de API regresa como texto en una respuesta 200 OK en lugar de lanzar una excepción. Debes clasificar explícitamente el texto de la respuesta, no confiar solo en el código de estado.
3. Sandboxing Necesita Configuración Cuidadosa
Si tu harness corre dentro de Docker, el sandbox (usado para crashear binarios) necesita seccomp=unconfined y apparmor=unconfined o fallará silenciosamente al iniciar.
4. No Pongas Análisis Estático Muy Temprano
Cloudflare integró Semgrep en todo el pipeline. En un mes de ejecuciones, los Hunters lo invocaron cero veces. Preferían leer y ejecutar el código. ¿La herramienta más usada? Una wishlist central donde los agentes solicitan recursos.
5. Deduplicación es un Problema Propio
A escala, comparar hallazgos con coincidencia simple de strings falla. Cloudflare usa código determinístico para construir índices invertidos sobre archivos, funciones y tokens raros, y solo entonces usa un LLM para razonar sobre una lista corta de candidatos.
6. Forja Verificación Adversarial
Cada hallazgo debe incluir:
- Un modelo de amenaza declarado (quién es el atacante, qué frontera se cruza)
- Un PoC que corre contra el codebase original, intacto
- Un parche propuesto
Un Validador separado (que no puede registrar sus propios hallazgos) intenta refutar todo. Si un Hunter califica su propio trabajo, validará con confianza cualquier disparate.
Explora el skill open-source que comenzó todo.

Métricas del Mundo Real y Limitaciones
Para un repositorio estándar de ~30k LOC:
- Hallazgos iniciales: ~100 candidatos brutos
- Después de validación: ~80 bugs de alta fidelidad
- Tiempo para corregir con revisión humana: ~14 horas para el pipeline, luego 5 días para correcciones críticas, 15-20 días para hardening
- Compresión a lo largo del tiempo: ~65% de reducción en candidatos en toda la flota
Limitaciones y Cuidados
- Sin tasa de falso negativo: No existe un conjunto etiquetado de todos los bugs reales en un codebase. El equipo mide efectividad rastreando si re-ejecuciones siguen encontrando nuevos bugs.
- Costo es pesado en la etapa de cacería: Presupuesta por repositorio, no por ejecución. Usa un límite de tareas y un pool de workers (50-200) para evitar desperdicio de cómputo.
- No para verificaciones por PR: Escaneos completos toman horas. Usa harnesses más pequeños y baratos para CI.
- Humano en el loop es obligatorio: El Fixer nunca hace merge sin que un humano apruebe en un dry run.
Próximos Pasos
- Empieza con un skill de un solo repo en tu entorno de desarrollo. Deja los prompts funcionando bien antes de construir infraestructura.
- Agrega persistencia (SQLite) antes de agregar paralelismo.
- Agrega un mecanismo de wishlist — deja que los agentes te digan lo que necesitan.
- Introduce verificación adversarial con un modelo separado para validación.
- Solo construye rastreo entre repos cuando tengas más de un repo que importe.