Playbook de incidentes para agentes de IA.

Corta el acceso de un agente en minutos y deja escrito quién decide. Cómo bloquear, revocar credenciales, verificar y cronometrar el bloqueo, desbloquear y qué guardar para la revisión.

Resumen

Cuando un agente de IA hace algo que no debe (un bucle de DELETE, lecturas fuera de su tarea, una instrucción inyectada), lo primero es detenerlo, no entender por qué. Vericto tiene un interruptor de bloqueo por agente: con un clic, cada sentencia de ese agente se rechaza en cada vía donde Vericto la evalúa, con un mensaje que le dice que no reintente y que pida ayuda a una persona.

Esta página es el playbook para el control 10 del checklist de acceso de agentes a producción: "Corta el acceso de un agente en minutos y sabe quién decide". Al final hay una plantilla de runbook para completar con los nombres de tu equipo.

Quién decide

Decide un rol con nombre, no "el equipo". Escríbelo en tu runbook antes de necesitarlo:

  • Responsable del incidente: ____ (rol, nombre y suplente). Decide bloquear y decide desbloquear.
  • Quién ejecuta el bloqueo en Vericto: el owner o un admin del workspace. Son los únicos roles que pueden bloquear y desbloquear; members y viewers ven los bloqueos, pero no los cambian.
  • Responsable de la base de datos: ____. Rota la contraseña del usuario de base de datos o desactiva el rol cuando la credencial está comprometida.
  • Escalamiento: si no se puede contactar al responsable del incidente en ____ minutos, decide ____.

Bloquear es reversible y no borra nada, así que la regla práctica es bloquear primero y preguntar después. Desbloquear necesita la decisión del responsable del incidente.

Cómo bloquear un agente

En el dashboard, abre Respuesta a incidentes → Bloquear un agente, elige el objetivo, escribe el motivo (obligatorio, por ejemplo el número del ticket) y confirma. El objetivo es la forma en que Vericto reconoce al agente en cada vía:

  • Una API key: lo que el agente usa con la API de runtime, los SDK, check_sql del MCP y la CLI.
  • Un usuario de base de datos, en una base o en todas las del workspace: las sesiones del agente a través del proxy TCP.
  • Un principal del registro: su API key y su usuario de base de datos exacto, en las bases del principal, con un solo bloqueo.
  • Bloquear todos los agentes (interruptor de emergencia del workspace): cada API key del workspace y cada usuario de base de datos en cada proxy TCP. En el proxy también bloquea a las personas que se conectan a través de él: Vericto no distingue en una conexión a un agente de una persona.

El bloqueo no cambia la allowlist del agente ni sus reglas: al desbloquear, todo vuelve a estar como antes. Cada bloqueo queda en el registro de auditoría y se avisa por los canales del workspace.

Qué pasa en cada vía y cuándo

  • API de runtime, SDK, check_sql del MCP y CLI: al instante. La siguiente llamada recibe BLOCKED con la regla VERICTO-105 y un mensaje que nombra el interruptor de bloqueo y quién lo activó, y le dice al agente que no reintente y que pida ayuda a una persona. No se evalúa nada y no se descuenta de tu cuota.
  • Proxy TCP: en su siguiente sincronización de reglas. El bloqueo llega en GET /sync/rules como una allowlist de acceso de agentes que no permite ninguna tabla para ese usuario de base de datos, así que funciona con los proxies ya desplegados (vericto-proxy 4.16.x y las versiones anteriores con allowlists de acceso de agentes), sin actualizar nada. La sentencia se rechaza con SQLSTATE 42501 en PostgreSQL o el error 1142 en MySQL y la regla VERICTO-087.

El tiempo hasta el proxy es su intervalo de sincronización: 300 segundos por defecto, configurable hasta 30 con VERICTO_RULES_SYNC_INTERVAL_SECS en el proxy o en los ajustes del proxy de la base en el dashboard. Para bases de producción con agentes, recomendamos 30 segundos: el bloqueo llega en 30 segundos como máximo.

Límites del proxy

  • Las sentencias que no leen ninguna tabla (por ejemplo SELECT 1, los SET de sesión habituales, BEGIN y COMMIT) siguen pasando: la allowlist gobierna tablas. Cualquier sentencia que lea o escriba una tabla, y todo DDL, se rechaza.
  • Las sesiones abiertas no se cierran, pero su siguiente sentencia que toque una tabla se rechaza.
  • Mientras el workspace está en modo monitor o en una ventana de observe mode, el proxy solo marca las sentencias del agente bloqueado, sin rechazarlas. El dashboard lo advierte al bloquear. Las vías de API bloquean igual.
  • Un proxy sin VERICTO_DATABASE_ID solo recibe los bloqueos "en todas las bases" y el interruptor del workspace.
  • Vericto no revoca credenciales de base de datos: si el incidente lo justifica, rota la contraseña del usuario de base de datos (ver abajo).

Cómo revocar credenciales

El bloqueo detiene al agente en Vericto. Si la credencial está comprometida, además revócala:

  • La API key del agente: desde el mismo panel de incidentes o en Dashboard → API keys. Es irreversible y se aplica al instante en las vías de API; el agente necesitará una key nueva. No detiene las sesiones del proxy, que se autentican con credenciales de base de datos.
  • El usuario de base de datos: rota su contraseña o desactiva el rol en la base de datos (ALTER ROLE … NOLOGIN en PostgreSQL, ALTER USER … ACCOUNT LOCK en MySQL).
  • Lo demás que use el agente: la política de confianza OIDC con la que obtiene keys en CI y cualquier conexión MCP involucrada.

Verificar y cronometrar

  • El panel de incidentes muestra, para cada bloqueo, qué proxies sincronizaron después del bloqueo y la primera sentencia rechazada en cada vía, con los segundos desde el bloqueo.
  • El Audit Trail muestra las sentencias bloqueadas (VERICTO-105 en las vías de API, VERICTO-087 en el proxy), y el detalle de cada evento nombra el interruptor de bloqueo que lo rechazó.
  • El registro de auditoría (Configuración → Registro de auditoría) guarda agent.blocked y agent.unblocked con el actor, el motivo, el objetivo y la hora.
  • Las alertas llegan a la campana del dashboard, al email del owner y los admins y a los canales Slack, Teams y webhook del workspace (ver alertas).

Hacer un simulacro

Un playbook que nunca se probó no se sabe si funciona. Haz un simulacro al menos cada trimestre y cada vez que cambies la forma en que se conectan tus agentes:

  1. Elige un agente de prueba: una API key y un usuario de base de datos que no use producción.
  2. Pon una sentencia en bucle por cada vía (la API de runtime o un SDK, check_sql o la CLI, y una conexión a través del proxy), una por segundo.
  3. Anota la hora (T0) y bloquea al agente con el motivo "simulacro".
  4. Anota la primera sentencia rechazada en cada vía. El panel de incidentes la muestra con los segundos desde T0.
  5. Desbloquea, comprueba que el agente vuelve a funcionar y anota el resultado en el registro de simulacros del runbook.

Un criterio de aprobación razonable: menos de 5 segundos en las vías de API y, en el proxy, no más que su intervalo de sincronización más 10 segundos.

Cómo desbloquear

Con la decisión del responsable del incidente, el owner o un admin abre el bloqueo en Respuesta a incidentes y elige Desbloquear, con un motivo obligatorio. Se aplica al instante en las vías de API y en la siguiente sincronización en los proxies. El desbloqueo queda en el registro de auditoría y se avisa por los mismos canales que el bloqueo. Una API key revocada no vuelve: el agente necesita una nueva.

Qué exportar para la revisión

  • El reporte del incidente, que se descarga del panel: el bloqueo, sus entradas de auditoría, la propagación a los proxies y los primeros rechazos por vía.
  • El export del Audit Trail de la ventana del incidente.
  • Las entradas del registro de auditoría del bloqueo y del desbloqueo.
  • Los reportes de checks de la CLI y del MCP de la key del agente.
  • El runbook completo, con la cronología: detección, decisión, bloqueo, primer rechazo y desbloqueo.

Plantilla de runbook

Descarga la plantilla en Markdown, complétala con los nombres de tu equipo y guárdala donde la guardia pueda leerla sin el dashboard: plantilla en español · plantilla en inglés. También puedes copiarla desde aquí:

Plantilla en inglés
# AI agent incident runbook

Template from https://vericto.com/docs/incident-playbook. Fill in every `____`, keep a copy
where the on-call team can reach it without the dashboard, and review it after every drill
and every incident.

Last reviewed: ____ by ____

## 1. Who decides

| Role | Person | Backup | How to reach them |
| --- | --- | --- | --- |
| Incident commander (decides to block and to unblock) | ____ | ____ | ____ |
| Vericto owner or admin on call (carries out the block) | ____ | ____ | ____ |
| Database owner (rotates credentials) | ____ | ____ | ____ |
| Agent owner (fixes the agent) | ____ | ____ | ____ |
| Security / compliance contact | ____ | ____ | ____ |

- Anyone who sees an agent misbehaving may ask for a block; the incident commander decides.
- Do not wait for a root cause to block: blocking is reversible, unblocking needs the incident commander.
- Escalate to ____ if the incident commander cannot be reached within ____ minutes.

## 2. Agent inventory

| Agent | Vericto API key name | Database user | Databases | Principal (registry) | Owner |
| --- | --- | --- | --- | --- | --- |
| ____ | ____ | ____ | ____ | ____ | ____ |
| ____ | ____ | ____ | ____ | ____ | ____ |

Proxy rule sync interval of each production database with agents: ____ s (recommended: 30 s).

## 3. Block the agent

- [ ] Note the time (T0): ____
- [ ] Dashboard → Incident response → Block an agent. Pick the API key, the database user (one database or every database), the principal, or "Block all agents". Reason: ____ (ticket ____).
- [ ] Confirm the block is listed as active, and read the coverage and warnings (monitor mode, proxies that cannot apply it).
- [ ] If the credential is compromised: revoke the API key (irreversible) and rotate the database user's password: ____
- [ ] Revoke any OIDC trust policy or MCP connection the agent used: ____
- [ ] Tell the agent owner and the stakeholders: ____

## 4. Verify that it took effect

- [ ] The incident panel shows every proxy as synced since the block.
- [ ] First rejected statement on each path, from the panel or the Audit Trail:

| Path | First rejection (time) | Seconds after T0 |
| --- | --- | --- |
| Runtime API / SDKs | ____ | ____ |
| MCP check_sql / CLI | ____ | ____ |
| TCP proxy (database ____) | ____ | ____ |

- [ ] The admin audit log shows `agent.blocked` with the actor, reason, target and time.
- [ ] The alert reached the channels: ____

## 5. Unblock

- [ ] The incident commander approved the unblock: ____ (time ____)
- [ ] Dashboard → Incident response → Unblock, with the reason: ____
- [ ] The agent works again on each path: ____

## 6. Drill log

Pass criterion: API paths under 5 s; TCP proxy within the sync interval plus 10 s.

| Date | Target | T0 | Runtime API | MCP / CLI | TCP proxy | Unblocked at | Pass / fail | Run by |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ____ | ____ | ____ | ____ | ____ | ____ | ____ | ____ | ____ |

## 7. Post-incident review

- [ ] Incident report downloaded from the incident panel (block record, audit entries, propagation, first rejections).
- [ ] Audit Trail exported for the incident window: ____ to ____
- [ ] Admin audit log entries for the block and the unblock saved.
- [ ] CLI and MCP check reports for the agent's key saved.
- [ ] Timeline written: detection ____, decision ____, block ____, first rejection ____, unblock ____
- [ ] Root cause and fix: ____
- [ ] Follow-ups (allowlist, sensitive columns, rules, sync interval, this runbook): ____
Plantilla en español
# Runbook de incidentes con agentes de IA

Plantilla de https://vericto.com/es/docs/incident-playbook. Completa cada `____`, guarda una
copia donde el equipo de guardia pueda leerla sin el dashboard y revísala después de cada
simulacro y de cada incidente.

Última revisión: ____ por ____

## 1. Quién decide

| Rol | Persona | Suplente | Cómo contactarla |
| --- | --- | --- | --- |
| Responsable del incidente (decide bloquear y desbloquear) | ____ | ____ | ____ |
| Owner o admin de Vericto de guardia (ejecuta el bloqueo) | ____ | ____ | ____ |
| Responsable de la base de datos (rota credenciales) | ____ | ____ | ____ |
| Responsable del agente (corrige el agente) | ____ | ____ | ____ |
| Contacto de seguridad / compliance | ____ | ____ | ____ |

- Cualquiera que vea a un agente comportarse mal puede pedir un bloqueo; decide el responsable del incidente.
- No esperes a conocer la causa para bloquear: bloquear es reversible, y desbloquear necesita al responsable del incidente.
- Escala a ____ si no se puede contactar al responsable del incidente en ____ minutos.

## 2. Inventario de agentes

| Agente | Nombre de la API key en Vericto | Usuario de base de datos | Bases de datos | Principal (registro) | Responsable |
| --- | --- | --- | --- | --- | --- |
| ____ | ____ | ____ | ____ | ____ | ____ |
| ____ | ____ | ____ | ____ | ____ | ____ |

Intervalo de sincronización de reglas del proxy de cada base de producción con agentes: ____ s (recomendado: 30 s).

## 3. Bloquear al agente

- [ ] Anota la hora (T0): ____
- [ ] Dashboard → Respuesta a incidentes → Bloquear un agente. Elige la API key, el usuario de base de datos (en una base o en todas), el principal o "Bloquear todos los agentes". Motivo: ____ (ticket ____).
- [ ] Confirma que el bloqueo figura como activo y lee la cobertura y los avisos (modo monitor, proxies que no pueden aplicarlo).
- [ ] Si la credencial está comprometida: revoca la API key (irreversible) y rota la contraseña del usuario de base de datos: ____
- [ ] Revoca toda política de confianza OIDC o conexión MCP que usara el agente: ____
- [ ] Avisa al responsable del agente y a los interesados: ____

## 4. Verificar que se aplicó

- [ ] El panel de incidentes muestra cada proxy como sincronizado después del bloqueo.
- [ ] Primera sentencia rechazada en cada vía, según el panel o el Audit Trail:

| Vía | Primer rechazo (hora) | Segundos desde T0 |
| --- | --- | --- |
| API de runtime / SDK | ____ | ____ |
| MCP check_sql / CLI | ____ | ____ |
| Proxy TCP (base ____) | ____ | ____ |

- [ ] El registro de auditoría muestra `agent.blocked` con el actor, el motivo, el objetivo y la hora.
- [ ] La alerta llegó a los canales: ____

## 5. Desbloquear

- [ ] El responsable del incidente aprobó el desbloqueo: ____ (hora ____)
- [ ] Dashboard → Respuesta a incidentes → Desbloquear, con el motivo: ____
- [ ] El agente vuelve a funcionar en cada vía: ____

## 6. Registro de simulacros

Criterio de aprobación: vías de API en menos de 5 s; proxy TCP dentro del intervalo de sincronización más 10 s.

| Fecha | Objetivo | T0 | API de runtime | MCP / CLI | Proxy TCP | Desbloqueado a las | Aprobado / no | Lo ejecutó |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ____ | ____ | ____ | ____ | ____ | ____ | ____ | ____ | ____ |

## 7. Revisión posterior al incidente

- [ ] Reporte del incidente descargado del panel (bloqueo, entradas de auditoría, propagación, primeros rechazos).
- [ ] Audit Trail exportado para la ventana del incidente: ____ a ____
- [ ] Entradas del registro de auditoría del bloqueo y del desbloqueo guardadas.
- [ ] Reportes de checks de la CLI y del MCP de la key del agente guardados.
- [ ] Cronología escrita: detección ____, decisión ____, bloqueo ____, primer rechazo ____, desbloqueo ____
- [ ] Causa raíz y corrección: ____
- [ ] Pendientes (allowlist, columnas sensibles, reglas, intervalo de sincronización, este runbook): ____