Tarde o temprano, alguien con autoridad sobre un agente de IA pide el registro: todo lo que hizo el agente con consecuencias, en orden y sin alteraciones. La respuesta habitual de las plataformas de agentes es un log de auditoría completo, centralizado y consultable, y es una mejora real frente a logs de aplicación dispersos.

Lo que el auditor necesita saber, sin embargo, es si le puede creer a ese log; que exista es apenas la condición previa. Un log completo guardado en una base de datos que controla el proveedor contesta si hay log y esquiva, sin decirlo, si se le puede creer. El proveedor, o cualquiera con acceso privilegiado a esa base, puede editar una fila, borrar un evento o cambiar el orden de una secuencia, y nada en el log lo dejaría ver. El registro vale entonces lo que vale la palabra de quien lo lleva, y un regulador no está para aceptar esa palabra a ciegas.

Venkat Peri, que trabaja en infraestructura de IA agéntica para gestión patrimonial en Advisor360°, plantea lo mismo desde la capa que hace cumplir las reglas en The Complete Architecture for Trustworthy Autonomous Agents: "un log producido por la aplicación puede ser alterado por la aplicación" [1]. La respuesta de Peri es un registro escrito por una capa que la aplicación no puede modificar. Este artículo toma el otro camino: un registro cuya alteración cualquiera puede detectar, salvo que quien lo altere tenga también la clave de firma.

La auditoría habitual, contada sin caricatura

El enfoque dominante es la completitud: capturar todo, centralizarlo, hacerlo consultable y restringirlo por roles. Bien hecho, es durable y exhaustivo, y nada de lo que sigue discute la completitud: hace falta. La discusión va por otro eje. Un log puede estar completo y aun así no ser verificable, porque su integridad depende por entero de confiar en el sistema que lo guarda. La completitud responde "¿está todo?" y deja abierta "¿lo cambiaron?", que es justamente la pregunta que ataca un adversario con acceso a la base.

La inversión: que la alteración sea detectable

La alternativa estructural es dejar de pedirle al auditor que confíe en el lugar donde se guarda el registro. Cada evento de máquina de estados y de flow se encadena al anterior con un hash criptográfico, y cada hora la cadena se sella con un checkpoint firmado:

Una cadena de hashes SHA-256 sobre el log de eventos, sellada con checkpoints firmados con Ed25519: un verificador offline ubica un evento alterado o borrado en su número de secuencia exacto.

event_hash = SHA-256( canonical(content) ‖ prev_hash ‖ seq )
checkpoint = Ed25519-sign( canonical{ tenant, log, seq, chain_head, prev_checkpoint, window_id, signed_at, kid } )

Nada de esto es criptografía nueva: los registros de auditoría de la nube publican desde hace años resúmenes firmados y encadenados por hash. Lo poco común es aplicarlo a lo que hizo un agente.

Lo que sale de esta construcción no depende de la política de nadie. Si se cambia el contenido de un evento pasado que cubre un checkpoint, su hash recalculado deja de coincidir con el guardado y con el eslabón siguiente: la cadena se rompe en ese evento exacto. Si se borra un evento, la secuencia queda con un hueco. Si se inserta uno, no encadena. Si se recalcula el resto de la cadena para tapar el cambio, la cabeza deja de coincidir con el checkpoint firmado, y firmar uno nuevo requiere la clave de firma.

El chequeo corre offline, para cualquiera que tenga la clave pública publicada. El primer comando baja esa clave; el segundo exporta el bundle firmado, y para eso hace falta una cuenta del tenant con permiso para leer su auditoría. En la corrida de abajo, del 23 de septiembre de 2026, los dos salieron de un deployment local de desarrollo, con 51 eventos de flow y 25 checkpoints firmados con su clave de desarrollo:

$ zarel trust-keys fetch <deployment-host> -o trust-keys.json   # la clave, desde AFUERA del bundle
$ zarel audit evidence flows -o bundle.tar.gz                   # el bundle firmado
$ zarel verify bundle.tar.gz --keys trust-keys.json
✓ Audit chain bundle.tar.gz verified and attested.
  Covered seq: 1..51
  Checkpoints verified: 25
  Signed by: k_1c3770f5d8450a57
  Anchoring: no external timestamp anchor in range (self-asserted time only).
  Transparency log: none in this bundle.

# el mismo bundle, con el evento 26 cambiado y el bundle vuelto a firmar:
$ zarel verify bundle-rewritten.tar.gz --keys trust-keys.json
✗ Audit chain verification FAILED (2 anomalies):
  seq 26: event_hash_mismatch
  seq 27: prev_hash_mismatch
  Anchoring: no external timestamp anchor in range (self-asserted time only).
  Transparency log: none in this bundle.

El auditor no necesita ninguna respuesta de nuestra API: toma los eventos, los checkpoints y la clave pública, corre el verificador en su máquina, y el resultado verifica o falla en el número de secuencia donde se tocó el registro. La confianza deja de estar puesta en nuestra infraestructura y pasa a una clave, que tenés solo vos cuando el deployment lo operás vos.

Por qué esta es la pieza que faltaba

El resto de esta serie construye un agente que propone en lugar de actuar y que, en los límites regulatorios, rechaza con una salida de control determinística. Las dos cosas dejan registros (el rechazo que se disparó; un hash y una copia enmascarada del valor que rechazó un binding) en sus propias tablas de auditoría, que todavía no están en la cadena de hashes. Lo que la cadena cubre hoy es lo que se ejecutó: cada transición de estado y cada paso de flow. Un registro vale lo que vale poder demostrar que nadie lo editó después, y la auditoría tamper-evident es lo que cierra el recorrido: proponer, pasar el control, ejecutar y después demostrar que lo ejecutado ocurrió tal como quedó registrado.

Los límites honestos

Es tamper-evident (deja la manipulación a la vista), no tamper-proof (a prueba de manipulación). No frena a un operador privilegiado que altera una fila. Garantiza que la alteración no pase inadvertida para cualquiera que verifique contra la cadena firmada. Quien diga "inmutable" o "a prueba de manipulación" de una base de datos en la que un operador puede escribir está exagerando, y un auditor lo va a notar.

La garantía vale lo que valga el lugar donde viven la clave y los checkpoints. La detección funciona contra cualquiera salvo contra quien pueda reescribir la cadena y volver a firmarla con una clave en la que el verificador todavía confía. Fuera de desarrollo, los checkpoints se firman con una clave guardada en el KMS del operador del deployment. Si corrés Zarel vos, el operador sos vos: la clave de firma vive en tu KMS, el proveedor nunca tiene material de firma, y "verificable sin confiar en Zarel" es literal, porque no podemos reescribir y volver a firmar un registro para el que no tenemos clave. Si el deployment lo operamos nosotros, somos el operador con acceso a la clave, y ahí la afirmación honesta se reduce a tamper-evident y verificable de forma independiente y offline: un operador privilegiado podría, en principio, reescribir y volver a firmar antes de que un tercero guarde un checkpoint. Un deployment de producción exige además una autoridad de sellado de tiempo RFC 3161, y cada hora cerrada de checkpoints queda anclada ahí. Para cada hora anclada, eso prueba que los checkpoints existían antes del sello de la autoridad, así que nadie puede antedatarlos; una reescritura que se vuelve a anclar después solo queda expuesta ante quien ya tenga el anclaje anterior. Achica la brecha del modo hosteado sin cerrarla. El bundle de desarrollo de arriba no trae ni anclaje ni prueba de un log de transparencia, y el verificador informa que faltan los dos.

Da fe de la integridad de lo que se escribió, y de nada más. La cadena demuestra que ningún evento registrado se cambió, se borró ni se reordenó. No puede dar fe de un evento que la aplicación nunca emitió.

Lo que está en juego

Un log completo alcanza para un cuestionario de compliance; frente a un adversario hace falta uno verificable. La pregunta que termina llegando, de un auditor que reconstruye un incidente o de tu propio equipo legal antes de poner el registro delante de un regulador, es cómo se sabe que ese log es el que produjo el sistema. La respuesta que se sostiene es un chequeo que hace el auditor: "corré el verificador vos mismo; si algo se movió, falla en el evento exacto".

Las herramientas se pueden revisar hoy, aunque todavía no contra un deployment en vivo. zarel verify viene en el CLI publicado en npm (@zarel-ai/cli), y el verificador de la cadena que usa está publicado bajo Apache-2.0 (@zarel-ai/audit-chain). Lo que un lector todavía no puede hacer es exportar un bundle: no hay un deployment público arriba, y por eso la corrida de más arriba sale de uno local. Cómo funciona muestra dónde entra el registro en la secuencia de proponer, controlar y demostrar.

Esta es la capa de prueba de una línea más amplia: la comunicación y la propuesta pueden ser probabilísticas, pero la autoridad, la consecuencia, el compliance y el registro de los tres tienen que ser determinísticos, declarados y verificables. El argumento general está en No se combate el probabilismo con probabilismo; el caso del rechazo regulado está en El rechazo es una salida de control, no una conversación; el caso de la aplicación estructural está en El agente propone; el runtime aprieta el botón.


Las citas están traducidas por el autor. Los originales, en inglés:

  1. Peri, The Complete Architecture for Trustworthy Autonomous Agents: "a log produced by the application can be altered by the application".

Nicolás Moreno construye Zarel: operaciones de IA gobernadas, donde la IA propone y el contrato dispone.