8 min de lectura

Investigar registros de auditoría de API cuando los registros del agente entran en conflicto

Investigación de registros de auditoría de API para acciones de agentes: compara identificadores de solicitud, marcas de tiempo, resultados y eventos ausentes del proveedor sin sacar conclusiones falsas.

Investigar registros de auditoría de API cuando los registros del agente entran en conflicto

Un proveedor de API afirma que una solicitud cambió datos de producción. El registro del agente indica que nunca llegó tan lejos. Ambas afirmaciones pueden ser ciertas, y tratar cualquiera de los dos registros como un veredicto es la forma en que los equipos convierten una discrepancia contenida en una mala respuesta a un incidente.

Investiga la acción como una cadena de observaciones. Determina quién inició la ejecución, qué intentó hacer el agente, qué cruzó el límite de las credenciales, qué aceptó el proveedor y qué cambió después. Las marcas de tiempo ayudan a ordenar la cadena. Los identificadores de solicitud la conectan. Los resultados y el estado indican si tuvo importancia. Los eventos ausentes también son evidencia, pero solo después de descartar las formas habituales en que desaparecen los registros.

He visto a personas empezar con una hoja de cálculo y ordenar inmediatamente por hora. Es al revés. Una marca de tiempo suele ser el campo de unión más débil de todos. Empieza con identificadores estables y exportaciones inmutables, y usa el tiempo después para comprobar si la secuencia propuesta tiene sentido.

Conserva los registros antes de que alguien actualice un panel

Captura las pruebas originales antes de filtrar, reintentar, revocar el acceso o pedir al equipo de soporte del proveedor que investigue. Los paneles interactivos cambian, se ejecutan trabajos de retención y un reintento puede crear el segundo evento que confunde al primero.

Abre una carpeta del caso con un identificador de caso y recopila exportaciones sin procesar, no solo capturas de pantalla. Incluye el registro de sesión del agente, los registros individuales de acciones, la exportación de auditoría del proveedor, los registros de la aplicación del sistema afectado y cualquier registro de salida disponible para el equipo. Registra la hora de recopilación en UTC, quién la hizo, la cuenta o el rol utilizado y el filtro empleado para generar cada exportación.

Calcula el hash de cada archivo después de recopilarlo. Basta con un comando de shell si tu sistema operativo ofrece una utilidad estándar SHA-256:

$ shasum -a 256 provider-events.json agent-activity.json
81b5777b8416320fe26cb8a8dddb6a9e736fab4f5e7aa5812bf6afeffc5f4e82  provider-events.json
a1e98c01992b51104fbc8c5fcbaa78e65db31f1edb3e546f4c14d0e6d3673ba  agent-activity.json

Pon los hashes en una nota sencilla del caso. El hash no demuestra que la exportación del proveedor fuera completa. Demuestra que tu copia de trabajo no ha cambiado silenciosamente desde la recopilación. Son afirmaciones distintas, y los informes de incidentes suelen mezclarlas.

No conviertas el JSON en una hoja de cálculo como primera copia. La normalización puede descartar campos duplicados, el orden de las matrices, los segundos fraccionarios, los valores vacíos y el cuerpo exacto de la solicitud que después explica una discrepancia. Conserva una exportación intacta y crea un archivo de trabajo analizado por separado.

Si la discrepancia pudiera estar relacionada con una filtración de credenciales o un uso no autorizado, contiene el acceso de una forma que conserve la secuencia. Revoca una sesión activa del agente o bloquea la ruta de acción si puedes. Evita rotar la credencial del proveedor antes de recopilar sus registros de auditoría recientes, salvo que un abuso activo exija una rotación inmediata. A veces rotar la credencial es necesario, pero puede borrar la única vía restante para atribuir la acción.

Un identificador de solicitud tiene prioridad sobre una marca de tiempo

Relaciona los registros mediante identificadores que sobrevivan a los límites: un identificador de solicitud del proveedor, un identificador de correlación proporcionado por el cliente, una clave de idempotencia, un identificador de objeto devuelto por la escritura y un identificador de traza si el proveedor documenta uno. Conserva todos los identificadores, porque el proveedor puede mostrar identificadores distintos en cabeceras, eventos de auditoría, exportaciones de soporte y cuerpos de error.

El mejor caso es sencillo. El registro de acción indica que el agente llamó a POST /v1/invoices; las cabeceras de respuesta contienen x-request-id: req_72M...; la exportación del proveedor incluye req_72M...; y la factura creada tiene inv_4P.... Ahora tienes una unión entre intención, entrega, procesamiento del proveedor y estado persistente.

Los casos difíciles son más habituales. Un proveedor puede asignar un identificador de solicitud solo después de analizar la solicitud. Un fallo de TLS no tendrá identificador de solicitud del proveedor porque la solicitud nunca llegó a la aplicación. Una pasarela puede generar un identificador y el servicio posterior otro. Una API asíncrona puede devolver un identificador de trabajo y escribir el objeto solicitado varios minutos después. Registra qué límite emitió cada identificador en lugar de reducirlos todos a una única columna request_id.

Usa una tabla de conciliación que haga visible la incertidumbre:

CampoRegistro de acción localRegistro del proveedorSistema afectado
Identificador de correlación del clienterun-18-call-42run-18-call-42ausente
Identificador de solicitud del proveedorreq_72M... en la respuestareq_72M...ausente
Método y rutaPOST /v1/invoicesPOST /v1/invoicesfactura creada
Resultado504 timeout202 acceptedtrabajo job_91... completado
Hora del evento10:04:03.219Z10:04:03Z10:04:11.802Z

Esta tabla revela un fallo conocido: el cliente agotó el tiempo de espera, pero el proveedor aceptó la escritura y la procesó después de que el cliente abandonara. Sería incorrecto llamar «fallida» a la acción por el resultado del cliente. También sería incorrecto llamar al registro del proveedor «prueba de que el agente tenía intención de hacerlo». La evidencia indica que el agente envió una solicitud que el proveedor aceptó y que el cliente no recibió una respuesta a tiempo.

Si el proveedor permite una clave de idempotencia para las escrituras, úsala. El borrador de Internet de la IETF sobre Idempotency-Key describe bien el objetivo práctico: un cliente reintenta una operación HTTP insegura sin crear accidentalmente el mismo efecto dos veces. El comportamiento específico varía según el proveedor, así que lee su documentación sobre retención y reglas de coincidencia. No supongas que basta con que coincida el endpoint.

Para las API que aceptan cabeceras personalizadas, genera un identificador de correlación antes de la llamada y envíalo en una cabecera documentada, como X-Client-Request-ID. Guárdalo con el evento local. Nunca pongas secretos, prompts, datos de usuarios ni tokens sin procesar en este identificador. Un valor seguro no tiene significado fuera del caso, por ejemplo case-2025-041-run7-call18.

El tiempo puede refutar una historia, pero rara vez la demuestra

Usa las marcas de tiempo para delimitar eventos y detectar órdenes imposibles. No las uses como campo principal de identidad salvo que ninguna fuente tenga un identificador mejor.

RFC 3339 define un perfil común de marcas de tiempo de Internet y recomienda la forma UTC en mayúsculas terminada en Z, como 2025-03-08T10:04:03.219Z. Conserva la cadena original incluso después de analizarla. La diferencia entre 10:04:03Z y 10:04:03.219Z importa cuando una fuente redondea a segundos y otra informa de milisegundos.

Crea cuatro campos de tiempo para cada evento relevante:

  • la marca de tiempo de la fuente exactamente como se exportó
  • la marca de tiempo normalizada en UTC
  • el tipo de evento, como enviado, aceptado, completado o registrado
  • el propietario del reloj, como Mac local, extremo del proveedor, trabajador del proveedor o base de datos

Una marca de tiempo del extremo del proveedor puede preceder a una marca local de «respuesta recibida» sin que exista una contradicción. La marca de finalización de un trabajador del proveedor puede ser posterior a la salida del proceso del agente. Un reloj local desviado puede hacer que una acción parezca anterior al inicio de la sesión. Son mecanismos normales, no pruebas de manipulación.

Construye un intervalo alrededor de un ancla conocida, normalmente un identificador de solicitud o el inicio de una sesión. Empieza con un intervalo suficientemente estrecho para evitar uniones accidentales. Amplíalo solo cuando puedas indicar el motivo: el proveedor solo registra segundos, la operación es asíncrona o mediste la desviación del reloj frente a una referencia fiable. Escribe el intervalo elegido en la nota del caso. «Buscamos aproximadamente alrededor de esa hora» no es un método.

Ten cuidado con la hora de ingestión del registro. Muchos sistemas muestran event_time y created_at. El primero describe cuándo ocurrió el evento según el sistema que lo emitió. El segundo puede describir cuándo un agregador lo recibió o indexó. Una llegada tardía no significa una ejecución tardía. Si un evento aparece después de que comenzara un incidente, inspecciona ambos campos antes de construir una historia.

Una prueba de ordenación útil solo pregunta si la historia propuesta es posible. Un evento del proveedor a las 10:04:03, junto con un envío local a las 10:04:03.219, puede ser posible si los relojes difieren o el proveedor redondea hacia abajo. Una finalización declarada a las 10:02 cuando el proveedor dice que aceptó el trabajo a las 10:04 no es posible, salvo que hayas mezclado dos eventos o entendido mal el campo.

Separa intentado, entregado, aceptado y completado

Los equipos suelen comprimir cuatro estados distintos en la palabra «llamó». Ese atajo provoca la mayoría de las disputas sobre registros.

Un agente puede intentar una acción al construir una solicitud. Un componente local puede entregar bytes a un endpoint remoto. El proveedor puede aceptar la solicitud. Un trabajador posterior puede completar el efecto. Cada etapa tiene un registro y un modo de fallo diferentes.

La especificación HTTP Semantics, RFC 9110, deja claro que el código de estado es una afirmación sobre la respuesta del servidor, no un historial completo de la experiencia del cliente. Un 202 Accepted indica explícitamente que el procesamiento se aceptó, pero aún no se completó. Un 204 No Content indica que el servidor completó la solicitud correctamente, pero por sí solo no explica todos los efectos posteriores. Una interrupción de red puede no producir ninguna respuesta HTTP aunque el servidor haya procesado la solicitud.

Clasifica cada evento en disputa con un estado como estos:

  • Solo intentado: existe un registro de acción local, pero ninguna evidencia demuestra que se entregara por la red.
  • Entregado, resultado desconocido: la solicitud salió del límite local, pero el cliente no recibió una respuesta fiable y el proveedor aún no tiene un registro consultable.
  • Aceptado, efecto pendiente: el proveedor devolvió una aceptación o una referencia de trabajo, pero todavía no hay un estado completado.
  • Completado: un resultado del proveedor y un cambio de estado observado coinciden.
  • Contradicho: las fuentes hacen afirmaciones que no pueden ser ciertas a la vez después de tener en cuenta el significado de sus campos.

«Resultado desconocido» es una conclusión legítima. No lo rebautices como fallo solo porque el agente recibió una excepción. En una operación de escritura, esa excepción debería detener los reintentos automáticos, salvo que un mecanismo de idempotencia o una comprobación posterior haga seguro el reintento.

El error inverso es igual de grave: una respuesta 200 no significa que se produjera el resultado de negocio previsto. Un endpoint puede devolver éxito para una solicitud sintácticamente válida mientras una validación posterior, un trabajo asíncrono o una dependencia posterior rechaza el cambio previsto. Inspecciona el objeto devuelto, el estado del trabajo o el evento del sistema de destino que el contrato de la API define como señal de finalización.

Los eventos ausentes necesitan una explicación delimitada

Añade un límite de credenciales real
Sallyport ejecuta por sí mismo la acción con credenciales en lugar de pasarle la credencial al agente.

La ausencia de un registro puede significar que la solicitud nunca ocurrió, pero también que consultaste el servicio equivocado, usaste el ámbito de cuenta incorrecto, buscaste en el nivel de retención equivocado o esperabas un registro que el proveedor nunca promete emitir.

Analiza los eventos ausentes en un orden fijo. Primero, confirma la cuenta, el proyecto, la región, el entorno y el producto de API exactos. Los proveedores suelen separar las vistas de auditoría por uno o varios de estos campos. Después, busca con todos los identificadores, y luego con un intervalo de tiempo y un endpoint documentados. Comprueba si el proveedor registra solicitudes aceptadas, rechazadas, llamadas del plano de datos, llamadas del plano de control o solo acciones administrativas. Revisa después la retención y el retraso de las exportaciones. Por último, pregunta si un proxy, un SDK o una cola asíncrona crea un evento del proveedor diferente del que esperabas.

Conviene recordar un fallo concreto. Un agente envía POST /exports y recibe una interrupción de conexión. El equipo busca el identificador local del cliente en los registros de auditoría del proveedor y no encuentra nada. Reintenta y después recibe dos notificaciones de finalización de exportación.

La primera solicitud llegó a un endpoint regional de ingestión. La pantalla de auditoría que consultaron solo mostraba eventos del plano de control. El proveedor registró el trabajo con un identificador de exportación generado, no con la cabecera del cliente, y el servicio de trabajos lo completó después de la interrupción. Nada de esta secuencia requería actividad maliciosa. El duplicado se produjo al reintentar una escritura antes de comprobar si existía una clave de idempotencia, un endpoint de consulta del trabajo o un marcador de nivel de negocio.

Este fallo también muestra por qué la ausencia debe expresarse con cuidado. Di «La exportación que recopilamos no contiene ningún evento del plano de datos que coincida con este intervalo», en lugar de «El proveedor no tiene ningún registro». La primera afirmación identifica la evidencia y su límite. La segunda hace una afirmación que a menudo no puedes respaldar.

Si se esperaba un registro pero está ausente, conserva los parámetros de consulta y captura la documentación del proveedor que indique la cobertura esperada de eventos. Una solicitud de soporte sin el identificador exacto de solicitud, el ámbito de cuenta, el intervalo UTC, el endpoint y los hashes de las pruebas hará perder días.

Los resultados necesitan una inspección que vaya más allá de los códigos de estado

Aprueba el proceso, no las reglas
La autorización por sesión muestra la autoridad de firma de código de un proceso nuevo antes de aprobar su ejecución.

Compara la intención declarada de la solicitud con el contenido de la respuesta y el efecto observable. Los códigos de estado informan sobre un intercambio de protocolo. No indican si la solicitud tenía el ámbito correcto, si el proveedor aplicó un valor predeterminado o si el agente envió un identificador obsoleto.

Para cada acción, captura estos campos cuando la API los exponga: método HTTP, ruta normalizada, identificador de solicitud, clave de idempotencia, identidad del actor o de la credencial, código de estado, hash del cuerpo de respuesta, identificador del objeto devuelto y cualquier identificador de trabajo asíncrono. Redacta las credenciales y los datos sensibles del contenido antes de compartirlos de forma amplia, pero conserva un original protegido si la política lo permite.

Un hash del cuerpo de respuesta ayuda a distinguir dos registros 200 superficialmente idénticos. Calcúlalo sobre los bytes sin procesar de la respuesta antes de embellecerla. Si la API devuelve JSON y el orden de los campos cambia entre capas, conserva tanto los bytes originales como una copia analizada y canónica. No afirmes que códigos de estado iguales significan respuestas iguales.

Después, consulta el recurso que debería existir o haber cambiado. En una operación de creación, recupera el identificador del objeto devuelto y compara su creador, hora de creación y atributos. En una actualización, recupera una versión, revisión o entrada de auditoría si el servicio la ofrece. En un borrado, comprueba que el objeto esté ausente y que un registro de auditoría del proveedor atribuya el borrado a la misma credencial.

Aquí es donde las credenciales amplias perjudican las investigaciones. Si muchas herramientas comparten un token de API, el proveedor a menudo puede decirte que el token actuó, pero no qué proceso local o qué persona inició la acción. Trata la identidad de la credencial como un marcador de límite, no como la identidad del actor.

Un registro de pasarela solo sirve si registra el límite

Una pasarela de acciones ofrece un punto de observación claro entre un agente y la operación con credenciales. Debe registrar el proceso o la ejecución que invoca, el estado de autorización aprobado, la operación solicitada, el resultado devuelto al agente y suficientes identificadores para relacionar los registros del proveedor. No debe entregar la credencial al agente y luego llamar a la telemetría local resultante un registro de auditoría.

Sallyport mantiene las credenciales de API y SSH en su bóveda cifrada, ejecuta la acción por sí mismo y devuelve el resultado al agente, no el secreto. Sus diarios Sessions y Activity se proyectan desde un registro de auditoría cifrado, encadenado mediante hashes y ciego a escritura, lo que ofrece al investigador registros tanto del nivel de ejecución como del nivel de llamada. sp audit verify puede verificar esa cadena sin conexión sobre el texto cifrado, sin necesitar la clave de la bóveda.

Ese diseño cubre una carencia concreta. Un registro del proveedor puede identificar una credencial y una solicitud de API. No indica qué proceso del agente recibió permiso para usar esa credencial ni demuestra que el agente nunca vio el secreto. Un registro de auditoría local solo puede responder en parte a esa pregunta cuando el límite de las credenciales está dentro del componente que genera el registro.

No exageres lo que demuestra un registro de pasarela. No puede informar de una solicitud que la haya evitado ni convertir una API ambigua del proveedor en una API precisa. Te ofrece un lugar más sólido para comparar pruebas y un punto desde el que revocar una ejecución conocida del agente mientras continúa la investigación.

Redacta el hallazgo como afirmaciones con pruebas y límites

Deja de entregar secretos a los agentes
Los agentes se conectan mediante sp mcp mientras Sallyport ejecuta por sí mismo las acciones HTTP y SSH.

Un buen hallazgo permite que otro ingeniero reproduzca tu razonamiento sin heredar tus suposiciones. Escribe afirmaciones separadas sobre la invocación, el permiso, la entrega de la solicitud, el procesamiento del proveedor y el efecto observado. Adjunta los identificadores, las marcas de tiempo, los archivos de origen y el significado de los campos que respaldan cada afirmación.

Usa un lenguaje que corresponda al nivel de confianza. «El diario de acciones registra que el proceso X solicitó POST /v1/invoices a esta hora». «La exportación del proveedor contiene una solicitud con el mismo identificador de solicitud del proveedor». «La factura existe y sus atributos coinciden con la respuesta registrada». Son afirmaciones comprobables. «El agente causó definitivamente la factura» solo puede estar justificado si las relaciones y el límite de las credenciales lo respaldan.

Cuando los registros no coincidan, deja la discrepancia visible en el informe final. No promedies las marcas de tiempo ni descartes la fuente incómoda. Expón la explicación más probable, las alternativas que descartaste y las pruebas que aún faltan. Si no puedes establecer si una escritura se completó, regístrala como desconocida y corrige la ruta de la API antes de permitir reintentos automáticos.

El cambio práctico después de un incidente suele ser pequeño y poco llamativo: exigir un identificador de correlación, conservar la clase correcta de eventos del proveedor, preservar las marcas de tiempo UTC con fracciones y usar idempotencia para las escrituras. Estos controles convierten la próxima discrepancia de una discusión forense en una conciliación breve.

FAQ

¿Qué registro es la fuente de verdad cuando los registros de una API entran en conflicto?

Considera el registro del proveedor como evidencia de lo que llegó a su límite, y el registro del agente como evidencia de lo que el agente observó o intentó. Ninguno es completo automáticamente. Reconcilia ambos con una tercera fuente, como el registro de auditoría de una puerta de acciones, los registros de salida de red o el estado del sistema afectado.

¿La ausencia de un registro del proveedor demuestra que un agente nunca hizo la solicitud?

No. Los reintentos, las redirecciones, el procesamiento asíncrono, la desviación del reloj y la falta de telemetría pueden crear una discrepancia falsa. Empieza con el identificador de solicitud y un intervalo de tiempo limitado, y luego clasifica la discrepancia antes de considerarla un incidente de seguridad.

¿Cómo relaciono una acción de un agente de IA con una solicitud al proveedor de API?

Usa el identificador de correlación que el proveedor devuelve o acepta, y regístralo en cada límite. Si el proveedor no ofrece uno, genera un identificador de solicitud del cliente y envíalo en una cabecera personalizada documentada cuando esté permitido. Nunca dependas solo de una marca de tiempo para relacionar registros.

¿Qué formato de marca de tiempo debo usar para investigar un incidente de API?

Usa UTC y conserva la cadena de marca de tiempo original, el desplazamiento de zona horaria, la precisión y la fuente del reloj. Compara un intervalo en lugar de exigir una coincidencia exacta. Una diferencia de un segundo puede ser inofensiva, pero un registro fuera de toda la duración de la ejecución necesita una explicación.

¿Puede una llamada a una API tener éxito aunque el agente informe de una interrupción?

Una interrupción indica que el cliente no recibió una respuesta utilizable a tiempo. El proveedor aún puede haber aceptado y completado la solicitud, especialmente si era una operación de escritura. Busca el identificador de solicitud e inspecciona el recurso resultante antes de reintentar.

¿Qué amplitud debe tener el intervalo de tiempo al comparar registros?

Empieza con un intervalo pequeño alrededor del evento y amplíalo solo cuando tengas un motivo concreto, como una desviación de reloj observada o una cola asíncrona. Las búsquedas amplias producen coincidencias accidentales, sobre todo durante ejecuciones intensas de agentes. Registra cada cambio del intervalo en las notas del caso.

¿Qué debo hacer si una solicitud fallida del agente pudo haber creado un recurso?

No reintentes a ciegas. Primero consulta el recurso mediante una clave de idempotencia, el identificador de solicitud del proveedor o un identificador de negocio que la llamada original hubiera creado. Si la API no admite una repetición segura para una escritura, es un problema de diseño que debes resolver antes de dar acceso a los agentes.

¿Qué pruebas debo conservar durante una investigación de registros de API?

Conserva los datos de eventos cifrados originales, su resultado de verificación, los registros exportados del proveedor y una tabla breve de conciliación. Calcula hashes de los archivos exportados y registra quién los recopiló y cuándo. Las capturas ayudan a explicar el caso, pero por sí solas son pruebas débiles.

¿La firma de código puede demostrar que una acción del agente estaba autorizada?

No. El nombre de un proceso firmado puede identificar el programa local que hizo una solicitud por una ruta aprobada, pero no demuestra que la intención de negocio fuera correcta. Inspecciona el endpoint exacto, el método, los parámetros, el resultado y cualquier efecto posterior.

¿Por qué hay huecos en los registros de los proveedores de API?

Los proveedores suelen conservar distintas clases de eventos durante periodos diferentes y pueden omitir solicitudes rechazadas, almacenadas en caché o asíncronas de la vista que consultaste primero. Define la cobertura esperada antes de un incidente, incluida la retención y los campos de cada exportación. No puedes reconstruir pruebas después de que el proveedor las haya eliminado.

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