8 min de lectura

Cómo las solicitudes de aprobación de agentes evitan aprobar la ejecución equivocada

Las solicitudes de aprobación de agentes necesitan la identidad del proceso y de la sesión para que los revisores autoricen la acción prevista cuando varias ejecuciones comparten una cola.

Cómo las solicitudes de aprobación de agentes evitan aprobar la ejecución equivocada

Una cola de aprobación para agentes autónomos no es una pila de botones de permisos. Es un sistema de atribución activo. Cuando dos o más ejecuciones de agentes pueden solicitar la misma credencial, llamar a la misma API o abrir la misma conexión SSH, el revisor debe poder responder una pregunta concreta antes de aprobar: ¿qué proceso en ejecución me pide autorizar exactamente esta acción?

La mayoría de las interfaces de aprobación fallan porque hacen que cada tarjeta parezca provenir de un actor genérico llamado «el agente». Esa etiqueta no causa problemas durante una demostración con una sola ventana de terminal. Se vuelve peligrosa cuando un agente de programación repara un incidente de producción mientras otro prepara una versión, ambos usan el mismo cliente y ambos solicitan acceso al mismo servicio. El revisor ve un destino conocido, reconoce la tarea en términos generales y aprueba la acción correcta para la ejecución equivocada.

Aprobar es decidir a quién pertenece una acción

Un revisor no aprueba una solicitud HTTP de forma aislada. Aprueba una solicitud porque pertenece a un trabajo concreto que espera que se esté realizando. Si la interfaz no conserva esa relación, el botón de aprobación se convierte en una conjetura disfrazada de control humano.

Trata cada aprobación como una declaración con cinco partes:

  1. Un ejecutable o proceso de agente concreto la inició.
  2. Una sesión concreta de ese proceso sigue activa.
  3. Esa sesión corresponde a una tarea o elemento de trabajo identificado.
  4. Quiere realizar una acción externa específica.
  5. El revisor autoriza o rechaza ese conjunto de elementos.

El quinto punto importa más de lo que parece. «Aprobar el acceso a la API de despliegue» no es una declaración completa. Un revisor puede estar dispuesto a permitir que la ejecución de lanzamiento lea un registro de compilación, pero no que una ejecución de depuración no relacionada cambie una configuración de lanzamiento. El destino por sí solo no transmite el significado.

La diferencia se difumina porque el mismo cliente de agente suele crear ambas ejecuciones. La línea de comandos puede ser idéntica. La autoridad de firma del código puede ser idéntica. La ruta del repositorio puede ser idéntica. El agente incluso puede generar solicitudes casi iguales. Nada de eso convierte dos invocaciones simultáneas en el mismo sujeto de seguridad.

He visto equipos añadir más palabras al resumen de la acción cuando el problema real era la falta de atribución. Cambian «POST /deployments» por «POST /deployments para activar el despliegue de staging de la versión 1.8.4». Eso ayuda a explicar la operación, pero sigue dejando al revisor dos tarjetas que indican que son despliegues de staging. Una frase mejor no puede solucionar la ausencia de un límite de sesión.

La interfaz de aprobación debe hacer visible la jerarquía de identidades. La acción es el objeto principal. El proceso que la inició y la sesión activa explican por qué apareció. La etiqueta de la tarea ayuda al revisor a reconocer la intención, pero no sustituye ninguno de los dos identificadores técnicos.

Un proceso firmado no es una sesión en ejecución

La identidad de firma del código puede indicar a un sistema quién firmó el código, pero no puede decirle al revisor qué invocación de ese código produjo una solicitud pendiente. La documentación de firma de código de Apple marca el mismo límite con otra terminología: los requisitos de código establecen la identidad del código, mientras que un requisito designado describe qué se considera el mismo código entre versiones. Es una evidencia útil sobre el invocador, pero no sustituye a un identificador de ejecución.

Esto importa cuando una solicitud de aprobación empieza así:

Request from: Acme Agent CLI
Signed by: Example Engineering, Team ABCD1234

Es un buen comienzo. Indica al revisor si un cliente esperado solicitó acceso. No responde si se trata del asistente de lanzamientos iniciado hace cinco minutos, del asistente de pruebas que quedó abierto esta mañana o de un comando de shell copiado que se ejecuta en una segunda terminal.

La identidad del proceso y la identidad de la sesión responden preguntas distintas:

CampoPregunta que respondeLo que no puede responder
Autoridad de firma del código¿Quién produjo este ejecutable?¿Qué invocación es esta?
Ruta del ejecutable¿Qué cliente instalado lo inició?¿Qué tarea está realizando?
ID del proceso¿Qué proceso local posee actualmente la conexión?¿Puede una persona reconocerlo después de reinicios?
ID de sesión¿Qué ejecución acotada hizo esta solicitud?¿Tiene sentido la acción solicitada?
Etiqueta de tarea¿Qué pidió el usuario que hiciera esta ejecución?¿La etiqueta es veraz o constituye evidencia suficiente?

No ocultes las dos primeras filas solo porque hayas añadido la cuarta. El revisor necesita la autoridad del proceso para detectar un cliente inesperado. Necesita el ID de sesión para separar clientes esperados que se ejecutan al mismo tiempo. Necesita la etiqueta de la tarea para relacionar un identificador técnico con una idea comprensible del trabajo.

La regla práctica es sencilla: muestra la identidad del proceso como procedencia y la identidad de la sesión como la unidad que se autoriza.

En macOS, usar únicamente un identificador de firma como etiqueta de aprobación es especialmente débil. Apple señala expresamente que varios firmantes pueden declarar los mismos identificadores de firma y recomienda combinar la comprobación del identificador con la categoría de validación y, para código que no pertenece a Apple, con un identificador de equipo. Una tarjeta que muestre solo un nombre de bundle amigable o solo un identificador declarado ofrece al revisor menos evidencia de la que la plataforma puede proporcionar.

No muestres el lenguaje técnico de los requisitos como etiqueta principal. Es preciso, pero la mayoría de los revisores no puede leerlo con suficiente rapidez para tomar una decisión. Presenta la autoridad de firma en lenguaje sencillo, conserva el requisito técnico en los detalles y acompáñalo del nombre reconocible del ejecutable. Después, coloca el identificador de sesión donde pueda verse sin expandir nada.

Da a cada ejecución una identidad de sesión que sobreviva en la cola

El ID de sesión debe existir antes de la primera llamada protegida, mantenerse estable durante toda la ejecución y desaparecer del conjunto de autorizaciones cuando esta termine. Cualquier opción más débil crea ambigüedad cuando aumenta la carga.

Genera un ID opaco con alta entropía al conectarse o registrarse el proceso. Guarda el valor completo en el registro de auditoría, pero muestra un prefijo corto y no ambiguo en la solicitud. La forma visible debe ser suficientemente larga para que dos sesiones activas difícilmente lo compartan, y la interfaz debe hacer que cualquier colisión sea imposible de pasar por alto. No derives el ID únicamente de la hora actual, la posición en la cola, el nombre del repositorio o el ID del proceso.

Un registro interno útil podría tener este aspecto:

{
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "display_id": "7TQ4N8M2",
  "process": {
    "pid": 84172,
    "executable": "/usr/local/bin/agent-cli",
    "signing_authority": "Example Engineering (Team ABCD1234)"
  },
  "task": {
    "label": "Prepare the staging release notes",
    "workspace": "/Users/maya/work/app"
  },
  "started_at": "2026-07-22T16:42:11Z"
}

La etiqueta de la tarea debe proceder de una instrucción visible para una persona o de un título de sesión elegido de forma deliberada, no de una frase generada por el modelo que cambie con cada llamada a una herramienta. El modelo puede proponer la etiqueta, pero el sistema debe fijarla cuando comienza la sesión. Si una sesión pasa de «preparar las notas de la versión» a «rotar la credencial del webhook de producción», el revisor merece un cambio de tarea explícito o una sesión nueva. Reescribir la etiqueta en silencio dificulta la lectura del historial y permite que la ejecución tome prestada la legitimidad de una tarea anterior y más segura.

Usa un ciclo de vida con límites claros:

  • Crea la sesión antes de cualquier acción que use credenciales.
  • Asocia cada solicitud, aprobación, rechazo, cancelación y resultado con esa sesión.
  • Cierra la sesión cuando el proceso que la inició termina o pierde su conexión válida.
  • Revoca la sesión de inmediato cuando el revisor elige revocar.
  • Rechaza las aprobaciones pendientes después del cierre o la revocación, aunque la tarjeta siga visible durante unos instantes.

El último punto evita una carrera sutil pero habitual. Un revisor ve una tarjeta de la ejecución A. La ejecución A termina. Comienza una nueva ejecución B, solicita una acción similar y la tarjeta antigua todavía acepta entradas. Si el servicio de aprobación vincula ese clic a «la última solicitud para esta credencial», el revisor ha aprobado B mientras miraba A. Vincula la tarjeta a un ID de solicitud inmutable y a un ID de sesión. Cuando cualquiera de los dos deja de ser válido, el único botón seguro es cerrar la tarjeta.

Evita etiquetas como «Sesión 1», «Ejecución del agente» o «Tarea actual». Funcionan hasta que comienza la segunda ejecución. Una etiqueta puede ser amigable, pero la interfaz necesita un identificador que siga siendo útil después de que se reinicie un proceso, un portátil entre en reposo o se revise un incidente días más tarde.

Coloca los datos correctos en las dos primeras líneas

Las dos primeras líneas de una solicitud de aprobación deben permitir al revisor distinguirla de cualquier otra solicitud pendiente sin abrir los detalles. Coloca primero la acción solicitada y, justo debajo, indica directamente el proceso y la sesión que la iniciaron.

Una tarjeta práctica tiene este formato:

Allow POST to api.example.internal/v1/releases?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Prepare the staging release notes

Creates a release record named "2026.07.22-rc3"
Credential: release-service-write
[Review request]                         [Deny] [Allow]

La línea de acción indica qué ocurrirá y dónde. La línea de atribución indica quién lo solicitó. La línea de tarea señala con qué trabajo debe relacionar el revisor esa solicitud. La vista previa aporta suficiente información sobre las consecuencias para realizar una primera valoración. El orden es intencionado.

No empieces con «Aprobación solicitada» o «El agente quiere usar un secreto». Ninguna de las dos frases ayuda a ordenar una cola cargada. Tampoco empieces con el nombre de la credencial. Las credenciales son detalles de implementación. Normalmente, un revisor sabe si una solicitud pertenece a la ejecución de lanzamiento correcta antes de saber si release-service-write es la clave almacenada adecuada.

Para SSH, la solicitud equivalente debe indicar el host remoto y la clase de comando, no limitarse a «Acceso SSH». Por ejemplo:

Allow SSH command on build-staging-03.example.internal?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Verify the staging migration

Runs: /usr/local/bin/check-migration --database app_staging
Credential: deploy-ssh
[Review command]                         [Deny] [Allow]

Si el sistema no puede producir una vista previa segura y legible, debe decirlo. «Argumentos del comando no disponibles» es mejor que inventar una frase amigable que oculte una expansión del shell, un script indirecto o una entrada no inspeccionada. El revisor podrá abrir el comando exacto o rechazar la solicitud.

Una buena solicitud no obliga al revisor a deducir la ejecución que la inició a partir de una marca de tiempo. La hora pertenece a los detalles y al registro de actividad. Dos agentes pueden emitir solicitudes en el mismo segundo, y las personas no relacionan de forma fiable una tarjeta con una terminal usando solo las horas. Usa la hora como evidencia complementaria, nunca como la etiqueta que soporta la atribución.

Tampoco coloques el ID de sesión en un pie de página apenas visible. El identificador no es información de diagnóstico residual. En una cola en paralelo, es el campo que impide que el revisor trate dos tarjetas casi idénticas como intercambiables.

Una cola necesita agrupación, pero sin falsas unificaciones

Verificar lo que hicieron los agentes
Ejecuta sp audit verify para comprobar la cadena de auditoría cifrada sin conexión y sin necesidad de una clave.

El trabajo en paralelo crea un problema de orden visual. Agrupar las tarjetas por sesión puede ayudar, pero la agrupación se vuelve peligrosa cuando la interfaz oculta diferencias importantes entre solicitudes.

La cola debe permitir que el revisor vea juntas todas las acciones pendientes de una sesión y conservar una decisión de aprobación por acción cuando sus efectos sean distintos. Un asistente de lanzamientos que necesita tres llamadas de solo lectura a una API puede mostrarse razonablemente como un grupo compacto. Una sesión que quiere leer una incidencia, escribir un registro de despliegue y ejecutar una migración remota debe mostrar tres decisiones separadas porque las consecuencias no son iguales.

El patrón incorrecto es un banner global que diga:

agent-cli requests access to 5 services
[Allow all]

Ese botón pide al revisor que apruebe un conjunto antes de atribuir cada elemento a una ejecución o examinar sus efectos. También fomenta el cansancio ante la cola. Cuantas más veces vea el revisor ese banner, más probable será que desarrolle el hábito de eliminarlo para volver al trabajo.

Una cola mejor usa los encabezados de sesión como contexto, no como una autorización amplia:

Session 7TQ4N8M2 · agent-cli · Prepare the staging release notes
2 pending requests

  GET api.example.internal/v1/builds/rc3             [Allow]
  POST api.example.internal/v1/releases              [Review]

Session C5J1W6PA · agent-cli · Investigate test failure #1842
1 pending request

  SSH build-staging-03.example.internal              [Review]

El revisor puede explorar visualmente por ejecución, pero cada fila sigue haciendo una afirmación independiente. Si el sistema admite un estado de autorización por sesión, muéstralo en el encabezado con un alcance claro: «Esta sesión está autorizada hasta que termine». No hagas que ese estado parezca una aprobación de todas las acciones individuales. La autorización por sesión permite que la ejecución solicite acciones, pero no convierte las acciones inesperadas en esperadas.

El orden también influye en los errores. Una cola puramente cronológica puede intercalar tanto las solicitudes de cinco ejecuciones que el revisor no pueda mantener el contexto de ninguna. Una cola agrupada exclusivamente por sesión puede ocultar una solicitud urgente detrás de una sesión ruidosa. Ofrece ambas vistas: una vista agrupada por defecto para la atribución y otra ordenada por hora para responder a incidentes. Mantén visible la etiqueta de sesión en las dos.

No unas tarjetas solo porque compartan destino y credencial. Dos ejecuciones distintas que escriben en el mismo endpoint crean precisamente la ambigüedad que la cola debe resolver. La similitud es una razón para destacar más la identidad de la ejecución, no para combinar las aprobaciones.

La aprobación debe vincularse a la solicitud exacta que revisó la persona

Una solicitud puede identificar la ejecución correcta y aun así autorizar una solicitud equivocada si la aprobación se aplica a una plantilla modificable en lugar de a una acción inmutable. El revisor debe aprobar una representación concreta de la solicitud, no una solicitud futura que por casualidad reutilice la misma ruta, comando o credencial.

Crea un registro canónico de la acción antes de mostrar la tarjeta. Para HTTP, incluye como mínimo el método, el origen y la ruta normalizados, los encabezados seleccionados por nombre, el alias de la credencial y un resumen criptográfico del cuerpo. Para SSH, incluye la identidad normalizada del host, la cuenta solicitada, el puerto, los bytes del comando y el alias de la credencial. Guarda el material protegido completo dentro del componente de confianza; el agente no debe recibirlo solo porque el revisor necesite ver una solicitud.

Después, vincula la aprobación al registro canónico:

{
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "action_digest": "sha256:2a13c4e0...",
  "expires_at": "2026-07-22T16:47:11Z",
  "decision": "allow_once"
}

Al ejecutar la acción, vuelve a calcular el resumen a partir de la acción que realmente saldrá del equipo. Si difiere, rechaza la aprobación y crea una tarjeta nueva. No trates silenciosamente una solicitud modificada como «suficientemente parecida». Un parámetro de URL cambiado puede redirigir un pago, un encabezado modificado puede alterar el alcance de una cuenta y un argumento de shell cambiado puede convertir un comando de inspección en una escritura.

Aquí fallan muchos sistemas que, por lo demás, están bien pensados. Muestran un resumen revisable, aprueban «usar la credencial X para el endpoint Y» y después permiten que el agente haga una segunda solicitud con esa autorización amplia. El revisor no ha revisado la segunda solicitud. El sistema ha convertido una decisión explícita en una regla de política invisible.

Usa una caducidad breve para las aprobaciones pendientes. El objetivo no es castigar a un revisor que se toma un descanso. Es impedir que una decisión antigua se aplique después de que cambie el contexto. Si el agente todavía necesita la acción más tarde, puede crear una solicitud nueva con los mismos datos del proceso y la sesión. El revisor podrá comprobar si sigue perteneciendo a esa ejecución.

El material de NIST sobre la participación humana en decisiones automatizadas advierte del sesgo de automatización y de los ciclos de aprobación de baja fricción que normalizan la fatiga ante las alertas. La consecuencia práctica es clara: hacer que las aprobaciones sean fáciles de pulsar no las vuelve significativas. La interfaz debe hacer que la decisión sea lo bastante pequeña para inspeccionarla y lo bastante específica para permitir atribuir responsabilidades.

La vista de detalles debe resolver disputas, no crearlas

Mantener el punto de control local
Una sola app de Mac firmada en la barra de menús gestiona la bóveda y las acciones, sin necesidad de administrar un daemon independiente.

Una tarjeta compacta no puede contener todos los bytes de una solicitud. Sí necesita una vista de detalles que responda a las preguntas que un revisor cuidadoso se hace cuando la acción es desconocida, costosa o sospechosa.

Para una acción HTTP, muestra el método y la URL completos, los encabezados redactados de forma predeterminada, los campos del cuerpo indicando claramente cómo se tratan los secretos, el alias de la credencial, la identidad del proceso que la inició, el ID de sesión, la etiqueta de la tarea y la hora de creación de la solicitud. Si el cuerpo es binario o demasiado grande, muestra su tamaño, el tipo de contenido y el resumen criptográfico. No finjas que un resumen de una sola línea es un sustituto adecuado.

Para SSH, muestra el host, el usuario, el puerto, el estado de verificación del host cuando esté disponible, el comando exactamente como se ejecutará, el directorio de trabajo si es relevante y cualquier valor de entorno que afecte al comportamiento. La vista previa debe conservar las comillas y los límites entre argumentos. Convertir un array en una cadena de shell unida de forma imprecisa puede hacer que un comando seguro parezca peligroso o, peor aún, que uno peligroso parezca inofensivo.

Hay una diferencia clara entre redactar por seguridad y omitir por comodidad. Redacta un token bearer, una clave privada, una contraseña o un valor sensible del cuerpo en la solicitud. No ocultes la ruta, la cuenta de destino, el host remoto, el comando ni el campo modificado solo porque los detalles alarguen la tarjeta. A menudo, esos son los datos que permiten saber si la solicitud pertenece a esta ejecución.

Usa una huella estable de la solicitud en la vista de detalles. Un revisor que escriba a un compañero debe poder decir: «He rechazado la solicitud apr_K9H2D7LQ de la sesión 7TQ4N8M2», y el compañero debe encontrar exactamente un registro. Nunca obligues a describir un evento como «la segunda solicitud de despliegue alrededor de las 4:40». Esa forma de hablar deja de servir cuando un incidente exige precisión.

La superficie de revisión también debe indicar qué autoriza y qué no autoriza la aprobación. Por ejemplo:

Allow once
This decision authorizes only this POST request with digest 2a13c4e0…
It does not authorize later calls from session 7TQ4N8M2.

Esa frase merece su espacio. Impide que el revisor suponga que ha concedido un permiso amplio y evita que un implementador amplíe después el alcance detrás de la misma etiqueta del botón.

La cancelación y la revocación necesitan consecuencias visibles

Tarde o temprano, un revisor aprobará la tarjeta equivocada o advertirá que una ejecución se ha desviado. La recuperación debe ser rápida, visible y estar vinculada a los mismos identificadores usados durante la aprobación.

La interfaz necesita acciones separadas para rechazar una solicitud y revocar una sesión. Rechazar significa «no realices esta acción». Revocar significa «este proceso en ejecución ha perdido su autorización, cancela sus aprobaciones pendientes y rechaza sus acciones posteriores». Como las consecuencias son distintas, no deben compartir un botón ambiguo de «Detener».

Cuando un revisor revoque una sesión, muestra una confirmación que indique el proceso, el ID de sesión y la tarea:

Revoke session 7TQ4N8M2?
agent-cli is running “Prepare the staging release notes.”
Pending requests from this session will be cancelled. New protected actions
from this process will be denied until it starts a new session.
[Keep session] [Revoke session]

Si una solicitud ya se está ejecutando, informa de ello con honestidad. Una revocación puede impedir futuras acciones privilegiadas, pero quizá no pueda deshacer una solicitud HTTP que un servicio remoto ya aceptó ni detener un comando remoto que ya comenzó. El registro de actividad debe indicar si la acción estaba pendiente, fue enviada, se completó, falló o se canceló. No escribas «revocada» de manera que implique que el efecto externo desapareció.

Esta es otra razón para mostrar el ID de sesión en cada tarjeta. Durante un incidente estresante, el revisor necesita un vínculo directo entre una solicitud sospechosa y el control que detiene esa ejecución. Si la cola solo dice «agent-cli», la revocación puede terminar con la ejecución útil y dejar activa la incorrecta.

El diario de sesiones y el diario de actividad deben coincidir en sus identificadores. Un registro indica que la sesión de proceso 7TQ4N8M2 comenzó, recibió autorización y fue revocada. El otro indica qué acción individual intentó antes y después de cada cambio de estado. Si esos registros usan etiquetas que no tienen relación, los responsables pierden tiempo reconstruyendo asociaciones que el producto debería haber hecho explícitas.

Prueba la aprobación de la ejecución equivocada antes que los usuarios

Vincular la aprobación a un proceso
Una aprobación de sesión cubre un solo proceso de agente hasta que termina, no todos los procesos que usan el mismo cliente.

Puedes probar este fallo sin un equipo de seguridad ofensiva ni una interrupción en producción. Ejecuta dos instancias del mismo cliente de agente contra el mismo espacio de trabajo y pídeles que realicen llamadas protegidas similares. La prueba solo tiene éxito si un revisor puede identificar correctamente cada solicitud mientras observa una cola cargada.

Haz este ejercicio:

  1. Inicia la ejecución A con la etiqueta «Inspeccionar la compilación de staging fallida».
  2. Inicia la ejecución B con la etiqueta «Publicar el registro de lanzamiento de staging».
  3. Haz que ambas ejecuciones soliciten la misma credencial con pocos segundos de diferencia.
  4. Haz que sus primeras solicitudes sean similares, por ejemplo, dos llamadas al mismo origen de API.
  5. Cambia una acción de modo que aprobarla para la otra ejecución produzca un efecto visible e indeseable en un entorno de prueba.

Después, pide a alguien que no haya creado la interfaz que apruebe únicamente la solicitud de la ejecución B. No le digas qué tarjeta es B por su posición en la cola. Observa qué utiliza. Si depende de las marcas de tiempo, del orden de las tarjetas o del recuerdo de qué terminal abrió primero, la interfaz ha fallado. Si puede señalar la autoridad del proceso, el ID de sesión, la tarea, el destino y la acción sin abrir otra pantalla, tienes un punto de partida utilizable.

Prueba también el comportamiento de las aprobaciones obsoletas. Crea una tarjeta para la ejecución A, termina A, inicia B y pulsa la tarjeta antigua. El sistema debe rechazar el clic y explicar que la solicitud ya no está activa. Repite la prueba después de cambiar el cuerpo de una solicitud o un argumento SSH tras la revisión. El sistema debe exigir una aprobación nueva en lugar de aplicar la antigua a la acción modificada.

Prueba nombres que colisionen. Dos tareas pueden llamarse «Corregir CI». Dos repositorios pueden tener el mismo nombre de directorio. Dos ramas pueden compartir un número de lanzamiento. El texto amigable ayuda a las personas, pero el diseño completo debe seguir funcionando cuando ese texto sea ambiguo.

La autorización por sesión de Sallyport ofrece un lugar natural para establecer este límite: la primera llamada de un proceso de agente nuevo identifica esa ejecución para su aprobación, mientras que las claves por llamada pueden exigir una aprobación independiente para cada uso. Mantén visible la etiqueta de sesión y la autoridad del proceso cuando aparezcan esos controles, o las ejecuciones paralelas volverán a convertirse en un «agente» indistinto.

El registro de auditoría debe reproducir la decisión de aprobación

Un registro de auditoría solo es útil si puede responder, después de los hechos, qué vio el revisor y qué ejecutó el sistema. Registrar «el usuario aprobó el acceso a la API» no basta. Deja sin resolver la cuestión central: ¿acceso para qué ejecución, para qué acción y con qué contexto visible?

Para cada decisión, registra los identificadores inmutables y los datos que se mostraron:

{
  "event": "approval_granted",
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "process_identity": "agent-cli / Example Engineering (Team ABCD1234)",
  "task_label": "Prepare the staging release notes",
  "action_digest": "sha256:2a13c4e0...",
  "displayed_action": "POST api.example.internal/v1/releases",
  "decision_scope": "once",
  "recorded_at": "2026-07-22T16:44:03Z"
}

Guarda el registro canónico de la acción por separado o junto a él, con el cifrado y los controles de acceso adecuados. El evento de auditoría debe indicar qué decía la tarjeta; el registro canónico debe demostrar qué bytes y qué destino utilizó el componente de confianza. Si ambos difieren, trátalo como un defecto de seguridad, no como un detalle de registro.

Un registro encadenado mediante hashes ayuda a detectar modificaciones del historial, pero no corrige un contenido impreciso. Puedes demostrar criptográficamente que «aprobación concedida» no fue alterado y aun así no saber qué solicitud recibió esa aprobación. La integridad y la atribución resuelven problemas distintos. Necesitas ambas.

Los proyectos de Sallyport registran las sesiones y las llamadas individuales en un único registro de auditoría cifrado y encadenado mediante hashes, y su comando sp audit verify verifica la cadena sin conexión sobre el texto cifrado. Esto resulta útil porque los revisores pueden conservar pruebas de que el registro no fue reescrito sin exponer los secretos almacenados durante la verificación.

La prueba final del diseño es sencilla. Elige cualquier acción completada y retrocede desde el resultado: ¿puede un investigador identificar el proceso, la sesión concreta, la etiqueta de tarea mostrada en ese momento, la solicitud exacta revisada, el alcance de la decisión del revisor y el resultado? Después, avanza desde una sesión: ¿puede ver en orden todas las acciones pendientes, rechazadas, aprobadas, canceladas y ejecutadas? Si alguna de las dos direcciones requiere hacer conjeturas, la cola de aprobación todavía permite el error de aprobar la ejecución equivocada.

Los agentes en paralelo harán que las colas de aprobación sean habituales. La solución no es sepultar a los revisores bajo más tarjetas ni darles un control amplio de «permitir todo». Da a cada proceso en ejecución una identidad de sesión duradera, colócala junto a la acción donde realmente miran las personas y vincula cada clic a la solicitud que revisaron. Así una aprobación conserva su significado cuando hay varios agentes activos a la vez.

FAQ

¿Qué es una cola de aprobación de agentes en paralelo?

Una cola de aprobación de agentes en paralelo reúne las solicitudes generadas al mismo tiempo por más de un proceso de agente. El revisor necesita suficiente contexto para saber qué proceso en ejecución creó cada solicitud, en lugar de tratar todas las tarjetas como solicitudes intercambiables de «el agente».

¿Por qué no basta con el nombre del proceso para aprobar acciones de agentes?

El nombre de un proceso indica quién inició el trabajo, pero no identifica una ejecución concreta. Dos ventanas de terminal pueden ejecutar el mismo cliente firmado y enviar solicitudes similares, por lo que la tarjeta de aprobación también necesita un ID de sesión y una etiqueta breve de la tarea.

¿Cómo debe ser el ID de sesión de un agente?

Usa un ID de sesión estable y opaco, generado cuando el proceso del agente se conecta, y mantenlo sin cambios hasta que el proceso termine o sea revocado. No uses la posición en la cola, un contador de solicitudes por sí solo ni una marca de tiempo como única identidad de sesión.

¿Qué información debe aparecer primero en una solicitud de aprobación?

Coloca primero la acción y el destino, y justo debajo identifica el proceso y la sesión que la iniciaron. Normalmente, los revisores deciden si la acción corresponde al trabajo previsto antes de examinar encabezados, opciones de comandos o cuerpos de solicitudes.

¿Las solicitudes de aprobación deben mostrar el comando o la solicitud HTTP completa?

La tarjeta debe mostrar una vista previa breve y permitir inspeccionar el comando, la URL, el destino, el método y los campos modificados exactos. No obligues al revisor a aprobar un resumen impreciso porque la solicitud completa está escondida en un registro de actividad.

¿Cómo puedo evitar que las tarjetas de aprobación queden obsoletas?

No permitas que una tarjeta cambie de significado silenciosamente después de aparecer. Vincula la aprobación a un resumen criptográfico inmutable de la solicitud, hazla caducar cuando termine la sesión y rechaza la acción si el proceso intenta reutilizarla con argumentos modificados.

¿Puedo usar un ID de sesión corto en una solicitud de aprobación?

Usa un identificador duradero que una persona pueda comparar entre la tarjeta de aprobación, el diario de sesiones y el registro de actividad. Una versión corta para mostrar está bien, pero debe corresponder sin ambigüedad al ID completo del registro de auditoría.

¿Qué debe ocurrir cuando se revoca una sesión de agente?

La cancelación debe identificar la sesión afectada e informar al revisor qué ocurrirá con las solicitudes pendientes. Si la revocación las cancela, dilo claramente. Si una solicitud ya aprobada todavía puede completarse, muestra ese estado en lugar de dar a entender que la cancelación detuvo todo.

¿Cuál es la diferencia entre la aprobación de sesión y la aprobación por llamada?

La aprobación por sesión responde «¿puede ejecutarse este proceso?». La aprobación por llamada responde «¿puede realizar esta acción concreta ahora?». Surgen problemas cuando una aprobación amplia de sesión se presenta como si demostrara que todas las solicitudes destructivas posteriores son esperadas.

¿Cómo puedo probar una cola de aprobación de agentes?

Empieza con ejecuciones simultáneas que usen intencionadamente el mismo cliente de agente, repositorio, credencial y endpoint. Si un revisor no puede saber qué tarjeta corresponde a cada ejecución en una captura con los detalles contraídos, la cola no está lista para un uso real.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov