# Controles de aprobación para agentes de IA: reglas frente a decisiones claras

Un agente de IA no necesita un programa empresarial de autorización en miniatura cada vez que requiere un token de API o una clave SSH. La mayoría de los equipos necesita tres decisiones que sigan siendo comprensibles bajo presión: si el almacén de secretos está disponible, si este proceso del agente puede actuar en esta ejecución y si esta credencial concreta requiere una nueva decisión humana.

Los motores de políticas pueden responder a muchas más preguntas. También pueden convertir cada cambio de permisos en un pequeño proyecto de software, con datos que deben considerarse fiables, reglas que probar, excepciones que explicar y fallos que aparecen justo cuando alguien edita una condición en el peor momento posible. Usa un motor de reglas cuando tu problema de acceso tenga realmente responsabilidades y restricciones variables. No lo uses como adorno alrededor de un límite de aprobación sencillo.

## Un motor de reglas convierte la autorización en mantenimiento de software

Un motor de políticas es código, aunque su sintaxis no se parezca al código. Alguien debe definir los datos disponibles, escribir las reglas, decidir la precedencia, probar los cambios, publicar versiones, investigar coincidencias inesperadas y retirar las reglas que ya no encajan con la organización.

Ese trabajo puede estar justificado. Una empresa puede necesitar que distintos responsables de recursos establezcan condiciones de acceso, restringir acciones por región o entorno, o aplicar requisitos legales y contractuales. En esos casos, un conjunto pequeño de controles fijos puede obligar a tratar casos distintos con una única aprobación demasiado general. El error consiste en tratar esta complejidad como gratuita porque un lenguaje de políticas la oculta detrás de una sintaxis declarativa.

Considera una regla conocida:

```text
allow if
  agent.project == "payments"
  and request.host ends_with ".internal.example"
  and request.method in ["GET", "POST"]
  and time.weekday in ["Mon", "Tue", "Wed", "Thu", "Fri"]
```

Parece razonable hasta que alguien tiene que responder preguntas operativas. ¿Quién asigna `agent.project`? ¿Puede el agente influir en ello? ¿`ends_with` acepta `not-internal.example`? ¿Qué permite POST en un endpoint que puede crear, reembolsar, borrar o activar una transferencia? ¿Qué ocurre durante un incidente el sábado? ¿Una denegación posterior anula una autorización anterior?

Cada pregunta añade semántica. Cada elemento semántico necesita una prueba. Cada excepción pasa a formar parte del modelo de permisos, aunque viva en un mensaje escrito deprisa en un chat y alguien la copie a una regla una semana después.

La documentación de Open Policy Agent describe correctamente las políticas como código y recomienda probarlas. No es un eslogan de marketing sobre la flexibilidad. Es el reconocimiento del contrato operativo: si una política controla un acceso importante, el equipo debe tratar sus cambios como cambios de código. Los revisores necesitan casos preparados. La integración continua necesita decisiones esperadas. Una persona de guardia necesita saber qué versión de la política permitió una solicitud.

Muchos equipos ignoran ese contrato. Pegan unas cuantas reglas en un archivo de configuración y descubren seis meses después que nadie sabe si una denegación se debió a un error tipográfico, a un dato de entrada ausente o a un límite intencionado. Un agente de IA hace más visible este fallo porque genera secuencias inusuales de llamadas y puede recorrer una rama olvidada mucho más rápido que un operador humano.

Los controles fijos reducen el mantenimiento porque se niegan a expresar condiciones arbitrarias. Eso parece limitante porque lo es. La pregunta útil es si esa limitación excluye un requisito que realmente tienes o simplemente una regla futura que alguien quizá quiera algún día.

## La claridad de la decisión importa cuando una llamada tiene consecuencias

Una persona operadora debe poder explicar en una frase por qué se permitió una llamada. Si la respuesta exige leer un conjunto de reglas, resolver la precedencia e inspeccionar atributos proporcionados por el agente, no podrá aprobar o revocar el acceso de forma fiable durante un incidente.

Las decisiones claras también evitan un error de categoría frecuente: una regla puede hacer que una acción esté técnicamente permitida sin hacerla comprensible para la persona que asumirá las consecuencias. Un aviso que dice que un proceso sin nombre solicitó acceso a una capacidad genérica apenas ofrece algo que evaluar. Es una formalidad, no una aprobación.

Una pantalla de autorización útil responde preguntas concretas:

- ¿Qué ejecutable solicitó actuar y quién lo firmó?
- ¿Es un proceso nuevo o uno ya aprobado para esta sesión?
- ¿Qué credencial utilizará la acción?
- ¿A dónde irá la solicitud o con qué host se comunicará SSH?
- ¿La persona está aprobando una ejecución o un uso sensible?

El primer punto merece más atención de la habitual. Los nombres de los agentes son etiquetas. La identidad del proceso es una prueba. Un proceso puede llamarse `release-agent`, mientras que una autoridad de firma de código o una ruta del ejecutable ofrece al revisor algo que resiste que se cambie el nombre de un script de shell. La evidencia de identidad no demuestra que cada instrucción sea segura, pero reduce la pregunta a un principal real.

NIST Special Publication 800-207 estructura la confianza cero alrededor de la verificación explícita y la evaluación continua, en lugar de la confianza heredada de la red. La lección práctica para las acciones de agentes locales es más sencilla de lo que muchas implementaciones hacen parecer: evalúa al actor y la solicitud en el punto de acción. No entregues un token a un agente esperando que el límite siga siendo significativo después de que el token deje de estar bajo tu control.

La claridad de la decisión también es una propiedad de seguridad. Cuando las personas pueden anticipar una aprobación, detectan mejor una inesperada. Si un agente de programación que normalmente lee datos de incidencias solicita de pronto una credencial de escritura en producción, la diferencia debe resultar evidente antes de que la llamada salga del equipo.

## La identidad, la autoridad y el uso de secretos son preguntas distintas

Los equipos suelen juntar tres preguntas separadas en una sola declaración de política y después no pueden saber qué supuesto falló. Mantenlas separadas.

La identidad pregunta quién hizo la solicitud. En un agente local puede incluir el proceso, su autoridad de firma de código, su proceso padre y su duración. Una etiqueta legible del agente puede ayudar, pero no debería tomar por sí sola la decisión de seguridad.

La autoridad pregunta si ese proceso identificado puede realizar acciones en esta ejecución. La aprobación de una sesión encaja aquí. Registra que una persona examinó un proceso nuevo y le permitió utilizar una pasarela de acciones definida hasta que termine o el operador revoque la aprobación.

El uso de secretos pregunta si una clave de API o SSH concreta puede utilizarse para esta acción. Aquí encajan el control de la bóveda y la aprobación por credencial. Una bóveda bloqueada debe denegar todas las acciones, independientemente de una decisión previa sobre la sesión. Una credencial especialmente sensible puede exigir aprobación humana cada vez, incluso cuando el proceso ya tenga autoridad de sesión.

Confundir estas preguntas produce errores previsibles. Un equipo aprueba un proceso de agente una vez y después trata esa aprobación como permiso para usar todas las credenciales. O desbloquea una bóveda y confunde la disponibilidad con la autorización. O escribe una política que comprueba el nombre del proceso y el host de destino, pero permite que el agente recupere el token y lo reutilice en otro lugar.

Este último fallo es el más importante. Si un agente tiene credenciales en texto plano, tu política solo comprobó el primer uso. El agente puede pasar el valor a un subproceso, incluirlo en un registro, enviarlo a otro servicio o utilizarlo después de que expire la aprobación original. Una pasarela que mantiene los secretos fuera del agente cambia el límite: el agente solicita una acción y la pasarela realiza la acción autenticada por sí misma.

La diferencia es más profunda que el «enmascaramiento de secretos». Ocultar una salida después de que el token haya llegado al agente no lo elimina de su memoria, del historial de instrucciones, del entorno del shell ni del proceso hijo. Impedir que el agente reciba el secreto elimina toda una clase de reutilizaciones accidentales.

## Tres controles explícitos cubren el caso habitual de los agentes

Un conjunto pequeño de controles funciona cuando cada control se ocupa de una decisión y ninguno pretende resolver las demás. Para los agentes locales de desarrollo, tres controles cubren gran parte del riesgo real sin crear un lenguaje de políticas.

Primero, usa un control absoluto de la bóveda. Mientras la bóveda esté bloqueada, todas las acciones fallan. Esto ofrece al operador una condición de parada física y conceptual. No debería depender de una evaluación de reglas, de una sesión recordada ni de una comprobación de red. En un Mac, el desbloqueo protegido por hardware mediante Secure Enclave y Touch ID puede hacer que esta decisión sea especialmente clara: el operador ha abierto la bóveda o no lo ha hecho.

Segundo, autoriza un proceso de agente recién detectado durante su vida útil. La aprobación debe identificar el proceso de una forma que resista un cambio de nombre amigable y debe caducar cuando el proceso termine. Este control evita una solicitud para cada petición inofensiva, pero no convierte la aprobación en permanente por defecto.

Tercero, marca determinadas credenciales para que requieran aprobación en cada uso. Hazlo de forma selectiva y deliberada. Una credencial de despliegue que pueda cambiar la infraestructura de producción, una identidad SSH con acceso amplio a hosts o un token que pueda mover dinero pueden justificar una decisión inmediata en cada llamada. Una credencial de desarrollo de solo lectura que el agente usa repetidamente normalmente no la necesita.

La secuencia de decisiones resultante es fácil de razonar:

```text
if vault is locked:
    deny action
else if this agent process has no current session approval:
    ask for session approval
else if the selected credential requires approval per use:
    ask for credential approval
else:
    execute the action
```

Esto no sustituye al principio de mínimo privilegio. La credencial debe seguir teniendo un alcance limitado y la ruta de solicitud necesita seguridad de transporte y validación del destino. La secuencia hace explícito el punto de control humano. No convierte un token de administrador en una credencial segura.

El orden importa. Una solicitud por llamada nunca debe saltarse una bóveda bloqueada. Una sesión recordada nunca debe saltarse una decisión sobre una credencial marcada para aprobación repetida. Con un motor de reglas general, esas relaciones de precedencia suelen vivir en políticas separadas y se vuelven sorprendentemente difíciles de auditar. Con una secuencia fija, el orden es el modelo.

## Un motor de políticas merece su coste cuando varían las responsabilidades

Un motor de políticas está justificado cuando la decisión de autorización debe variar entre muchos recursos administrados de forma independiente y esa variación no puede representarse mediante la elección de credenciales o un conjunto pequeño de clases de aprobación.

Supón que un servicio de automatización compartido gestiona varias unidades de negocio. Cada unidad es responsable de distintos repositorios, cuentas en la nube y almacenes de datos. Los responsables necesitan conceder acceso temporal a grupos definidos, imponer condiciones de conservación diferentes y auditar decisiones dentro de un proceso de gobierno central. Una capa de políticas puede ser el diseño adecuado porque la organización necesita delegar la propiedad de las reglas y aplicar decisiones de forma coherente en un entorno amplio.

Otro buen caso es un servicio del lado del servidor que recibe solicitudes de muchos clientes no fiables. El servicio puede tener que evaluar el inquilino, el rol, la propiedad del objeto, el origen de la solicitud y el estado de la transacción antes de actuar. Una aprobación fija de sesión local no puede sustituir eso. El servidor debe decidir en cada solicitud, aunque no haya una persona cerca para aprobarla.

No extiendas estos casos hasta justificar colocar un motor de políticas delante de cada agente local de programación. En una máquina de desarrollo normalmente la pregunta es más pequeña: ¿puede este proceso de agente firmado usar esta credencial almacenada a través de esta pasarela de acciones mientras el operador lo permite? La persona ya tiene el contexto local. Añadir condiciones sobre franjas horarias, etiquetas de proyecto y puntuaciones de riesgo especulativas puede producir más confianza falsa que control.

Existe otro límite importante. Una política no puede reparar una credencial demasiado amplia. Una regla puede permitir solicitudes a un solo host, pero si el agente puede extraer el token portador, el emisor del token debe imponer su propio alcance. Mantén el secreto en la pasarela y limita sus permisos en el proveedor. Trata la autorización de la pasarela como una capa, no como sustituto del control de acceso del recurso.

## La fatiga de aprobaciones indica que el alcance es incorrecto

Las solicitudes repetidas hacen que las personas actúen más rápido, no con más cuidado. Si alguien ve la misma tarjeta de aprobación veinte veces mientras un agente obtiene metadatos de un repositorio, aprende que hacer clic permite continuar el trabajo. La undécima solicitud que difiera de forma importante recibirá entonces el mismo gesto reflejo.

La respuesta habitual es crear reglas más inteligentes que supriman las solicitudes bajo condiciones cada vez más específicas. Eso suele cambiar una fatiga visible por una complejidad invisible. Alguien escribe una excepción para las llamadas de lectura y después descubre que un endpoint supuestamente de lectura activa un cálculo remoto o expone datos que deberían haber requerido revisión. Bajan las aprobaciones mientras la decisión se vuelve más difícil de inspeccionar.

Define el alcance de la aprobación según el criterio humano necesario. Una aprobación de sesión dice: «Reconozco este proceso y le permito trabajar con las credenciales habituales asignadas a esta ejecución». Una aprobación por llamada dice: «El uso de esta credencial tiene consecuencias suficientes para que lo revise de forma individual». Ninguna solicitud debería existir solo porque una implementación quiere mostrar un cuadro de confirmación.

Un buen diseño de credenciales lo facilita. Divide las credenciales según sus consecuencias en lugar de conservar un único token potente y esperar que una política filtre cada llamada. Da al agente un token limitado para el trabajo normal de desarrollo. Mantén separado el token que cambia producción y exige una decisión explícita cuando se use. Puede que esto cree más credenciales, pero elimina el análisis frágil de solicitudes del límite de autorización.

Una recomendación rechazada merece una respuesta directa: «Exigir aprobación para cada acción del agente» parece seguro porque crea un registro completo de clics humanos. Normalmente es incorrecto para llamadas repetidas de pocas consecuencias. Las personas no pueden revisar bien una avalancha de solicitudes similares. Exige aprobación donde el revisor pueda tomar una decisión concreta y registra el resto para que el equipo investigue el comportamiento real.

## Una regla inofensiva puede autorizar una solicitud dañina

Un fallo común comienza cuando un equipo quiere permitir que un agente actualice un servicio de pruebas. Configura una regla que permite solicitudes POST a `api.example.internal` cuando el agente afirma pertenecer al proyecto `staging`. El agente recibe un token en su entorno porque la pasarela no puede inyectarlo directamente.

Durante una tarea de depuración, el agente sigue un comando copiado que usa el mismo nombre de host, pero un endpoint de administración. El endpoint acepta POST y admite una operación que promociona una configuración a producción. La política ve un método permitido, un host permitido y una etiqueta de proyecto permitida. Devuelve «permitir».

El equipo puede llamar a esto un error de la política, pero hay varios fallos:

1. El método era demasiado amplio para describir la intención.
2. El atributo del proyecto, controlado por el agente, no demostraba la responsabilidad.
3. El host contenía endpoints con consecuencias muy distintas.
4. El token existía fuera del punto de aplicación y podía reutilizarse después de la solicitud.
5. El operador nunca vio una decisión que distinguiera entre actualizaciones de pruebas y promoción a producción.

Añadir patrones de rutas puede cerrar este agujero concreto. Después alguien añade una ruta versionada, un nombre de host alternativo, un endpoint por lotes o un parámetro de consulta que cambia el comportamiento. La política crece porque la credencial subyacente hace demasiado.

Un diseño mejor separa las credenciales de pruebas y producción. La sesión normal puede usar la credencial de pruebas a través de la pasarela. La credencial de producción requiere aprobación en cada uso y la aprobación identifica el destino y la acción. La pasarela inyecta la credencial y devuelve el resultado, mientras el agente nunca recibe su valor.

Este diseño sigue dependiendo de que el proveedor de la API limite correctamente ambas credenciales. Tampoco impide que un agente aprobado haga un cambio incorrecto en pruebas. Sí garantiza que un flujo de pruebas no herede en silencio autoridad de producción mediante una regla laxa y un token reutilizable.

## Prueba las rutas de denegación antes de que el agente las pruebe por ti

Las pruebas de autorización deben demostrar que el sistema rechaza acciones en condiciones esperadas, no solo que una solicitud normal funciona. Los casos útiles son lo bastante pequeños para ejecutarse antes de que el equipo cambie las credenciales o las integraciones del agente.

Para una secuencia fija de decisiones, escribe los resultados esperados en una tabla y mantenla junto a la implementación:

| Estado de la bóveda | Aprobación de sesión | Configuración de credencial | Resultado esperado |
| --- | --- | --- | --- |
| bloqueada | presente | normal | denegar |
| desbloqueada | ausente | normal | solicitar aprobación de sesión |
| desbloqueada | presente | normal | ejecutar |
| desbloqueada | presente | por llamada | solicitar aprobación de credencial |
| desbloqueada | revocada | normal | denegar o solicitar una nueva aprobación de sesión |

Esta tabla detecta una clase importante de regresiones: que un ingeniero añada una ruta de conveniencia que compruebe la autoridad de sesión antes del estado de la bóveda o permita que un proceso recordado se salte una decisión sobre una credencial que requiere aprobación por llamada. La tabla hace que el orden previsto pueda revisarse sin aprender un lenguaje de políticas.

En un motor de políticas, prueba algo más que ejemplos que deberían permitirse. Prueba atributos ausentes, URL mal formadas, nombres de host alternativos, cambios de versión de la política, conflictos entre reglas, cambios de reloj y denegaciones explícitas. El modelo de pruebas de Open Policy Agent admite pruebas de reglas, pero el trabajo difícil sigue siendo tuyo: decide qué datos pueden influir un atacante, un agente defectuoso o una integración futura.

Prueba también la revocación mientras el agente está activo. Inicia una sesión, apruébala, realiza una acción normal, revoca el acceso y repite la misma solicitud. El segundo intento debe producir una denegación en la pasarela de acciones. Una revocación que solo cambia un registro del panel y deja a un proceso con una credencial utilizable no ha revocado la autoridad efectiva.

En HTTP, inspecciona el resultado devuelto con suficiente contexto para diagnosticar el fallo sin exponer las cabeceras de autorización. En SSH, confirma que el asistente usa la identidad seleccionada para conectarse, pero no entrega material de la clave privada al agente que realiza la llamada. Estos detalles parecen triviales hasta que un incidente obliga al equipo a establecer qué poseía realmente el proceso.

## Un registro de auditoría debe responder una pregunta distinta de la solicitud

Los controles de aprobación impiden o permiten una acción en el momento. Un registro de auditoría te dice después qué ocurrió, quién lo aprobó y si alguien alteró el registro. No mezcles ambos trabajos en una función vaga de «responsabilidad».

Un registro de eventos útil incluye la identidad de la sesión, la decisión tomada, la referencia de la credencial en lugar de su valor secreto, el tipo de acción, el destino, el resultado y los datos de ordenación. También debe registrar la revocación de la sesión. Sin ese vínculo, los investigadores pueden ver una solicitud, pero no saber si ocurrió antes o después de que un operador retirara la aprobación.

La evidencia de manipulación requiere una formulación precisa. Una cadena de hashes puede hacer detectable una modificación o eliminación posterior cuando el verificador dispone de los datos esperados de la cadena. No puede demostrar que un sistema comprometido registrara todos los eventos desde el principio. Tampoco puede decidir si una aprobación fue sensata. El registro ofrece pruebas sobre el historial registrado, no una máquina del tiempo.

Para una pasarela local, un registro de auditoría cifrado y ciego a escritura proporciona una separación útil: el componente que ejecuta las acciones registra los eventos, mientras que los lectores habituales consumen diarios proyectados en lugar de reescribir la historia. La verificación sin conexión es especialmente útil porque no requiere un servicio disponible ni una clave de descifrado solo para comprobar la estructura de la cadena.

Sallyport registra las ejecuciones de los agentes en un diario de Sessions y las acciones individuales en un diario de Activity, ambos proyectados desde un registro de auditoría cifrado y encadenado mediante hashes. Su comando `sp audit verify` comprueba la cadena sin conexión sobre el texto cifrado, una buena dirección para un registro que puede ser importante después de que la máquina haya quedado bajo sospecha.

Haz que la revisión de auditoría sea práctica. Cuando un agente te sorprenda, identifica primero el proceso que recibió la aprobación de sesión, enumera las acciones en orden temporal, revoca la sesión activa y examina los registros del proveedor afectado. El diario local explica qué atravesó la pasarela; el servicio de destino explica qué aceptó el sistema remoto.

## Elige el modelo de decisiones más pequeño que puedas operar

Empieza por la ruta de autoridad real, no por un deseo abstracto de flexibilidad. Enumera las credenciales que necesita un agente, identifica cuáles tienen consecuencias que justifican una nueva aprobación y decide cómo puede una persona revocar un proceso activo. Si eso produce tres decisiones estables, mantenlas explícitas.

Adopta un motor de políticas cuando la organización necesite una propiedad y una variación de reglas que no puedan expresarse mediante la separación de credenciales y las aprobaciones de sesión y por llamada. Después acepta la obligación correspondiente: versionar las políticas, probar entradas adversarias, documentar la precedencia, asignar responsables y revisar las excepciones con el mismo cuidado que el código.

El mal diseño no son las «reglas» ni las «solicitudes». El mal diseño es un límite de autorización que nadie puede explicar mientras un agente espera para actuar. Si tu equipo no puede decir por qué se permite una solicitud, reduce el modelo de decisiones antes de intentar hacerlo más inteligente.
