8 min de lectura

La vinculación de solicitudes de aprobación impide cambios después del clic

La vinculación de solicitudes de aprobación impide que un cliente de IA cambie una solicitud HTTP o un comando SSH después de que una persona haya aprobado la acción.

La vinculación de solicitudes de aprobación impide cambios después del clic

Una aprobación humana solo tiene sentido si autoriza una acción que ya no puede cambiar. Mostrar la solicitud HTTP o el comando SSH propuesto por un agente y permitir después que ese mismo agente envíe los datos finales deja una brecha entre la comprobación y el uso lo bastante grande como para hacer pasar una solicitud destructiva.

He visto este error llegar con un aspecto tranquilizador: una elegante hoja de aprobación, una insignia con la identidad del proceso y un estado de confirmación en verde. Después, la implementación devuelve por el protocolo un token de aprobación que conserva el cliente y acepta junto a él una URL o un comando nuevos. La persona aprobó una cosa. El ejecutor hizo otra. Es un diseño de autorización fallido, aunque nadie pretendiera eludirlo.

Una vista previa debe describir un objeto de autorización inmutable

La pantalla de aprobación debe mostrar un objeto de acción almacenado, y el ejecutor debe enviar ese mismo objeto después de la aprobación. La pantalla muestra el estado de referencia, no pide al cliente que repita su propuesta con más cuidado.

Crea el objeto antes de mostrar cualquier aprobación. Asígnale un identificador de acción aleatorio, relaciónalo con el proceso y la sesión que hacen la solicitud, resuelve las entradas específicas del canal y guárdalo en memoria o en almacenamiento local cifrado bajo el control del ejecutor. El cliente puede recibir un estado pendiente y un identificador. No debe recibir una capacidad que le permita añadir nuevos parámetros de ejecución más tarde.

Un modelo mental útil es un ticket de restaurante, no una autorización abierta. La cocina no pide al cliente que vuelva a describir la cena después de que el camarero marque el ticket como aprobado. Prepara lo que dice el ticket que tiene. Si el pedido cambia, la cocina recibe un ticket nuevo y el cliente ve el cambio.

El objeto inmutable debe incluir más datos que los campos visibles en una vista previa compacta. También necesita la identidad del proceso, el identificador de sesión, la hora de creación, la hora de expiración, el canal, la referencia de la credencial, los detalles de la acción normalizados y un resumen hash de vinculación. El resumen permite detectar mutaciones accidentales y sustituciones deliberadas, pero la verdadera labor de seguridad la hace el control del objeto por parte del ejecutor.

Por tanto, una respuesta de aprobación solo debería significar esto: «aprobar la acción 7c91... con el resumen de vinculación sha256:...». No debe significar «este proceso puede realizar una llamada HTTP» ni «el autor de la llamada puede ejecutar más tarde el comando X». Esas afirmaciones más amplias tienen su lugar en la autorización de sesión, pero no pueden sustituir el consentimiento para un efecto secundario concreto.

Esta diferencia importa especialmente con los agentes autónomos, porque el cliente no es un empleado de confianza que transcribe fielmente una decisión humana. Es un programa activo que puede reintentar, encadenar llamadas posteriores, cambiar de plan después del resultado de una herramienta o contener un error. Considera sospechoso cualquier campo que todavía pueda influir después de la vista previa.

Una vista previa HTTP debe nombrar todas las entradas efectivas

Una aprobación HTTP vincula el método, el destino completo, las cabeceras efectivas, el cuerpo y el comportamiento de envío que puedan cambiar el significado de la solicitud. Una vista previa que diga «POST al servicio de facturación» da a la persona demasiada poca información para aprobar una llamada que cambia el estado.

RFC 9110 separa el método, el destino, los campos y el contenido de la solicitud porque los servidores pueden asignar un significado distinto a cada elemento. El código de autorización debe mantener esa separación. No construyas una frase agradable para la hoja de aprobación y dejes que una capa inferior rellene después las partes incómodas.

Para una solicitud saliente, captura estos valores después de resolver las plantillas y los valores predeterminados:

  • Esquema, nombre de host, puerto, ruta y cadena de consulta.
  • Método HTTP y posibilidad de seguir redirecciones.
  • Cada nombre y valor de cabecera efectivo, excepto los secretos que inyecta la bóveda.
  • Los bytes finales del cuerpo, su tipo de contenido, longitud y resumen hash.
  • La referencia de la credencial y el modo de inyección, como bearer o una cabecera personalizada.

El valor de la credencial no pertenece a la vista previa ni al contexto del agente. La persona necesita suficiente información para valorar su uso. «Credencial de pagos de producción enviada solo a api.example.test como token bearer» cuenta una historia distinta de «credencial adjunta». El ejecutor puede mostrar esa descripción a partir de un registro de la bóveda sin revelar el token.

No apruebes una plantilla sin expandir. Supón que el agente propone POST /users/{id}/role con un cuerpo que contiene {role}. Si otro componente expande esas variables después de la aprobación, puede cambiar el destino efectivo o el privilegio. Resuelve primero las variables y crea después el objeto de acción. Si una entrada no está disponible intencionadamente hasta más adelante, solicita la aprobación cuando se vuelva concreta.

Las cabeceras merecen más atención de la que suelen recibir. Una cabecera duplicada, un Content-Type modificado, una cabecera de sobrescritura añadida o una codificación de consulta diferente pueden cambiar el comportamiento del servidor aunque el resumen amistoso parezca idéntico. Conserva los campos repetidos en orden cuando el protocolo o el servidor de destino den importancia al orden. Rechaza las entradas ambiguas en lugar de unirlas silenciosamente con comas.

Una estructura interna razonable podría ser la siguiente. Es un patrón de implementación, no un contrato de endpoint:

{
  "action_id": "7c91e2d4",
  "binding": "sha256:4f06...",
  "caller": {"session": "p-481", "process_start": "..."},
  "http": {
    "method": "PATCH",
    "url": "https://api.example.test/v1/users/42",
    "headers": [["content-type", "application/json"]],
    "body_sha256": "a4d8...",
    "body_length": 31,
    "redirects": "deny"
  },
  "credential_ref": "vault:payments-prod"
}

Después de que la persona apruebe este objeto, la capa de transporte lee http y credential_ref de su propio registro almacenado. No acepta del cliente una segunda URL, un mapa de cabeceras ni un cuerpo. Esta última regla evita el error; el resumen solo demuestra a qué registro se refería la aprobación.

Los comandos SSH necesitan su contexto de ejecución resuelto

Una vista previa de un comando SSH debe vincular el contexto de ejecución remoto, porque la cadena del comando por sí sola no dice a la persona qué se ejecutará. El mismo texto puede tener efectos distintos con otro usuario, host, shell, directorio de trabajo, entorno o flujo de entrada estándar.

RFC 4254 define una solicitud de protocolo de conexión SSH para ejecutar comandos, pero no crea un límite de aprobación comprensible para una persona. SSH transporta una cadena de comandos al servidor. La interpretación del shell remoto, la configuración de la cuenta, los comandos forzados y los envoltorios de comandos pueden añadir un significado que una vista previa básica omite.

Guarda y muestra el nombre de host, el puerto, el usuario remoto, la expectativa de autenticación del host, la referencia de identidad, los bytes exactos del comando, el modo de ejecución, la asignación del terminal, el directorio de trabajo, el entorno proporcionado y el resumen hash y la longitud de la entrada estándar. Para una operación de archivos realizada mediante un asistente SSH, vincula también la ruta remota, el tipo de operación, el resumen hash del archivo y cualquier comportamiento de sobrescritura.

El modo de ejecución no es un detalle estético. Estos comandos no son intercambiables:

/usr/local/bin/deploy --environment=staging
sh -lc '/usr/local/bin/deploy --environment=staging'

El primero solicita una ejecución directa si el asistente la admite. El segundo pide explícitamente a un shell que analice la cadena. El análisis del shell introduce expansión, sustitución de comandos, comportamiento de inicio del shell y reglas de comillas. Si tu producto admite ambos modos, identifícalos claramente y nunca conviertas uno en otro después de la aprobación.

No crees una vista previa a partir de un comando formateado para mostrarlo y ejecutes un array ensamblado por separado. Una cadena para mostrar puede ocultar un argumento vacío, un salto de línea, un carácter no imprimible o la diferencia entre --file=/tmp/a b y dos argumentos. Muestra una representación con escapes seguros a partir de la secuencia exacta de bytes o del vector de argumentos que usará el asistente. Si el comando contiene bytes que no pueden mostrarse de forma segura, recházalo o muestra una representación codificada explícita que la persona pueda inspeccionar.

Los cambios del destino remoto necesitan la misma disciplina que las redirecciones HTTP. Un alias de configuración SSH local, un salto mediante proxy o una búsqueda en la configuración del host pueden convertir un nombre corto en un destino distinto. Resuelve el plan final de conexión antes de la aprobación y vincúlalo. En sistemas donde el cambio de resolución DNS forma parte del modelo de amenazas, añade con cuidado una política independiente de direcciones del host; fijar una dirección puede romper la conmutación por error habitual, mientras que ignorar un resolvedor hostil puede enviar un nombre de host válido a la máquina equivocada. No finjas que una vista previa del comando resuelve ese problema separado.

El intervalo vulnerable empieza después de que la persona hace clic

El fallo aparece cuando la interfaz comprueba los detalles propuestos, registra un sí y una ruta de ejecución posterior lee detalles mutables del cliente. A menudo se esconde detrás de código asíncrono normal.

Considera un proceso de agente que pide a una pasarela transferir fondos:

  1. El cliente envía POST https://api.example.test/transfers con un cuerpo por 50 unidades.
  2. La pasarela crea una vista previa y espera a que una persona la apruebe.
  3. La persona aprueba después de leer el destino y el importe.
  4. El cliente envía execute con el identificador de aprobación y un cuerpo nuevo por 5.000 unidades.
  5. La pasarela comprueba solo que el identificador de aprobación sea válido, inyecta la credencial y envía el cuerpo nuevo.

Nada de esta secuencia requiere una interfaz comprometida ni una credencial robada. El cliente utilizó una API que la pasarela ofrecía. Una prueba que apruebe la solicitud original y compruebe solo que el identificador funciona pasará. Una prueba que compare los bytes salientes finales con los bytes representados por el objeto aprobado fallará, exactamente como debe.

El mismo error aparece cuando una pasarela guarda por referencia un objeto de solicitud mutable. Un trabajador de vistas previas lo lee, un gestor de reintentos del lado del agente lo modifica y el trabajador de envío manda después la versión editada. Copiar el objeto no basta si los mapas anidados, los búferes del cuerpo o las devoluciones de llamada siguen compartidos. Construye un valor inmutable sin referencias propiedad del cliente, o serialízalo en una representación de autoridad y reconstruye solo a partir de ella.

La expiración no repara el estado mutable. Una aprobación que dura treinta segundos todavía puede autorizar una solicitud modificada enviada durante el primer segundo. Los límites de frecuencia tampoco lo reparan. Reducen la frecuencia con la que un cliente puede aprovechar un error, no determinan si la persona aprobó el efecto.

Mantén la máquina de estados lo bastante pequeña como para auditarla:

proposed -> frozen -> awaiting_human -> approved -> dispatched
                         |                 |
                         v                 v
                      rejected           expired

Solo la transición de approved a dispatched puede realizar la acción externa. Esa transición debe cargar el registro congelado por identificador de acción, volver a comprobar el autor de la llamada y la expiración, y entregar el registro directamente al ejecutor HTTP o SSH. Cualquier solicitud para cambiar los detalles vuelve a proposed y crea un identificador nuevo.

Vincula los bytes cuando la semántica pueda desviarse

Haz de la bóveda la puerta de acceso
Su puerta de la bóveda deniega cualquier acción mientras la bóveda cifrada está bloqueada.

Una vinculación necesita una representación estable, o dos componentes pueden creer que aprobaron la misma solicitud mientras construyen datos distintos para la red. La parte difícil es decidir qué representación tiene autoridad.

Para solicitudes JSON sencillas, normaliza una estructura siguiendo reglas documentadas, serialízala una vez y conserva los bytes finales del cuerpo y su resumen hash. La vista previa puede mostrar JSON legible, mientras que la ruta de envío utiliza los bytes conservados. Nunca analices, embellezcas y vuelvas a serializar después de la aprobación, salvo que esa salida transformada sea el objeto aprobado.

Para formularios, cargas multipart, cabeceras repetidas o entradas binarias arbitrarias, los bytes suelen ser el límite más seguro. Vincula los bytes exactos, el tipo de contenido y las decisiones de encuadre de la transferencia que afecten a la interpretación del servidor. Un resumen hash permite que la interfaz identifique un cuerpo grande sin volcar un documento privado en una hoja de aprobación, pero el ejecutor debe conservar esos bytes exactos o regenerarlos a partir de un estado de confianza.

La canonicalización de URL es otra trampa. Normalizar las mayúsculas y minúsculas del nombre de host suele ser inofensivo. Decodificar y volver a codificar una ruta, ordenar pares de consulta, eliminar un valor vacío o tratar + y %20 como idénticos puede cambiar cómo una aplicación enruta o valida una solicitud. Elige una forma canónica definida de manera estricta, documenta sus reglas y rechaza las entradas que tengan más de una interpretación plausible. «Normalizamos las URL» no es una propiedad de seguridad.

Para SSH, un vector de argumentos es mejor que una cadena de shell cuando el asistente de protocolo puede ejecutarlo sin invocar un shell. Vincula cada argumento como una secuencia de bytes independiente. Cuando el extremo remoto tenga que recibir necesariamente una única cadena de comando de shell, vincula esa cadena exactamente y muestra sus escapes con honestidad. No afirmes que un analizador de la máquina local puede demostrar qué hará un archivo de inicio arbitrario del shell remoto.

El resumen de aprobación debe cubrir una codificación versionada y separada por dominio. Anteponer a los datos codificados una etiqueta fija como action-v1/http o action-v1/ssh, incluir todos los campos inmutables con longitudes inequívocas o un serializador determinista y aplicar después el hash. El versionado impide que una interpretación antigua se convierta silenciosamente en otra nueva tras una actualización. La separación por dominio evita que un objeto HTTP coincida alguna vez con un objeto SSH solo porque sus bytes serializados resulten coincidir.

La identidad del autor y la vinculación de la acción resuelven problemas distintos

La autorización por sesión te dice qué proceso en ejecución puede solicitar acciones. La vinculación de la acción te dice qué acción exacta puede ejecutar ese proceso. Necesitas ambas, y ninguna sustituye a la otra.

Vincula la acción a la identidad del proceso observada por la pasarela, no a un nombre que envíe el cliente. En macOS, puede incluir la autoridad de firma del código, el identificador del proceso y la instancia de inicio del proceso. La instancia de inicio importa porque un sistema operativo puede reutilizar un identificador de proceso. Si el proceso termina, descarta sus acciones pendientes y aprobadas junto con la autoridad de sesión.

No permitas que un proceso hijo herede una aprobación amplia solo porque conoce el identificador de su padre. Observa cada proceso que se conecte en el límite de la pasarela. Si la arquitectura de herramientas lo hace imposible, declara la limitación y acorta el periodo de aprobación en lugar de inventar una confianza que no tienes.

La aprobación humana también necesita una vida útil breve y limitada. La expiración pertenece al objeto congelado y a la decisión de aprobación, no solo a un temporizador dentro de la interfaz. Cuando pasa la expiración, el ejecutor rechaza el envío aunque el cliente haya conservado una respuesta antigua durante todo ese tiempo. Una sesión revocada también debe impedir el envío de cualquiera de sus acciones aprobadas que aún no se hayan utilizado.

La autorización por sesión de Sallyport puede establecer si un proceso de agente recién conectado puede usar una ejecución, mientras que una pasarela de acciones sigue necesitando este límite inmutable separado para cada efecto secundario mostrado en una vista previa. Una decisión de sesión es intencionadamente amplia; la aprobación de una solicitud HTTP o un comando SSH debe seguir siendo exacta.

No conviertas la identidad del proceso en una razón para mostrar menos detalles. Un código firmado y de confianza puede tener defectos, recibir entradas inesperadas de inyección de instrucciones o incluir un complemento que tomó una ruta distinta de la que esperaba su autor. El valor de una barrera humana es que permite ver el efecto concreto antes de que salga de la máquina.

Los reintentos y las redirecciones deben mantenerse dentro del límite aprobado

Pon una puerta a cada clave
Exige Touch ID o un clic para cada uso de una clave HTTP o SSH sensible.

Un reintento de transporte puede reutilizar la aprobación solo cuando vuelve a enviar la misma acción congelada en las condiciones registradas. Muchas implementaciones de reintentos infringen esta regla sin darse cuenta al reconstruir las solicitudes a partir de un estado mutable del cliente.

Define el comportamiento permitido para los reintentos cuando congeles la acción. Por ejemplo, permite un reenvío después de un fallo de conexión antes de recibir cualquier respuesta HTTP, con la misma URL, las mismas cabeceras, los mismos bytes del cuerpo y la misma referencia de credencial. Registra cada intento con el mismo identificador de acción. No reintentes una solicitud no idempotente después de una respuesta incierta, salvo que el protocolo y la API de destino te proporcionen un mecanismo de idempotencia fiable.

Un token de idempotencia solo sirve si también está vinculado. Si lo genera el ejecutor, genéralo al congelar la acción y consérvalo en el conjunto de cabeceras aprobado. Si lo proporciona el cliente, trátalo como parte de la solicitud aprobada. Sustituirlo durante un reintento puede hacer que una aprobación produzca un segundo efecto secundario.

La recuperación de autenticación merece la misma desconfianza. Si una bóveda actualiza internamente una credencial, pero envía la misma solicitud aprobada al mismo destino, la acción puede seguir dentro del límite. Si la recuperación cambia el arrendatario, el destino, el alcance o las cabeceras visibles para la aplicación, es una solicitud distinta y necesita una nueva aprobación. Evita un mecanismo en segundo plano que convierta un fallo de autorización en una llamada alternativa no revisada.

El comportamiento predeterminado de las redirecciones HTTP debe ser denegar las redirecciones para las acciones aprobadas. Una redirección que conserve todos los campos relevantes aún puede cruzar a una autoridad distinta. Si el producto admite seguir redirecciones, inspecciona cada salto antes del envío y exige un objeto de acción nuevo cuando cambie el host, el puerto, el método o el cuerpo. Trata una redirección relativa en la misma autoridad conforme a una regla explícita, no según lo que casualmente haga una biblioteca de cliente subyacente.

Las reconexiones SSH siguen una regla parecida. Reconecta solo al plan de host vinculado, con la identidad y el comando vinculados. Una huella de host descubierta recientemente, una ruta de proxy modificada o un resultado distinto de resolución del host pueden exigir una nueva decisión humana según tu modelo de amenazas. El código de reintento debe ser lo bastante sencillo como para que un auditor vea que no puede ampliar la aprobación original.

Audita la aprobación y la ejecución como eventos separados

Un registro de auditoría debe conservar tanto la acción que revisó la persona como los intentos que hizo el ejecutor. Un registro que solo conserva la solicitud final no puede demostrar si coincidía con la vista previa, y uno que solo registra la aprobación no puede demostrar si se produjo el envío.

Registra el identificador de la acción congelada, el resumen hash de vinculación, la identidad del autor de la llamada, los campos seguros para la vista previa, el identificador de referencia de la credencial, la hora de aprobación, la expiración y el resultado. Después registra cada intento de envío con el mismo identificador, el resultado del transporte, el motivo del reintento si lo hubo y un resumen hash del cuerpo o comando enviado realmente. Mantén los valores secretos fuera tanto del diario visible para la persona como de la respuesta del agente.

Aquí es donde un registro encadenado mediante hashes resulta útil. Una cadena puede revelar la eliminación o reordenación de entradas anteriores cuando la verificación cubre la secuencia almacenada. No puede hacer útil un evento impreciso. Si el registro solo dice «acción SSH aprobada», la cadena conservará fielmente un evento impreciso para siempre.

En una pasarela que mantenga un registro cifrado, encadenado mediante hashes y ciego a la escritura, un verificador sin conexión debería comprobar la cadena de textos cifrados de forma independiente del acceso a la bóveda. Sallyport ofrece esa comprobación mediante sp audit verify, lo que resulta útil porque un investigador puede verificar la continuidad sin abrir primero la bóveda de credenciales.

El resultado de la auditoría debe hacer visible la vinculación. Un revisor debería poder ver que la aprobación 7c91e2d4 cubría el resumen 4f06..., que el envío utilizó el mismo resumen y que el ejecutor rechazó cualquier propuesta que no coincidiera. Evita registros que impriman un resumen para personas en el momento de la aprobación y una solicitud sin procesar separada durante la ejecución, sin una relación persistente entre ambos.

Prueba el cliente como si quisiera cambiar de opinión

Verifica la cadena de auditoría
Verifica sin conexión la cadena hash cifrada con sp audit verify, sin abrir la bóveda.

Una prueba de integración normal demuestra que una acción aprobada funciona. Una prueba de seguridad debe demostrar que una acción aprobada no puede convertirse en otra distinta, incluso cuando el cliente se comporte mal después de que la persona haga clic.

Construye un entorno de pruebas que se pause justo después de la aprobación. Mientras el envío espera, modifica uno por uno los datos controlados por el cliente: método, host, puerto, ruta, consulta, valores de cabecera, cabeceras repetidas, cuerpo, selector de credencial, configuración de redirecciones, usuario SSH, comando, entorno, entrada estándar y resumen hash del archivo. El ejecutor debe enviar la acción original almacenada o rechazar el intento. Nunca debe enviar la modificación.

Prueba las condiciones de carrera con la misma intención que los cambios de campos. Envía dos mensajes execute para un identificador aprobado. Cancela la aprobación y envía execute exactamente al mismo tiempo. Deja que termine el proceso que hizo la solicitud y conecta después un proceso nuevo que intente usar el identificador antiguo. Reinicia la interfaz mientras una aprobación está pendiente. Llena el almacén de acciones pendientes hasta que se ejecute la limpieza por expiración. Son eventos normales del ciclo de vida, y el código de autorización suele fallar en las uniones entre ellos.

Usa un servidor HTTP simulado que informe del método exacto, el destino, las cabeceras duplicadas y el resumen hash del cuerpo que recibió. Usa un extremo SSH controlado que registre el usuario remoto, los bytes del comando, la solicitud de terminal, el entorno y el resumen hash de la entrada estándar. Comprueba esas observaciones, no solo el objeto de intención de la pasarela. El objetivo es detectar una divergencia entre la intención y el transporte.

Por último, haz que los fallos de las pruebas sean fáciles de leer. Un fallo útil dice que el resumen de aprobación 4f06... cubría PATCH /v1/users/42, mientras que el envío intentado llevaba un resumen distinto y fue rechazado. Un mensaje impreciso como «falló la autorización» devuelve a los ingenieros a las instrucciones de depuración y los anima a debilitar las comprobaciones hasta que la prueba pase.

Coloca el límite de inmutabilidad junto al ejecutor

El componente que guarda las credenciales y abre la conexión HTTP o SSH debe ser el propietario de la acción aprobada congelada. Cualquier límite anterior deja libre a otra capa para reinterpretarla, reconstruirla o sustituirla.

Este diseño también mantiene honesta la interacción humana. La persona ve una vista previa generada a partir del objeto que se enviará, el agente recibe resultados y no credenciales, y el registro de auditoría tiene un identificador que relaciona la intención, la aprobación y la ejecución. Son ventajas distintas, pero todas dependen del mismo rechazo a aceptar cambios después de hacer clic.

Si tu flujo actual devuelve un token de aprobación al agente y acepta después nuevos campos de acción, corrígelo antes de mejorar el texto, añadir más controles de políticas u otra ventana de aprobación. Congela primero la solicitud. Después haz que el ejecutor demuestre que utilizó el registro congelado.

FAQ

¿Qué es la vinculación de una solicitud de aprobación?

Una vista previa solo es fiable cuando el ejecutor guarda la acción exacta aprobada y rechaza cualquier sustitución posterior enviada por el cliente. Si la aprobación se limita a devolver un «sí» reutilizable al cliente, la vista previa es decorativa.

¿La aprobación de sesión impide que se cambien las solicitudes después de aprobarlas?

No. Un proceso con sesión iniciada todavía puede enviar una solicitud distinta después de que la persona lea la vista previa. La aprobación de sesión responde quién puede solicitar acciones; la vinculación de solicitudes responde qué puede ejecutar ese proceso.

¿Qué campos HTTP debe vincular una aprobación?

Incluye el método, el destino completo, las cabeceras después de inyectar las credenciales, los bytes o el resumen hash del cuerpo, el comportamiento de las redirecciones y la referencia de la credencial. No muestres secretos, pero identifica la credencial y su destino previsto.

¿Qué debe incluir una vista previa de aprobación SSH?

Como mínimo, vincula el host, el puerto, el usuario remoto, la identidad de autenticación, el modo de ejecución, los bytes exactos del comando, el entorno, el directorio de trabajo, la asignación del terminal y la entrada estándar o el contenido transferido. Una etiqueta como «deploy» no basta.

¿Son seguras las redirecciones HTTP después de aprobar una acción?

Trata una redirección como una nueva solicitud saliente cuando cambie el host, el método o el cuerpo. Seguirla en silencio permite que un servidor elija una acción que la persona nunca revisó.

¿Se puede reintentar una solicitud aprobada de forma segura?

Los reintentos pueden reutilizar la aprobación solo cuando vuelven a enviar la misma acción inmutable conforme a una regla de reintento limitada y registrada. Un reintento que cambie el cuerpo, el destino, la credencial o el comportamiento de idempotencia necesita una nueva decisión.

¿Debe recibir el cliente un token de aprobación?

Por lo general, no. Un token de aprobación en manos del cliente puede copiarse, reutilizarse o combinarse con parámetros alterados, a menos que el ejecutor lo compare por separado con un estado inmutable almacenado. Mantén la acción autorizada dentro del proceso que realiza la llamada de red o SSH.

¿Debo aplicar el hash a los bytes HTTP sin procesar o a los campos canónicos?

Usa una representación canónica de campos cuando la equivalencia semántica esté bien definida, y conserva después un resumen hash del cuerpo final transmitido cuando no lo esté. Sé especialmente estricto con las cabeceras repetidas, la codificación de consultas, los cuerpos multipart y las cadenas de comandos de shell.

¿Qué deben registrar los registros de auditoría de las acciones aprobadas?

Los registros de aprobación muestran qué se pidió autorizar a la persona. Los registros de ejecución muestran qué intentó hacer el ejecutor y qué ocurrió, incluidos los reintentos y errores. Conservar ambos hace que las investigaciones dependan mucho menos de suposiciones.

¿Cómo pruebo los fallos de comprobación en el momento de la aprobación?

Crea pruebas adversarias que aprueben una acción y después modifiquen cada campo controlado por el cliente antes de la ejecución. Prueba redirecciones, cabeceras duplicadas, análisis del shell, sustitución de procesos, reutilización, expiración y un flujo de aprobación interrumpido.

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