8 min de lectura

Registro de auditoría de webhooks: rastrea los flujos de los agentes de principio a fin

Crea un registro de auditoría de webhooks que conecte las acciones del agente, los intentos salientes, los callbacks verificados, los reintentos y el estado final del flujo de trabajo sin hacer suposiciones.

Registro de auditoría de webhooks: rastrea los flujos de los agentes de principio a fin

Una acción de un agente que inicia un flujo de trabajo asíncrono tiene dos historiales: la solicitud que envió y el evento que regresó. Los equipos suelen registrar el primero lo bastante bien como para responder «¿el agente llamó a la API?» y el segundo lo bastante bien como para responder «¿nuestro receptor recibió un webhook?». Durante un incidente descubren que nadie puede demostrar que esos registros describen el mismo trabajo.

Un registro de auditoría de webhooks debe conectar la intención, la autorización, la entrega saliente, el reconocimiento remoto, la recepción entrante, la verificación y el estado empresarial que decidiste aceptar. Tratar una respuesta 200 como el final del registro es la razón por la que un pago, despliegue, ticket o cambio de acceso se vuelve imposible de explicar tres días después.

Un registro de auditoría de webhooks conserva dos hechos distintos

Un registro de auditoría de webhooks debe mantener la diferencia entre una solicitud de acción y una notificación de evento porque responden preguntas diferentes. El lado saliente indica qué pidió un agente a un servicio remoto. El lado entrante indica qué afirmó después algún remitente que había ocurrido.

Esos hechos pueden referirse al mismo flujo de trabajo, pero tienen modos de fallo distintos. Un agente puede enviar un comando, perder la conexión y enviarlo de nuevo. El servicio remoto puede aceptar el comando, ejecutarlo minutos después y enviar dos callbacks idénticos. Tu receptor puede verificar el primer callback, pero fallar antes de guardar el estado resultante. Una línea ordenada en el registro de la aplicación no puede explicar esa cadena.

Uso seis tipos de registros cuando reviso estos sistemas:

  • Un registro de acción identifica la ejecución del agente, la autorización humana, la operación solicitada y el objetivo previsto.
  • Un registro de intento saliente identifica cada transmisión HTTP, incluido un resumen de la solicitud y la respuesta recibida.
  • Un registro de referencia remota conserva cualquier identificador que devuelva el proveedor, como un ID de trabajo u operación.
  • Un registro de recepción conserva cada entrega HTTP entrante antes de que el procesamiento empresarial cambie nada.
  • Un registro de verificación explica exactamente por qué el receptor aceptó, rechazó o puso en cuarentena esa entrega.
  • Un registro de transición de estado indica qué cambió en el flujo de trabajo después de procesar un evento verificado.

No mezcles un intento con una acción. Una acción puede producir varios intentos. Tampoco mezcles una recepción con un evento. Un evento del proveedor puede llegar varias veces a tu endpoint. La distinción parece minuciosa hasta que un ingeniero tiene que explicar si un segundo despliegue provino del reintento del agente, del reintento del cliente HTTP o del reenvío de un mismo evento por parte del proveedor.

RFC 9110 define POST de forma deliberadamente amplia: el recurso objetivo procesa la representación según sus propios criterios. Por eso una respuesta 202 suele significar «aceptado para trabajar más tarde», y una respuesta 200 solo indica que el endpoint terminó de gestionar la solicitud. No certifica el resultado empresarial remoto. Si el proveedor ofrece un endpoint separado para consultar el estado de la operación o un callback, esa evidencia posterior determina el resultado.

Un buen registro permite que un revisor lea la historia en orden sin deducir hechos a partir de las marcas de tiempo:

agent session sess_7c1e authorized action act_01
act_01 created outbound attempt out_01 with idempotency ref idem_44
remote service accepted out_01 and returned operation op_903
receiver accepted delivery rcp_01 for provider event evt_775
rcp_01 verified its signature and linked evt_775 to op_903
workflow wf_18 moved from pending to completed

Esa es una cadena de afirmaciones, no un único campo de estado. Cada afirmación necesita su propio origen y momento.

La correlación necesita más de un identificador

Un único ID de correlación no resuelve el rastreo de webhooks porque cada parte crea identificadores para ámbitos diferentes. Usa un pequeño conjunto de identificadores con un propietario claro y registra sus relaciones.

Empieza con un ID de acción interno. Créalo antes de cualquier llamada de red y asígnalo a la sesión del agente, la operación solicitada, la decisión de autorización y la entrada de auditoría inmutable. Este ID responde a la pregunta «¿qué instrucción del agente provocó este trabajo?». No debe cambiar cuando el cliente reintenta.

Crea un ID de intento saliente cada vez que tu cliente HTTP transmita algo. Este ID responde a la pregunta «¿qué intento en la red produjo esta respuesta o error?». Incluye una referencia de idempotencia cuando la API remota la admita. Una referencia de idempotencia indica que los envíos repetidos deben corresponder a una única operación remota lógica. No te dice si un intento HTTP concreto llegó al servidor.

Cuando el servicio remoto devuelva un ID de operación, guárdalo de inmediato junto al intento que lo recibió. Si tu solicitud admite una referencia del cliente o un campo de metadatos, coloca ahí tu ID de acción después de confirmar que el proveedor lo devolverá en los callbacks o en las respuestas de estado. Nunca pongas un secreto, el nombre de un empleado o el prompt completo en un campo de referencia. Estos campos suelen aparecer en las consolas del proveedor, los tickets de soporte y los payloads de eventos.

Los callbacks entrantes añaden dos IDs más: el ID del evento del proveedor y tu ID de recepción. El ID del evento del proveedor permite eliminar duplicados de ese remitente. Tu ID de recepción identifica la entrega HTTP exacta que recibió tu infraestructura, incluidos sus encabezados, la dirección de origen si la conservas, el resumen del cuerpo original y el resultado de la verificación.

La tabla de relaciones debería tener este aspecto:

IdentificadorCreado por¿Se mantiene en los reintentos?Responde a
ID de acciónTu servicio de acciones¿Qué solicitud del agente inició el trabajo?
ID de intentoTu cliente HTTPNo¿Qué transmisión produjo este resultado?
Referencia de idempotenciaTu servicio de acciones¿Qué envíos representan el mismo comando remoto?
ID de operación remotaProveedorNormalmente¿Qué trabajo u objeto remoto cambió?
ID de evento del proveedorProveedorSí, para un evento¿Qué callback debe deduplicarse?
ID de recepciónTu receptorNo¿Qué entrega recibimos?

CloudEvents resulta útil aquí, incluso cuando un proveedor no envía CloudEvents. Su especificación separa id, source, type, subject y time. Esa separación evita un error recurrente: tratar el ID de un evento como el ID de un flujo de trabajo. Un ID de evento identifica un evento de un origen. Un ID de flujo de trabajo identifica el trabajo que estás rastreando. Pueden apuntar al mismo objeto remoto, pero no significan lo mismo.

Si un proveedor solo te entrega un payload de callback con un ID de objeto, relaciónalo con cautela. Marca la relación como exacta únicamente cuando el ID del objeto provenga de la respuesta saliente registrada o de una consulta de estado autenticada. Coincidir por dirección de correo, texto del título, importe o marca de tiempo es una suposición disfrazada de correlación. No la incluyas en las conclusiones de auditoría.

Una respuesta 2xx y un callback resuelven preguntas distintas

Una respuesta 2xx resuelve el intercambio HTTP. Un callback verificado puede resolver un cambio de estado remoto. Tu flujo de trabajo necesita ambos y debe describir con honestidad la distancia entre ellos.

Imagina un agente que pide a un servicio de compilación alojado que publique un artefacto. El servicio devuelve 202 y un ID de operación. Tu servicio registra la solicitud como aceptada y espera. Diez minutos después, un callback indica que la publicación falló porque un repositorio posterior rechazó un manifiesto obligatorio. Si el registro de auditoría cambió a «éxito» con la respuesta 202, ahora contradice las propias pruebas del proveedor.

Usa estados que indiquen qué evidencia tienes. Por ejemplo:

  1. requested significa que la acción del agente pasó la autorización y creó un elemento de trabajo.
  2. submitted significa que al menos un intento saliente recibió una respuesta de aceptación o que un resultado ambiguo recuperable está pendiente de comprobación.
  3. confirmed significa que un callback verificado o una respuesta de estado autenticada estableció el resultado previsto.
  4. failed significa que una prueba autorizada estableció el fallo.
  5. unknown significa que todavía no puedes establecer si el lado remoto actuó.

El estado unknown es necesario. A los equipos no les gusta porque hace menos atractivos los paneles. Yo prefiero eso a la duplicación silenciosa. Un tiempo de espera después de enviar un POST produce una entrega ambigua: el sistema remoto puede haberlo recibido y procesado, o quizá nunca lo vio. Reintentar sin un mecanismo de idempotencia puede crear dos operaciones remotas. Llamar «fallido» al primer intento fomenta exactamente ese error.

Un callback tardío tampoco gana automáticamente. Supón que un agente solicita una cancelación después del comando inicial y tu flujo de trabajo interno registra una cancelación válida. Un callback de finalización que llega después puede informar de lo que ocurrió remotamente antes de que la cancelación tuviera efecto. Consérvalo, verifícalo, relaciónalo y registra el conflicto. No permitas que un controlador genérico sobrescriba un estado terminal de cancelación solo porque «completado» ocupa un lugar superior en el enum de alguien.

Escribe una regla de transición para cada tipo de callback. Una aprobación de pago, una compilación finalizada, un evento de aprovisionamiento de usuario y una confirmación de eliminación no merecen las mismas transiciones. La regla debe indicar qué estados anteriores permiten la transición, qué pruebas necesita el controlador y si un operador debe resolver un conflicto.

El receptor debe conservar la evidencia antes de analizarla

Tu receptor debe capturar la entrega original, verificarla y eliminar sus duplicados antes de ejecutar un efecto secundario. Analizar primero el JSON y guardar solo algunos campos destruye pruebas cuando después se descubre que el analizador, el esquema o el código de la aplicación tenían un error.

Al recibir el evento, registra lo siguiente en un almacén de eventos protegido:

  • El ID de recepción y la marca de tiempo del servidor.
  • El método de la solicitud, la ruta, los encabezados seleccionados y un resumen criptográfico del cuerpo original exacto.
  • La identidad del remitente que esperabas y el esquema de verificación aplicado.
  • El ID del evento del proveedor, si el payload lo incluye, además del tipo de evento analizado.
  • La decisión: aceptado, duplicado, rechazado o puesto en cuarentena, junto con un código de motivo.

Conserva los payloads originales solo durante el periodo que justifiquen tus necesidades de investigación y cumplimiento. Un resumen suele bastar para demostrar que dos payloads coinciden. Si conservas un cuerpo, cífralo, restringe el acceso y evita copiarlo en los registros normales de la aplicación. Los webhooks suelen contener datos personales, metadatos de repositorios, direcciones y notas internas. Un almacén de auditoría que filtra el payload es un riesgo, no una prueba.

La verificación de la firma debe funcionar sobre el cuerpo exactamente como lo firmó el remitente. Una capa de middleware que analiza el JSON, le da otro formato y después verifica los bytes reformateados rechazará entregas legítimas o, peor aún, permitirá un tratamiento incoherente. Lee con atención la documentación de verificación del proveedor. Algunos esquemas firman timestamp + "." + raw_body; otros solo el cuerpo original; otros usan firmas asimétricas y claves públicas rotatorias.

Para un esquema HMAC genérico que firma únicamente el cuerpo original, este comando muestra el formato del resumen que deberías esperar de los bytes sin modificar:

printf '%s' "$RAW_BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"
# SHA2-256(stdin)= 4d3c...hex digest...

Esto sirve para diagnosticar, no sustituye la cadena canónica exacta del proveedor. Si el proveedor incluye una marca de tiempo o un prefijo de versión, copiar el comando genérico dará un resultado incorrecto. Este error aparece a menudo porque los ingenieros verifican una aproximación cómoda en lugar del algoritmo documentado por el remitente.

La validez de la firma no detiene las repeticiones. Si el remitente proporciona una marca de tiempo firmada, rechaza las entregas fuera de una ventana estrecha después de tener en cuenta el desfase horario medido. Después registra los IDs de evento del proveedor en un almacén duradero de deduplicación antes de invocar el trabajo posterior. Si no puedes confiar en un ID de evento, deduplica mediante un resumen limitado al remitente y un periodo de retención apropiado, sabiendo que dos eventos idénticos legítimos podrían necesitar un tratamiento especial.

Devuelve una respuesta HTTP solo después de hacer duradera la decisión sobre la recepción. Si devuelves éxito primero y el proceso falla antes de escribir la deduplicación, el remitente puede reintentar y tu controlador puede procesar dos veces el mismo evento. El error se oculta en las pruebas de poco volumen y aparece precisamente durante las interrupciones en las que el tráfico de webhooks aumenta.

Los reintentos muestran dónde tus registros son demasiado vagos

Enruta SSH a través de Sallyport
La herramienta incluida sp-ssh ejecuta comandos SSH sin exponer las claves SSH al agente.

Los reintentos son un comportamiento normal, no un caso límite, y cada capa puede reintentar de forma independiente. Los agentes reintentan después de un tiempo de espera. Las bibliotecas HTTP reintentan cuando falla una conexión. Los proveedores de API reintentan los callbacks. Los consumidores de colas reintentan un controlador fallido. Un registro que reduce todo esto a «número de reintentos: 3» no ayuda a nadie.

Repasemos un fallo que he visto con distintas variantes. Un agente solicita crear un registro de acceso remoto. El cliente envía un POST y agota el tiempo de espera después de que los bytes salgan del equipo. El servicio remoto crea el registro y pone un callback en cola. El marco del agente reintenta porque ve un tiempo de espera. La segunda solicitud crea otro registro porque la capa de acciones generó una nueva referencia de idempotencia en cada intento. Llegan ambos callbacks. El receptor solo usa una dirección de correo para relacionarlos, decide que son duplicados y suprime el segundo. La página de auditoría muestra una solicitud completada. El servicio remoto ahora tiene dos registros de acceso.

Cada componente se comportó de una manera razonable. El sistema falló porque no conservó un comando lógico a través de los límites de los reintentos.

Corrige la secuencia de esta forma:

  1. Genera el ID de acción y la referencia de idempotencia una sola vez, antes del primer intento saliente.
  2. Registra cada intento por separado, incluidos los tiempos de espera y los errores de transporte.
  3. Ante una situación ambigua, consulta al proveedor por la referencia de idempotencia o la referencia del cliente antes de emitir otro comando.
  4. Acepta cada callback autenticado como una recepción y deduplica únicamente el ID del evento del proveedor, no el objeto remoto.
  5. Compara el número esperado de objetos remotos con la acción registrada antes de declarar completo el flujo de trabajo.

La primera comprobación de idempotencia pertenece al remitente y la segunda al receptor. Resuelven problemas diferentes. La idempotencia del remitente evita comandos remotos duplicados. La deduplicación del receptor evita procesar varias veces un mismo evento remoto. Los equipos suelen instalar una y asumir que también tienen la otra.

No uses la hora de llegada como orden de la verdad empresarial. Los proveedores pueden entregar eventos tarde o fuera de orden, y tu propia cola puede retrasar el procesamiento. Guarda al menos tres momentos: cuándo tu servicio de acciones creó la acción, cuándo tu cliente HTTP envió el intento o recibió su respuesta y cuándo tu receptor aceptó el callback. Conserva por separado la hora del evento declarada por el remitente. El reloj del remitente es una prueba de ese remitente, no tu reloj.

La autorización debe sobrevivir al límite asíncrono

La aprobación humana de una acción del agente debe estar vinculada a la acción misma, no al callback que llegue después. Un callback contiene información sobre un trabajo remoto. Nunca debe adquirir silenciosamente autoridad para activar una nueva operación privilegiada solo porque comparte un campo de correlación con una solicitud aprobada.

Esto importa cuando los callbacks pueden contener URL, nombres de objetos, metadatos controlados por usuarios o instrucciones que sigue un controlador interno. Un diseño defectuoso habitual recibe un evento de «trabajo completado» y permite que un trabajador de automatización genérico obtenga una URL de resultados o ejecute un comando posterior con credenciales amplias. La aprobación original del agente cubría el envío de un trabajo, no un conjunto abierto de acciones incluidas en un evento.

Registra la acción autorizada de forma concreta: sesión del actor, endpoint solicitado o plantilla de comando SSH, alcance del objetivo, identidad de la credencial, resultado de la aprobación y hora de aprobación. Para cada llamada saliente, apunta a ese registro de autorización. Para cada callback, apunta a la acción solo después de verificarlo y correlacionarlo. La dirección importa. Una solicitud entrante no debe buscar en tu base de datos cualquier aprobación previa conveniente y tomarla prestada.

Sallyport mantiene las credenciales del agente fuera del proceso del agente y registra tanto las ejecuciones de los agentes como las llamadas individuales, lo que facilita conservar esta parte saliente de la evidencia. El receptor del callback sigue necesitando sus propios registros de recepción y flujo de trabajo, porque un diario de acciones HTTP no puede saber si un sistema remoto envió después un evento válido.

Usa credenciales separadas para ambas direcciones. La credencial que autoriza tu llamada saliente a la API normalmente no debe verificar firmas entrantes, y el secreto de verificación entrante no debe autorizar a un controlador de callbacks a llamar a API externas arbitrarias. Separar la custodia limita el daño cuando una ruta del receptor, una dependencia o un destino de registros falla.

La evidencia de manipulación debe cubrir las relaciones, no solo las llamadas

Separa los reintentos de las acciones
Los registros de actividad mantienen separadas las llamadas individuales del agente y las ejecuciones del agente en el registro de sesiones.

Un registro de llamadas salientes que solo permite añadir datos resulta útil, pero no demuestra las decisiones de correlación tomadas después. Un operador o un error de la aplicación puede asociar el callback equivocado con la acción equivocada sin cambiar ninguno de los registros HTTP originales.

Convierte la correlación en un evento de auditoría de primer nivel. El evento debe incluir el ID de acción, el ID de recepción, la base de la relación, el actor o proceso que tomó la decisión y un resumen de los campos utilizados. Usa bases explícitas como remote_operation_id_exact, client_reference_exact, authenticated_status_lookup o manual_review. No escribas «coincide» y dejes que el investigador tenga que adivinar.

Un registro encadenado mediante hashes puede demostrar que los registros no cambiaron después de crearse, siempre que protejas la ruta de escritura y conserves puntos de control. No puede demostrar que la aplicación tomó una decisión correcta en ese momento. Es sano declarar esa limitación con claridad. La evidencia de manipulación te da un relato estable de lo que registró tu sistema, pero no convierte una correlación débil en un hecho.

El registro de auditoría cifrado y encadenado mediante hashes de Sallyport se puede comprobar sin conexión con sp audit verify, incluso sin una clave del almacén. Usa este tipo de verificación para los registros de acciones y conserva después una referencia inmutable comparable desde tu almacén de flujos de trabajo hacia los identificadores de acción y llamada relevantes.

En los flujos de trabajo de alto impacto, añade un proceso de reconciliación que compare tres grupos: las acciones enviadas, las operaciones remotas conocidas por el proveedor y los callbacks aceptados por tu receptor. El proceso debe crear un registro de excepción para cada elemento sin pareja, en lugar de cerrarlo automáticamente. La falta de un callback puede indicar una interrupción del proveedor, un endpoint incorrecto, un fallo en la rotación de firmas o un error del flujo de trabajo. Necesitas pruebas antes que optimismo.

La observabilidad debe permitir repetir la decisión

Evita multiplicar las reglas de políticas
Su escala fija de decisiones usa el control del almacén, la aprobación de sesión y las aprobaciones por clave en lugar de reglas de políticas.

Un investigador debe poder empezar desde cualquier identificador y reconstruir el flujo de trabajo sin acceso privilegiado a los prompts de los agentes ni a los secretos de las API. Diseña las rutas de búsqueda antes de publicar la integración.

Si se parte de un ID de acción, el registro debe mostrar la sesión del agente, la autorización, la etiqueta de la credencial, la forma de la solicitud después de ocultar datos, todos los intentos, las referencias remotas, las recepciones relacionadas y el estado terminal del flujo de trabajo. Si se parte de un ID de evento del proveedor, debe mostrar cada entrega de ese evento, los resultados de verificación, el resultado de la deduplicación, la operación relacionada y los cambios de estado. Si se parte de un objeto empresarial interno, debe mostrar la evidencia exacta que lo asoció con una acción del agente.

Usa campos estructurados, no una única cadena narrativa. Un contrato de evento útil puede copiarse en una revisión de esquema o en una canalización de registros:

{
  "record_type": "callback_receipt",
  "receipt_id": "rcp_01J...",
  "received_at": "2025-03-08T22:14:31Z",
  "sender": "build-service",
  "provider_event_id": "evt_775",
  "event_type": "publication.finished",
  "raw_body_sha256": "4d3c...",
  "signature": {"scheme": "hmac-sha256", "result": "valid"},
  "correlation": {
    "action_id": "act_01J...",
    "remote_operation_id": "op_903",
    "basis": "remote_operation_id_exact"
  },
  "processing": {"deduplication": "new", "result": "completed"}
}

El resumen del cuerpo, el resultado de la verificación y la base de la correlación hacen mucho más que un status: success impreciso. Permiten comprobar las afirmaciones. Si un proveedor cuestiona un callback, compara el resumen conservado. Si un ingeniero cuestiona una relación, revisa su base. Si un duplicado provocó efectos secundarios, comprueba si el receptor escribió el registro de deduplicación antes de enviar el trabajo.

Evita registrar encabezados de autorización, tokens bearer, claves privadas, secretos de firma o URL completas que contengan credenciales. Oculta los valores de consulta cuando contengan datos sensibles, pero conserva suficiente identidad de la solicitud para distinguir dos objetivos. He visto equipos ocultar una URL hasta volverla inútil y luego no poder determinar si un agente contactó con producción o con un endpoint de prueba. Guarda un host normalizado, una plantilla de ruta, el método y un identificador de objetivo cuidadosamente limitado.

Construye el rastreo antes de que los agentes hagan llamadas asíncronas

Debes definir los identificadores, las reglas de recepción y las transiciones de estado antes de dar a un agente una acción que inicie trabajo asíncrono. Añadirlos después de una disputa es costoso porque la evidencia que falta nunca existió.

Realiza un simulacro de fallo deliberado. Envía una acción de prueba inofensiva, fuerza al cliente a agotar el tiempo de espera después de la transmisión si tu entorno lo permite, reenvía el mismo callback, envía un callback con una firma no válida y entrega un callback válido después de que el flujo de trabajo entre en un estado terminal. Comprueba que el registro de auditoría explique cada resultado sin que una persona tenga que completar los huecos de memoria.

Si tu sistema no puede responder «¿qué acción autorizada provocó este callback, con qué evidencia exacta y qué hicimos con él?», todavía no tiene una historia de auditoría para los webhooks. Tiene dos conjuntos de registros que casualmente comparten un reloj.

FAQ

¿Qué es un registro de auditoría de webhooks?

Una solicitud saliente demuestra que tu agente o servicio intentó hacer una llamada. Un callback demuestra que otro sistema envió después un mensaje a tu receptor. Ninguno de los dos registros demuestra por sí solo el resultado empresarial completo, así que debes unirlos mediante identificadores duraderos y registrar la decisión del receptor.

¿Una respuesta HTTP correcta demuestra que una acción del agente tuvo éxito?

Por lo general, no. Una respuesta 2xx indica que el servidor receptor aceptó la solicitud HTTP según las reglas de ese endpoint. El sistema posterior todavía puede rechazar el trabajo, ponerlo en cola para revisarlo, reintentarlo o enviar después un estado final diferente en un callback.

¿Qué identificadores debo guardar para un webhook activado por un agente?

Conserva el ID de sesión del agente, el ID de acción, el ID de intento saliente, el ID de correlación del proveedor, el ID del evento del callback y el ID del objeto empresarial. Cada uno identifica algo distinto. Si falta alguno, investigar reintentos y duplicados resulta mucho más difícil.

¿Cómo debo gestionar un callback que llega después de cancelar un flujo de trabajo?

No marques la acción como completada con el primer callback coincidente. Primero verifica el callback, elimina los duplicados, relaciónalo con la solicitud correcta y aplica la transición de estado permitida por tu flujo de trabajo. Un callback de aprobación que llega después de una cancelación debe convertirse en evidencia, no en permiso para reabrir el trabajo.

¿Debo guardar los payloads completos de los webhooks en los registros de auditoría?

Guarda un resumen del cuerpo sin modificar, los encabezados usados para la verificación, el resultado de esa verificación, la hora de recepción y los campos analizados para el enrutamiento. Limita el acceso a los payloads completos porque los callbacks suelen contener datos de clientes o referencias internas. El registro de auditoría debe conservar las pruebas sin convertirse en un archivo de datos sin control.

¿Puedo usar el ID de evento del proveedor como único ID de correlación?

El ID de evento del proveedor solo es único dentro del flujo de eventos de ese proveedor, y algunos proveedores reenvían deliberadamente el mismo evento. Úsalo para eliminar duplicados dentro de ese origen, pero conserva también tu propio ID de recepción inmutable y un identificador separado de solicitud o flujo de trabajo para la correlación.

¿Los callbacks de webhook se entregan exactamente una vez?

No. Muchos sistemas de webhooks prometen una entrega al menos una vez, lo que significa que los duplicados son esperables. Crea un registro duradero de deduplicación antes de ejecutar efectos secundarios y haz que el controlador devuelva la respuesta correcta para un duplicado conocido.

¿Cómo verifico de forma segura un webhook entrante?

Verifica la firma contra el cuerpo de la solicitud sin modificar, antes de analizarlo o normalizarlo. Aplica también ventanas de tiempo cuando el remitente proporcione una marca de tiempo firmada, identifica el origen esperado y trata la detección de repeticiones como algo separado de la verificación de la firma.

¿Cómo puedo distinguir un reintento de una segunda acción del agente?

Usa el ID de intento registrado y la referencia de idempotencia para saber si el remitente reintentó el mismo comando lógico o creó un segundo comando. Después compara el valor de correlación del proveedor, el resumen del payload y el objeto empresarial resultante. El momento de llegada por sí solo es una evidencia débil, porque las colas y los reintentos de red lo distorsionan.

¿Qué pruebas necesitan los auditores para los flujos de trabajo asíncronos de los agentes?

Los auditores necesitan un relato cronológico que explique la autorización, el uso de credenciales, la intención de salida, los intentos de entrega, las recepciones verificadas y el estado final. Un registro de acciones con evidencia de manipulación ayuda a establecer qué hizo el agente, pero el registro del flujo de trabajo aún debe conectar esa acción con los eventos asíncronos que ocurren fuera de la pasarela.

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