Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help


id: ADR-018
title: La seguridad en tiempo de ejecución y la procedencia utilizan límites de decisión propiedad del runtime
date: 2026-08-17
status: propuesto
relates-to:
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7142
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6971
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6954
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7432
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7141
  • https://github.com/zeroclaw-labs/zeroclaw/issues/7155
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6996
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6909
  • https://github.com/zeroclaw-labs/zeroclaw/issues/3767
  • https://github.com/zeroclaw-labs/zeroclaw/issues/6105
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8583
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8289
  • https://github.com/zeroclaw-labs/zeroclaw/issues/8290
  • https://github.com/zeroclaw-labs/zeroclaw/pull/10425
  • docs/book/src/architecture/request-lifecycle.md
  • docs/book/src/architecture/background-work-lifecycle.md
  • docs/book/src/architecture/tool-execution-lifecycle.md
  • docs/book/src/security/model.md
  • crates/zeroclaw-api/src/ingress.rs
  • crates/zeroclaw-runtime/src/agent/turn/mod.rs
  • crates/zeroclaw-runtime/src/security/ingress.rs
  • crates/zeroclaw-runtime/src/security/audit.rs
  • crates/zeroclaw-runtime/src/approval/mod.rs
  • crates/zeroclaw-runtime/src/cron/scheduler.rs
  • crates/zeroclaw-runtime/src/tools/send_message_to_peer.rs
  • crates/zeroclaw-runtime/src/tools/spawn_subagent.rs

ADR-018: Seguridad en tiempo de ejecución y procedencia Usar límites de decisión propiedad del runtime

Contexto

ZeroClaw tiene varias rutas sensibles desde el punto de vista de la seguridad que necesitan todas la misma respuesta a tres preguntas: quién o qué originó este trabajo, qué política lo permitió y qué evidencia demuestra que el límite se aplicó antes de que se produjera el efecto. Las llamadas a herramientas, los comandos de shell, las mutaciones de gateway y RPC, los trabajos programados, los pasos de SOP, los mensajes de steering y los envíos a agentes pares han respondido históricamente a esas preguntas en lugares distintos.

Esa división crea dos modos de fallo. Una nueva ruta de acción puede omitir un paso, como la aprobación, el sellado de procedencia, la validación final del destino o la evidencia de auditoría. Un nuevo punto de extensión también puede volverse demasiado poderoso si puede decidir la política, suprimir la evidencia canónica y gestionar la respuesta a incidentes como un proveedor reemplazable.

Tres RFC aceptados describen la arquitectura que corrige esto en el límite de ejecución:

  • #7142 acepta un canal de decisiones de seguridad gestionado por el runtime para las acciones protegidas. El canal combina la política integrada, las concesiones de principales canónicos, los requisitos de aprobación, las restricciones del sandbox, las superposiciones restrictivas, las huellas digitales de las acciones, los permisos de runtime de un solo uso, los eventos de auditoría canónicos y los registros de resultados.
  • #6971 acepta la autoridad sobre la superficie de credenciales, la presentación de informes de postura de seguridad y una única ruta de admisión de modelos propiedad del runtime. Los campos de configuración con forma de credencial requieren clasificaciones de tratamiento explícitas, los valores protegidos permanecen fuera de las rutas de guardado y de lectura de propiedades, y el mapa de límites de credenciales del runtime identifica dónde pueden circular credenciales en texto plano. Cada turno dirigido al modelo y cada inyección de steering recibe un envoltorio de entrada de confianza antes de que el modelo lo vea, mientras que la autenticación en el borde de transporte y los controles contra abuso permanecen fuera de esa capa compartida de admisión de modelos.
  • #6954 acepta la procedencia gestionada por el runtime para los turnos iniciados internamente. El trabajo de cron, daemon, SOP, subagente y agente par debe incluir principales internos, vinculación de conversación, procedencia de respuesta, comportamiento explícito ante contexto faltante y resultados de ejecución, entrega y persistencia por separado.

Estas decisiones están relacionadas con, pero no sustituyen a, la decisión sobre el principal canónico en #7141, la decisión sobre confirmación de comandos y herramientas en #7155, la decisión sobre el sandbox del sistema de archivos en #6996, ni la validación de destino específica de cada consumidor, como la de #6909.

La base de código actual contiene trabajo preparatorio importante, pero no el objetivo completo. IngressContext, TurnOrigin e IngressDecision ya existen; el motor de turnos invoca la política de ingreso al entrar en el bucle y al vaciar el steering; la política predeterminada devuelve Loop; AuditLogger es una estructura base reutilizable de cadena de hash; y ya se ha iniciado el trabajo preparatorio de principales canónicos. La fase de principal interno y de resultado separado sigue en revisión en #10425. Este ADR registra la arquitectura objetivo y permanece en estado propuesto hasta que se cumplan los criterios de cumplimiento indicados a continuación.

Decisión

Mantén el runtime como autoridad de seguridad obligatoria

Las acciones protegidas pasan por un único pipeline de decisión de seguridad propiedad del runtime antes de su ejecución o mutación. El pipeline construye una solicitud tipada a partir del contexto de runtime de confianza, resuelve la política integrada y los permisos concedidos al principal canónico, aplica las restricciones de no escalada de privilegios y de sandbox, compone superposiciones restrictivas, recaba la aprobación de confianza cuando es necesaria, revalida la vigencia inmediatamente antes del efecto, genera evidencia de auditoría canónica, emite un permiso de runtime de un solo uso y consume ese permiso en el límite de ejecución propio.

El permiso es el traspaso entre la decisión y el efecto. Está vinculado a la acción normalizada, al principal, a las generaciones de la política, a la época de ejecución (runtime epoch), a la identidad del objetivo, al vencimiento de la aprobación y al esquema de fingerprint. No puede serializarse, reconstruirse a partir de los argumentos, duplicarse para una acción hermana ni consumirse más de una vez.

Se deniega el trabajo sensible para la seguridad cuando el entorno de ejecución no puede clasificarlo. Un nuevo límite protegido debe registrarse en el inventario de acciones o en una estructura mecánicamente equivalente que indique el propietario, el constructor de solicitudes, el límite de ejecución, las capas de política obligatorias y la clasificación de auditoría.

Dejar que las extensiones restrinjan la política, no reemplazar el mínimo

Las superposiciones restrictivas pueden denegar una acción, reducir sus recursos o exigir una aprobación más sólida o más reciente. No pueden convertir una denegación en una autorización, ampliar las concesiones de principal, debilitar los límites del sandbox o del perfil de riesgo, elegirse a sí mismas a partir de datos de solicitud no confiables, suprimir los eventos de auditoría canónicos ni marcar como completada la respuesta base a incidentes.

Los receptores y sinks de auditoría opcionales son puntos de extensión independientes. Pueden recibir proyecciones redactadas o añadir comportamientos de contención y notificación, pero no pueden eliminar, reescribir, retrasar ni reemplazar el evento canónico creado en tiempo de ejecución ni los hooks base del runtime.

Las futuras APIs públicas de plugins, WIT, políticas remotas, bibliotecas dinámicas o respondedores de incidentes requieren su propia revisión de implementación y de confianza. Este ADR acepta los límites de autoridad, no una ABI especulativa para proveedores de seguridad de terceros.

Mantén las superficies de credenciales clasificadas y protegidas

Los campos de configuración con forma de credencial deben tener clasificaciones de manejo explícitas, como secreto cifrado, referencia solo de ruta, valor público, almacén de autenticación externo, ruta de entorno de compatibilidad o requiere seguimiento. Un nuevo campo con forma de credencial no puede entrar en el esquema sin una prueba de clasificación, una auditoría o un ratchet mecánicamente equivalente.

Los valores de credenciales protegidos deben mantenerse fuera de las rutas de guardado y de lectura de propiedades. La capa de clasificación indica cómo se almacenan o se exponen los valores; por sí sola, no decide todos los componentes de ejecución que pueden recibir texto plano.

Un mapa independiente de los límites de credenciales en tiempo de ejecución identifica dónde puede fluir texto plano a través de los clientes de proveedores y canales, las herramientas, los servidores MCP, el trabajo delegado, los envoltorios de CLI, los manejadores de gateway, los registros, los recibos, los eventos y las rutas de error. Este ADR registra ese mapa como una puerta de implementación obligatoria y permite un endurecimiento focalizado guiado por él, pero no acepta un broker de credenciales completo ni un nuevo perfil de aislamiento por defecto.

Usa una única ruta de admisión de modelos para el contenido entrante

Cada turno destinado al modelo pasa por la política de ingreso compartida antes de la ejecución del modelo. Cada inyección de dirección recibe su propio sobre de ingreso de confianza y se evalúa con él, en lugar de heredar datos obsoletos del remitente, el mensaje, el transporte o la confianza del turno original.

El interruptor de ingreso produce Loop, Annotate, Gate o Drop. El valor predeterminado Loop preserva el comportamiento actual y no asigna trabajo SOP gestionado. Annotate enmarca el contenido como datos no confiables antes de continuar. Gate traslada el turno a una ruta de decisión humana o SOP gestionada. Drop rechaza el turno y registra el motivo.

Los controles de borde del transporte siguen siendo obligatorios y separados. El emparejamiento de canales, las listas de remitentes permitidos, las verificaciones de firma, la validación de la carga útil, la limitación de tasa, el filtrado específico de cada protocolo y los controles contra el abuso de recursos se ejecutan antes de la capa compartida de admisión al modelo. Esa capa compartida decide si el contenido normalizado puede entrar en el modelo; no autentica el transporte.

Antes de que una política configurable distinta de Loop sea alcanzable, las disposiciones distintas de Loop que aún no están implementadas deben fallar en modo seguro. Una rama Gate que cae por defecto en Loop no es compatible con esta decisión una vez que la configuración pueda seleccionar Gate.

Registrar la procedencia a partir de datos del tiempo de ejecución

La procedencia la registra el código de entrada de tiempo de ejecución de confianza, nunca el contenido del mensaje ni los argumentos de las herramientas. El origen y la confianza son hechos distintos. El trabajo interno, programado, delegado o retransmitido puede derivar de contenido externo y no adquiere confianza por el mero hecho de que quien lo invoca sea interno.

Los principales canónicos de #7141 proporcionan la identidad del actor autenticado y los permisos (grants) cuando existe un actor externo o autenticado. Los principales internos de #6954 identifican iniciadores propiedad del runtime, como trabajos de cron, tareas del daemon, pasos de SOP, despacho a agentes pares y sub-turnos anidados. Esos principales internos son hechos de procedencia, no pares externos, y nunca aparecen en los grupos de pares ni en las tablas de permisos como si fueran usuarios de transporte.

Los subturnos conservan la procedencia del padre o registran una cadena de padres, de modo que el trabajo delegado no pierda los datos de identidad y confianza que lo originaron. Los turnos originados por SOP y por el daemon deben usar nombres que distingan sus fuentes de tarea concretas en las trazas y los registros de ejecución.

Vincular el trabajo interno a las conversaciones sin transferir la autoridad

Un turno iniciado internamente puede llevar un único enlace de conversación interno del entorno de ejecución. El enlace indica de dónde se debe cargar el historial y dónde debe añadirse el turno completado, sujeto a las reglas normales de recorte y persistencia. El session_target = "main" de cron se enlaza a la sesión interactiva principal del agente; isolated no lleva ningún enlace de forma deliberada.

Vincular no es entrega ni recuperación de memoria. El vínculo responde a qué conversación es dueña del contexto y de los añadidos. La entrega responde a dónde ve el usuario un anuncio o una respuesta. La recuperación de memoria sigue controlada por la política de inyección de memoria.

Las respuestas entre agentes pares usan una procedencia de respuesta opaca, no una sesión compartida. El turno del remitente captura un identificador de correlación, la identidad del remitente y el vínculo de su conversación antes del envío. El destinatario se ejecuta como su propio agente y no puede leer ni desreferenciar el identificador de sesión del remitente. Al completarse, el runtime añade o entrega el texto final del destinatario siguiendo esa procedencia.

La procedencia de las respuestas entre pares en V1 es local al proceso. Un turno completado del destinatario en un proceso activo debe entregarse siguiendo la procedencia o registrar un resultado de entrega fallida, pero los envíos degrade en vuelo sin vincular pueden perderse ante una caída del proceso. Una fila de envío duradera o una cola duradera es un seguimiento separado, no parte de esta decisión de V1.

El contexto faltante es explícito. isolated significa que no se espera ninguna vinculación, require rechaza el despacho cuando no se puede derivar la procedencia de la respuesta requerida, y degrade se ejecuta sin la vinculación y registra la degradación. El destinatario o el contenido del mensaje no pueden debilitar require hasta convertirlo en degrade.

Mantén los resultados y la evidencia de estado por separado

La ejecución, la entrega, la persistencia y la durabilidad de la auditoría son resultados independientes. Un estado de compatibilidad puede resumirlos, pero debe derivarse de los ejes independientes en lugar de escribirse como una fuente de verdad competidora.

Los informes de postura de seguridad distinguen la intención configurada, la capacidad resuelta o sondeada, y la aplicación verificada en tiempo de ejecución. Las palabras como active y enforced están reservadas para la evidencia vinculada a la instancia de ejecución que realmente aplicó el límite. Las proyecciones, los registros, los eventos del observador y los recibos opcionales pueden exponer evidencia útil, pero no se convierten en otra autoridad de seguridad.

Cuando el sumidero de auditoría duradero canónico está habilitado, el evento previo a la ejecución se confirma antes de la mutación protegida. Si esa confirmación falla, la mutación se deniega y el estado de seguridad informa del estado degradado o no disponible. Un fallo al escribir el resultado tras un efecto registra un estado de auditoría explícito de desconocido o degradado, porque una acción que ya se ejecutó no puede deshacerse por la persistencia de la auditoría.

Mantén el despliegue fragmentado y reversible

La implementación sigue el tracker de enrutamiento en #7432 y los issues y PRs de implementación específicos enlazados desde los RFC de origen. El pipeline de seguridad en tiempo de ejecución, el sink de auditoría canónico, la clasificación de superficies de credenciales, el mapa de límites de credenciales en tiempo de ejecución, el sellado de ingreso, la política no-Loop, el envelope de principal interno, el enlace de conversación, la procedencia de respuestas de pares y el seguimiento del despacho duradero deben integrarse como slices revisables de forma independiente.

No ningún PR debe intentar enrutar todas las acciones, todos los transportes, todos los destinos de auditoría y todos los consumidores de turnos internos hacia el objetivo completo de una sola vez. Cada fragmento debe conservar el comportamiento predeterminado existente, a menos que ese fragmento sea responsable explícitamente de un cambio de compatibilidad.

Controles de aceptación

Este ADR permanece propuesto hasta que se cumplan todas estas condiciones:

  • El pipeline de acciones en tiempo de ejecución cuenta con un vocabulario tipado de solicitudes y decisiones, un inventario de acciones o un mecanismo equivalente de restricción progresiva (ratchet) para los límites protegidos, un permiso de un solo uso e infalsificable, comprobaciones de frescura de generación y de época de ejecución, y una revalidación final del objetivo en el límite de ejecución o mutación que le pertenece;

  • Las rutas directas, anidadas, programadas, delegadas, SOP, de puerta de enlace (gateway), RPC y de herramientas sensibles a la seguridad no pueden eludir el límite del pipeline registrado, y las acciones protegidas desconocidas o no clasificadas fallan de forma cerrada;

  • política integrada, concesiones de principal (#7141), sin escalada de privilegios, procedencia de la aprobación (#7155), restricciones del sandbox (#6996) y revalidación específica del consumidor, como #6909, siguen siendo capas obligatorias fuera del control de la superposición restrictiva;

  • credential-shaped config fields have explicit handling classifications, with a schema audit, test, or equivalent ratchet that fails new unclassified fields;

    Translated to Spanish:

    Los campos de configuración con forma de credencial tienen clasificaciones de tratamiento explícitas, con una auditoría de esquema, una prueba o un mecanismo equivalente de control progresivo que falla ante nuevos campos sin clasificar;

  • protected credential values remain absent from save and property-readback paths, with non-exposure coverage where applicable;

    Wait, the input is English and needs translation to Spanish. Translating:

    los valores de credenciales protegidos siguen ausentes de las rutas de guardado y de lectura de propiedades, con cobertura de no exposición donde corresponda;

  • el mapa de límites de credenciales en tiempo de ejecución cubre los clientes de proveedores y de canales, las herramientas, los servidores MCP, el trabajo delegado, los envoltorios de CLI, los manejadores de gateway, los registros, los recibos, los eventos y las rutas de error, y las brechas de endurecimiento resultantes se dirigen a seguimientos específicos en lugar de tratarse como un broker de credenciales aceptado;

  • la fuente canónica de eventos de seguridad minimizada se crea en tiempo de ejecución, incluye decisiones de política y evidencia de resultado sin cargas secretas, y el sumidero duradero habilitado confirma el evento previo a la ejecución antes de la mutación o deniega la mutación ante un fallo de persistencia;

  • Los destinos de auditoría opcionales y los respondedores de incidentes pueden añadir proyecciones o respuestas, pero no pueden suprimir, reemplazar, retrasar ni reescribir la evidencia canónica ni los hooks de runtime base;

  • Cada turno dirigido al modelo y cada inyección de steering recibe su propio envoltorio de ingreso de confianza, con transporte, remitente o principal, identidad del mensaje cuando esté disponible, origen y datos de confianza, estampados por el código de entrada y no por el contenido del mensaje;

  • configurable Annotate, Gate y Drop no se pueden habilitar hasta que las disposiciones no implementadas distintas de Loop fallen de forma segura (fail closed) con evidencia de auditoría y pruebas;

  • Los controles de autenticación en el borde de transporte, el emparejamiento, las listas de permitidos, las verificaciones de firma, la validación de cargas útiles, los límites de frecuencia, el filtrado de mensajes propios y de bots, y los controles contra abusos siguen aplicándose antes de la admisión del modelo normalizado.

  • internal principals are implemented for cron, daemon/SOP, peer-agent, and subturn entry points, with tests proving they are provenance facts and never peer-membership grants;

    Wait — I should translate this to Spanish, not return it unchanged. The source is English, so the translation is:

    principals internos están implementados para los puntos de entrada de cron, daemon/SOP, peer-agent y subturn, con pruebas que demuestran que son hechos de procedencia y nunca concesiones de pertenencia a pares;

  • El enlace de conversación carga y añade historial mediante un propietario serializado por conversación, cron session_target = "main" se vuelve visible en el siguiente turno interactivo, y isolated permanece deliberadamente sin vincular;

  • peer reply provenance entrega o registra la salida completada del destinatario en proceso activo sin exponer el identificador de sesión del remitente al destinatario, y require no puede ser debilitado por el destinatario ni por el contenido del mensaje;

  • los resultados de ejecución, entrega y persistencia siguen almacenándose o emitiéndose de forma independiente, y cualquier resumen de compatibilidad se deriva de esos ejes;

  • la documentación de postura, lanzamientos y documentación permanente utiliza con precisión el lenguaje de evidencia configurado, resuelto/sondeado y verificado en tiempo de ejecución, incluida la corrección de afirmaciones previas de aplicación activa que solo correspondían al andamiaje de la fase 1; y

  • #7432 y los rastreadores de implementación específicos identifican las entregas pendientes, los responsables, las pruebas y las notas de lanzamiento o de reversión antes de marcar este ADR como aceptado.

Consecuencias

Consecuencias positivas:

  • Los revisores obtienen una única pregunta gestionada por el runtime para los efectos protegidos: ¿esta acción recibió una decisión vigente y consumió un permiso válido en su límite?
  • Las extensiones de seguridad resultan menos peligrosas porque pueden restringir o proyectar, pero no reemplazar el mínimo obligatorio.
  • Las decisiones de contenido entrante, los mensajes de dirección, el trabajo programado y las respuestas de agentes pares comparten un vocabulario de procedencia en lugar de inventar historias de confianza locales.
  • Los operadores pueden distinguir la política configurada, la capacidad resuelta y la aplicación verificada en tiempo de ejecución, en lugar de tratar toda la salida de estado como igualmente comprobada.
  • El trabajo interno puede participar en el historial de conversación y en el enrutamiento de respuestas sin convertir los trabajos cron, los pasos de SOP ni los agentes pares en pares de canal externo falsos.

Consecuencias negativas:

  • El entorno de ejecución debe conservar más contexto estructurado a través de los límites de acciones y turnos.
  • Algunas rutas de código actualmente útiles siguen solo parcialmente demostradas hasta que sus fragmentos de implementación añadan los controles de regresión y las pruebas mencionados anteriormente.
  • A un despliegue que conserva los valores por defecto le toma más tiempo que una única reescritura de seguridad de gran alcance.
  • El comportamiento de ingreso distinto de Loop y el despacho duradero entre pares no pueden lanzarse a la ligera; antes necesitan evidencia de fallos, procedencia y compatibilidad.
  • La auditoría de durabilidad introduce E/S de archivos y un comportamiento de fallo cerrado cuando está habilitada, por lo que la compatibilidad y la reversión deben ser explícitas.

Referencias