Idea en 30 segundos
Allowlist en runtime define qué tools puede invocar el agente. Blocklist solo prohíbe una parte de tools dentro de un conjunto ya grande.
Cuándo se necesita: cuando un agente tiene acceso a APIs reales, acciones de escritura o recibe tools nuevos con frecuencia en producción.
Problema
Muchos equipos empiezan con blocklist: “prohibimos las herramientas peligrosas”. Al principio parece rápido y cómodo. En producción, este modelo se rompe pronto.
La razón es simple: cada tool nuevo queda disponible automáticamente si no se bloquea explícitamente. Es decir, el acceso crece por defecto, no por una decisión explícita.
Analogía: es como una oficina sin lista de puertas permitidas, pero con una lista de “no entrar aquí”. En cuanto aparece una sala nueva, queda abierta para todos hasta que alguien recuerde bloquearla.
Solución
La solución es definir default deny en el policy layer y permitir tools solo mediante allowlist.
La blocklist queda como freno de emergencia adicional para modo incidente, no como modelo principal de acceso.
El policy layer devuelve una decisión técnica por cada llamada: allow, deny o approval_required.
Esta decisión se toma en cada paso, no solo al final del run.
Es una capa separada del sistema, no parte del prompt ni de la lógica del modelo.
Allowlist ≠ Blocklist
Son enfoques de control distintos:
- Allowlist: solo está permitido lo que se agrega explícitamente a la policy.
- Blocklist: todo está permitido, excepto lo que se prohíbe explícitamente.
Uno sin el otro no es suficiente:
- sin allowlist, los accesos se expanden entre releases casi sin notarlo
- sin blocklist, es más difícil desactivar de emergencia un tool concreto durante un incidente
Ejemplo:
- allowlist:
search.read,kb.read,refund.lookup - incident blocklist: negar temporalmente
browser.runpor un vendor inestable
Métricas de control de acceso a tools
Estas métricas y señales trabajan juntas en cada paso del agente.
| Métrica | Qué controla | Mecánicas clave | Para qué |
|---|---|---|---|
| Default deny | Regla base de acceso | default = denydeny by default | Un tool nuevo no queda disponible automáticamente |
| Allowlist | Qué tools están permitidos | nombres explícitos de tools capability scoping | Define límites explícitos para la ejecución en runtime |
| Incident blocklist | Bloqueos temporales de emergencia | incident mode deny list time-bound rules | Permite reducir riesgo rápido sin release |
| Write escalation | Acciones de escritura riesgosas | approval_requiredseparate write policy | Evita acciones irreversibles sin control |
| Policy observability | Visibilidad de decisiones de policy | audit logs alerts on deny spikes | No limita acciones de forma directa, pero muestra dónde y por qué se bloquea el acceso |
Cómo se ve en la arquitectura
El policy layer (tool gateway) se ubica entre runtime y tools, y es el único punto de control de acceso antes de cada paso.
Cada decisión (allow, deny, approval_required) se registra en el audit log.
Cada paso del agente pasa por este flow antes de ejecutarse: runtime no ejecuta la acción directamente, primero hay verificación de policy y después ejecución.
Para acciones de escritura, la policy puede devolver approval_required; ese es un flow de confirmación separado que no se muestra en este diagrama (ver Human approval).
Resumen del flow:
- Runtime forma el tool call
- Policy layer aplica
default deny, luego allowlist e incident blocklist allow-> se ejecuta el tool calldeny-> se devuelve un stop reason- cada decisión se escribe en audit log
En runtime, deny se convierte en un stop reason explícito visible en logs y en la respuesta del run.
Ejemplo
Un agente de soporte recibe una solicitud para cerrar tickets de forma masiva.
El tool ticket.close_bulk no está en la allowlist, así que la llamada se bloquea de inmediato.
Durante un incidente separado, el equipo agrega browser.run a la incident blocklist.
Aunque ese tool esté en la allowlist, el policy layer devuelve temporalmente deny("incident_deny").
La allowlist limita el acceso base y la blocklist aporta control rápido de emergencia.
En código se ve así
En el esquema simplificado de arriba se muestra el control flow principal. En la práctica, la verificación se ejecuta en un único lugar: policy layer antes de cada paso.
Ejemplo de configuración de allowlist:
policy:
default: deny
allowlist:
- search.read
- kb.read
- refund.lookup
incident_blocklist:
- browser.run
decision = policy.evaluate(tool, user_context, mode="normal")
if decision.outcome == "approval_required":
if not approval.ok():
audit.log(run_id, decision.outcome, reason=decision.reason, tool=tool)
return stop(decision.reason)
else:
audit.log(run_id, "approval_granted", reason="human_approved", tool=tool)
elif decision.outcome == "deny":
audit.log(run_id, decision.outcome, reason=decision.reason, tool=tool)
alerts.notify_if_needed(run_id, decision.reason, tool=tool)
return deny(decision.reason)
result = tool.execute(args)
decision = Decision.allow(reason="policy_ok")
audit.log(run_id, decision.outcome, reason=decision.reason, tool=tool, result=result.status)
return result
Cómo se ve durante la ejecución
Escenario 1: tool fuera de allowlist (deny)
1. Runtime forma una llamada a ticket.close_bulk.
2. Policy layer verifica la allowlist.
3. Decisión: deny (tool_not_allowed).
4. Audit: decision=deny, tool=ticket.close_bulk, reason=tool_not_allowed.
5. La acción no se ejecuta.
---
Escenario 2: bloqueo por incidente (incident_deny)
1. Runtime forma una llamada a browser.run.
2. El tool está en allowlist, pero el modo incidente está activo.
3. Policy layer verifica la blocklist y devuelve deny (incident_deny).
4. Audit: decision=deny, tool=browser.run, reason=incident_deny.
5. El run se detiene sin llamar al tool.
---
Escenario 3: llamada permitida (allow)
1. Runtime forma una llamada a kb.read.
2. Policy layer verifica reglas: allow.
3. El tool se ejecuta.
4. Audit: decision=allow, tool=kb.read, result=ok.
5. El resultado vuelve al runtime.
Errores típicos
- usar blocklist como modelo principal de acceso
- no usar
default denypara tools nuevos - permitir wildcards como
*sin límites estrechos - mantener tools “universales” como
workflow.run_anything - loguear solo allow y no deny/approval_required
- verificar acceso en prompt o UI en lugar de policy layer
Como resultado, el acceso parece controlado, pero en realidad se expande en cada release.
Autoevaluación
Chequeo rápido de policy allowlist antes de lanzar a producción:
Progreso: 0/8
⚠ Faltan controles base de governance
Antes de production necesitas como mínimo control de acceso, límites, audit logs y parada de emergencia.
FAQ
P: ¿Se puede operar producción solo con blocklist?
R: Para producción, no. Blocklist sirve como mecanismo de emergencia, pero el modelo base debe ser default deny + allowlist.
P: ¿Cómo empezar con allowlist?
R: Empieza con un conjunto mínimo de tools read-only. Agrega acciones de escritura por separado, con condiciones explícitas y approval.
P: ¿Una allowlist wildcard (crm.*) está bien?
R: Solo en casos acotados y con revisión regular. Si no, el wildcard se convierte rápido en default-allow oculto. Por ejemplo, crm.* permitirá crm.delete_all_contacts si ese tool aparece en el siguiente release.
P: ¿Dónde implementar estas verificaciones?
R: En un policy layer centralizado (tool gateway), no en el prompt ni en la lógica de UI.
P: ¿Qué hacer si hay que desactivar un tool con urgencia?
R: Añádelo a la incident blocklist, registra la razón en audit log y luego vuelve a la policy allowlist permanente.
Dónde encaja en el sistema general
Allowlist/blocklist es una de las capas de Agent Governance. Junto con RBAC, presupuestos, approval y audit forma un sistema unificado de control de ejecución.
Páginas relacionadas
Siguiente sobre este tema:
- Resumen de Agent Governance — modelo general de control de agentes en producción.
- Control de acceso (RBAC) — cómo combinar roles, permissions y tenant scope.
- Control de presupuestos — cómo limitar gasto por run en el nivel de runtime.
- Human approval — cómo añadir confirmación para acciones riesgosas.
- Audit logs para agentes — cómo depurar decisiones de policy en incidentes.