Un agente no debería tocar archivos a ciegas
Si tu agente de IA tiene herramientas, tiene permisos, y los permisos son superficie de ataque. Allowlists, rutas denegadas, auditoría y confirmación humana.
Antes de empezar necesitás
- Idea de qué es un agente de IA con herramientas (tools)
- Saber leer YAML
Al terminar vas a poder
- Pensar un agente como una identidad no humana con permisos
- Escribir una policy con rutas permitidas y denegadas
- Diseñar un audit log de las acciones del agente
- Definir qué acciones exigen confirmación humana
Un agente de IA dejó de ser un chatbot hace rato. Lee archivos, ejecuta comandos, llama APIs, crea tickets, toca repos. Cada una de esas capacidades es un permiso, y cada permiso es superficie de ataque. El riesgo real no es que el modelo escriba algo raro: es que tenga herramientas y las use sobre lo que no debía.
El problema: permisos amplios “por las dudas”
Lo cómodo es darle al agente acceso total al filesystem y a una shell, “así no se traba”. Eso es el equivalente a chmod 777 para agentes: funciona hasta que una instrucción maliciosa —escondida en un archivo que el agente lee, en una página, en un issue— lo convence de leer .env, exfiltrar ~/.ssh/id_rsa o borrar algo importante.
El control: una policy explícita
Mínimo privilegio también aplica a los agentes. Declarás qué puede tocar (allowlist), qué nunca (denylist), y qué necesita aprobación humana.
cat agent-policy.yaml # agent-policy.yaml — política de un agente de archivos
filesystem:
allow_write:
- "./workspace/**" # única zona donde puede escribir
allow_read:
- "./workspace/**"
- "./docs/**"
deny: # nunca, ni leer ni escribir
- "**/.env"
- "**/.env.*"
- "~/.ssh/**"
- "**/secrets/**"
- "/etc/**"
actions:
require_confirmation: # el humano aprueba antes de ejecutar
- "file.delete"
- "shell.exec"
- "network.request"
audit:
log_path: "./logs/agent-audit.jsonl"
log_denied: true # también se registran los intentos bloqueados
Acción denegada: cómo se ve
El agente, influenciado por una instrucción maliciosa, intenta leer un secreto. La policy lo corta antes de que pase nada:
[agente] tool=file.read path="../.env"
[policy] match deny="**/.env" → DENEGADO
[agente] respuesta: no puedo acceder a ese archivo (fuera de política)
No hubo “criterio del modelo” en el medio: hubo una regla que se ejecuta siempre, sin importar lo que diga el prompt.
Auditoría: si no quedó registrado, no pasó
Toda acción —permitida o bloqueada— se escribe en un log append-only. Es tu CloudTrail del agente.
{"ts":"2026-05-02T14:03:11Z","tool":"file.write","path":"./workspace/out.md","decision":"allow"}
{"ts":"2026-05-02T14:03:40Z","tool":"file.read","path":"../.env","decision":"deny","rule":"**/.env"}
{"ts":"2026-05-02T14:04:02Z","tool":"file.delete","path":"./workspace/tmp","decision":"await_confirmation"}
Confirmación humana para lo irreversible
No todo se automatiza. Las acciones destructivas o de alto impacto —borrar, ejecutar shell arbitraria, mandar datos afuera— pasan por un approval gate: el agente propone, un humano confirma.
┌────────────┐ propone ┌──────────────┐ aprueba ┌──────────┐
│ Agente │ ──────────► │ Approval gate│ ──────────► │ Ejecuta │
└────────────┘ └──────────────┘ └──────────┘
│ rechaza
└────────► se descarta + se loguea
Si tu agente tiene herramientas, también tiene superficie de ataque. Dárselas no es el problema; dárselas a ciegas, sí.
Lo que practicás en este lab
Llevátelo a tu repo si querés, pero no es obligatorio: es tu aprendizaje.
- Tu archivo de policy con allowlist, denylist y reglas
- Ejemplo de una acción denegada y por qué
- Un fragmento de audit log de una acción del agente
Reto
Escribí una policy para un agente que solo puede escribir en ./workspace, nunca en ~/.ssh ni en .env, y que pide confirmación antes de borrar. Mostrá un log de una acción permitida y una denegada.
Resolvelo y escribí dos líneas explicando qué pasó. Con eso lo fijás.