Guardrails para agentes de seguridad IA en producción
Un agente IA que puede leer tu SIEM, consultar tu proveedor de identidad y ejecutar acciones de contención no es un chatbot — es un proceso privilegiado. Necesita guardrails.
He dedicado el último año a construir agentes de seguridad autónomos que investigan alertas, correlacionan señales en decenas de fuentes de datos y ejecutan acciones de contención. La lección más importante: lo difícil no es hacer agentes lo suficientemente inteligentes para actuar — es hacerlos lo suficientemente seguros para confiar en ellos.
Este post documenta la arquitectura de guardrails que uso en producción.
Principio de Diseño: Lectura Intensiva, Escritura Restringida
El principio fundamental es la asimetría. Los agentes deben poder leer todo pero escribir casi nada sin controles explícitos.
Los agentes PUEDEN libremente:
- Consultar todas las fuentes de datos (SIEM, proveedor de identidad, proveedor cloud, EDR)
- Calcular scores de riesgo y niveles de confianza
- Correlacionar señales entre múltiples sistemas
- Generar reportes de investigación
- Auto-auditar su propio historial de decisiones
Los agentes NO PUEDEN:
- Modificar cuentas de usuario (excepto en los niveles de severidad más altos con aprobación)
- Cambiar el estado de alertas sin justificación documentada
- Escribir en infraestructura de producción
- Cerrar casos de investigación sin cadena de evidencia
- Ejecutar acciones de contención fuera de su alcance asignado
Esta asimetría significa que un fallo del agente resulta en “leyó mucho pero no hizo nada” en vez de “desactivó la cuenta del CEO a las 3 AM.”
Cinco Capas de Guardrails
Capa 1: Audit Logging
Cada llamada a herramienta que hace el agente se escribe en un log JSONL append-only. Sin excepciones.
import json, time, hashlib
def audit_log(agent_id: str, tool: str, params: dict, result: str):
entry = {
"ts": time.time(),
"agent": agent_id,
"tool": tool,
"params": params,
"result_hash": hashlib.sha256(result.encode()).hexdigest(),
"prev_hash": get_last_entry_hash()
}
# Append-only, cadena a prueba de manipulacion
with open(f"/var/log/agents/{agent_id}.jsonl", "a") as f:
f.write(json.dumps(entry) + "\n")
El campo prev_hash crea una cadena de hashes — si alguien modifica una entrada histórica, la cadena se rompe. Un agente de gobernanza separado valida la integridad de la cadena cada hora.
Capa 2: Write Guards
Cada operación de mutación pasa por un write guard que puede operar en tres modos: block, dry-run o live.
class WriteGuard:
def __init__(self, mode: str = "dry-run"):
self.mode = mode # "block" | "dry-run" | "live"
def execute(self, action: str, target: str, params: dict) -> dict:
if self.mode == "block":
return {"status": "blocked", "reason": "write guard activo"}
if self.mode == "dry-run":
return {"status": "dry-run", "would_execute": action, "target": target}
# Modo live — aun requiere verificacion de deny-hook
if self.deny_hook_check(action, target):
return {"status": "denied", "reason": "blocklist permanente"}
return self._execute_live(action, target, params)
Los agentes nuevos empiezan en modo block. Tras una semana revisando sus logs de dry-run, los promuevo a dry-run. Solo después de cientos de decisiones validadas ganan el modo live — y aun así, solo para tipos de acción específicos.
Capa 3: Deny Hooks
Algunas operaciones están permanentemente bloqueadas independientemente del contexto. Son innegociables:
- Nunca eliminar una cuenta de usuario
- Nunca modificar políticas IAM
- Nunca desactivar el audit logging
- Nunca acceder directamente a almacenes de credenciales
- Nunca escalar sus propios permisos
Son reglas de denegación hardcodeadas, no configurables. Ningún prompt, nivel de severidad u override puede saltárselas.
Capa 4: Actor Scope
Cuando un agente investiga un usuario o sistema específico, sus acciones de contención se limitan exclusivamente a ese objetivo. Un agente investigando user-12345 no puede tomar acciones contra user-67890, aunque crea que hay conexión. Expandir el alcance requiere una nueva investigación con su propia cadena de aprobación.
Capa 5: Firma de Evidencia
Cada pieza de evidencia recopilada durante una investigación se firma con HMAC-SHA256 para mantener la cadena de custodia:
import hmac, hashlib, json, time
def sign_evidence(evidence: dict, signing_key: bytes) -> dict:
evidence["collected_at"] = time.time()
evidence["agent_version"] = AGENT_VERSION
payload = json.dumps(evidence, sort_keys=True).encode()
signature = hmac.new(signing_key, payload, hashlib.sha256).hexdigest()
return {"evidence": evidence, "signature": signature}
Si una investigación llega a revisión legal, cada dato tiene una prueba criptográfica de cuándo fue recopilado y de que no ha sido alterado.
Defensa contra Prompt Injection
Los agentes IA que ingieren datos externos (payloads de alertas, asuntos de email, entradas de log) son vulnerables a prompt injection. Un atacante que controle un mensaje de log podría intentar manipular el comportamiento del agente.
Mis defensas:
Tags XML de frontera — Las instrucciones del sistema y los datos externos están separados por fronteras XML estrictas. Las instrucciones del agente van en tags
<system>; todo input externo se envuelve en tags<external_data>con advertencias explícitas.Validación de input — Todos los datos ingeridos pasan por validación de esquema antes de que el agente los vea. Si un asunto de email contiene patrones tipo instrucción (
ignore previous,you are now,system:), se marca y sanitiza.Escaneo de outputs de herramientas — Cuando el agente llama a una herramienta MCP, la respuesta se escanea buscando patrones de inyección antes de pasarla al contexto del agente. Un sistema externo comprometido no puede inyectar instrucciones a través de outputs de herramientas.
Contención Graduada: Niveles de Acción de Seguridad
No toda amenaza requiere la misma respuesta. Uso cuatro Niveles de Acción de Seguridad (SAL):
| Nivel | Respuesta | Aprobación Requerida |
|---|---|---|
| SAL 1 | Monitorizar — aumentar verbosidad de logging | Ninguna (autónomo) |
| SAL 2 | Contención suave — forzar MFA, reducir duración de sesión | Agente + peer review |
| SAL 3 | Contención dura — suspender sesiones activas, revocar tokens | Aprobación de analista humano |
| SAL 4 | Aislamiento total — desactivar cuenta, bloquear todo acceso | SOC manager + notificación CISO |
El agente determina el nivel SAL basándose en confianza de la señal, criticidad del activo y radio de impacto. Pero crucialmente, SAL 3 y superior siempre requieren aprobación humana — el agente propone, los humanos disponen.
Testing
La confianza en estos guardrails viene de testing exhaustivo:
- 1.700+ tests unitarios cubriendo caminos de decisión del agente, edge cases e inputs adversariales
- 4 gates de CI que cada cambio debe pasar: code review asistido por IA, escaneo SAST, auditoría de dependencias y análisis semántico de cambios en prompts
- Validación dual-agent — un segundo agente revisa independientemente las conclusiones de investigación del primer agente antes de que se ejecute cualquier acción de contención
El patrón dual-agent detecta un número sorprendente de errores de razonamiento. Cuando el Agente A concluye “esta es una cuenta comprometida,” el Agente B evalúa independientemente la misma evidencia. Los desacuerdos escalan a revisión humana.
Lecciones Aprendidas
Empieza con dry-run en todo. La tentación es lanzar agentes que pueden actuar inmediatamente. Resiste. Ejecuta cada agente en dry-run al menos dos semanas. Descubrirás patrones de decisión que nunca anticipaste, y te alegrarás de que no se estuvieran ejecutando en vivo.
Loguea decisiones, no solo acciones. Al revisar un incidente, saber lo que el agente hizo no es suficiente. Necesitas saber por qué lo hizo — qué señales pesó, qué alternativas consideró, qué umbral de confianza cruzó. Esto marca la diferencia entre debugging y adivinar.
Agentes de gobernanza que auditan a otros agentes previenen el drift. Sin supervisión automatizada, el comportamiento de los agentes deriva con el tiempo a medida que los modelos se actualizan, los prompts evolucionan y las distribuciones de datos cambian. Un agente de gobernanza dedicado que revisa decisiones de sus pares detecta el drift antes de que se convierta en una brecha de seguridad.
Los agentes de seguridad IA son multiplicadores de fuerza — pero solo si puedes confiar en ellos. La arquitectura de guardrails descrita aquí me ha permitido desplegar agentes que manejan miles de alertas por semana manteniendo la superficie de control que un equipo de seguridad requiere. La idea clave: los guardrails no son limitaciones a la capacidad del agente — son lo que hace que la capacidad sea desplegable.
Artículos relacionados:
- Cómo construí un sistema de guardrails para agentes IA — la implementación open source del framework de guardrails con código completo.
- 14 agentes IA eliminaron nuestro backlog: la arquitectura SOC multi-tier — la arquitectura multi-agente donde estos guardrails se aplican en producción.
- Harness Engineering: 6 capas de defensa para Claude Code — el concepto más amplio de harness engineering donde los guardrails son una de las 6 capas.