Vaara
Vaara es la capa de evidencia en tiempo de ejecución a prueba de manipulaciones para sistemas de IA. Cubre el cumplimiento de la Ley de IA de la UE y cualquier otro caso en el que necesites demostrar lo que realmente hizo un agente. Código abierto, sin SaaS, sin telemetría.
Documentación
Autonomía con rendición de cuentas.
Un recibo verificable para cada acción autónoma, comprobable por cualquiera.
Tu agente de IA transfirió los fondos, escribió el archivo, llamó a la herramienta. Más tarde, alguien que no confía en ti te pide que demuestres exactamente qué hizo y por qué: un regulador, un auditor, un cliente después de un incidente. Tus propios registros no lo resolverán, porque podrías haberlos editado.
Inicio rápido
pip install vaara # Python: CLI, MCP proxy, server
brew tap vaaraio/tap && brew install vaara # macOS: CLI + menu-bar app (built from source)
npm install @vaara/client # TypeScript client for the HTTP API
import vaara
@vaara.govern
def transfer_funds(to: str, amount: float) -> str:
...
Eso es todo. Cada llamada a una función gobernada recibe una puntuación de riesgo y se decide contra tu política antes de que el cuerpo se ejecute. Una llamada permitida se ejecuta, y la decisión, la llamada y el resultado aterrizan en un registro encadenado por hash y a prueba de manipulaciones que cualquiera puede verificar sin conexión. Fírmalo al exportar (vaara trail export) para obtener una prueba de terceros. Los registros persisten en ~/.vaara/trail/audit.db por defecto, por lo que la evidencia sobrevive a los reinicios. Python 3.10+, cero dependencias en tiempo de ejecución.
Tanto deny como escalate lanzan vaara.Blocked, ya que una escalada significa que un humano aún no ha respondido. Ejecuta el ejemplo anterior en una instalación nueva y lanzará una excepción: sin historial de resultados, el intervalo de confianza del puntuador es amplio, y un tx.transfer escala en el límite superior del intervalo aunque su estimación puntual esté por debajo del umbral de permitido. Esa es la dirección prevista para fallar, y se estabiliza. Alimentar resultados reales de vuelta a través de report_outcome estrecha el intervalo, y la misma llamada comienza a permitirse después de unas pocas docenas de resultados limpios. Para observar las decisiones sin actuar sobre ellas mientras eso sucede, comienza con @vaara.govern(shadow=True).
Verifica un recibo sin nada instalado
vaara.io/verify.html es la Vaara Resin. Un solo archivo HTML, sin paso de compilación y sin dependencias. Pega un recibo y recalcula la codificación previa a la autenticación DSSE, toma su digesto y verifica la firma Ed25519 con WebCrypto. El recibo nunca sale de la pestaña, nada se sube y la página funciona con la red apagada, por lo que la verificación no es un servicio y Vaara no es parte de ella. Guarda el archivo y sigue funcionando.
También indica lo que una verificación exitosa no establece: que la clave pertenece a la parte que esperas, que la declaración firmada es verdadera, que decided_at significa algo sin una autoridad de tiempo externa, o que un recibo es una historia completa.
El explorador en la misma página lee el registro de transparencia público directamente desde tu navegador. Busca un encabezado de cadena por digesto, o pega una clave pública para ver todo lo publicado bajo ella. Sin cuenta y sin inicio de sesión, porque la clave es la identidad. Publicar en ese registro es opcional y está desactivado por defecto (vaara trail publish-head), por lo que una ausencia allí significa que no se publicó nada, no que no ocurrió nada.
Ve quién más lo ha verificado
vaara.io/conformance.html es la página de resultados. Contiene cada suite y su veredicto, y cada parte distinta del mantenedor que ejecutó los verificadores e informó lo que encontró en público. Las filas están encadenadas, cada una contiene el digesto de la fila anterior, por lo que eliminar o reordenar una rompe cada digesto posterior y la ruptura es visible para cualquiera. El mantenedor tampoco puede eliminar una fila. Una ejecución que no está de acuerdo con la nuestra también es una fila, con la razón indicada, y no hay lista negra.
El ejecutor agregado califica todas las suites a la vez, y califica los vectores de otra implementación de la misma manera:
python scripts/conformance_runner.py # grade the reference corpus
python scripts/conformance_runner.py --vectors-dir ./your_vectors # grade your own
Imprime un enlace precargado al final de cada ejecución, por lo que solicitar una fila toma un clic. El conjunto de reglas nombrado y versionado, lo que una aprobación establece y no establece, y la lista completa de suites están en docs/conformance-profile.md.
¿Prefieres el pipeline explícito?
El decorador impulsa el mismo motor que puedes llamar directamente cuando quieres el objeto de decisión en la mano.
from vaara.pipeline import InterceptionPipeline
pipeline = InterceptionPipeline()
result = pipeline.intercept(
agent_id="agent-007",
tool_name="fs.write_file",
parameters={"path": "/etc/service.yaml", "content": "..."},
agent_confidence=0.8,
)
if result.allowed:
pipeline.report_outcome(result.action_id, outcome_severity=0.0)
else:
print(result.reason)
Cada llamada recibe una puntuación de riesgo y una decisión de permitir / bloquear / escalar contra tu política, luego la llamada, la decisión y el resultado real se escriben en el registro de auditoría. report_outcome cierra el ciclo: el puntuador re-pondera según qué señales realmente predijeron el resultado. Las versiones incluyen procedencia SLSA Build Level 3, verificable con slsa-verifier verify-artifact. Clasificador ML opcional: pip install 'vaara[ml]'.
Verifícalo sin confiar en el productor
Escribir un registro es la mitad fácil. La mitad que importa es permitir que alguien que no confía en ti lo verifique, sin clave, sin acceso y sin ninguno de tu código. Cada registro de Vaara está direccionado por contenido y cierra en fallo en autenticidad, y se envía con vectores de conformidad públicos más un verificador independiente que no importa código de Vaara, por lo que una parte independiente reproduce cada veredicto sin conexión.
vaara verify-bundle evidence-bundle.json
ok solo cuando una firma está realmente establecida, no meramente presente en un registro. La misma propiedad impulsa el trabajo de estándares detrás del Vaara Receipt Internet-Draft: evidencia que se sostiene para alguien que no ejecuta ninguno de tu software. El conjunto completo de verificadores, el modelo de confianza para cada verbo y de dónde proviene la confianza en cada caso están en docs/verifying-evidence.md.
Para verificar esa afirmación tú mismo, sin instalar Vaara, ejecuta el verificador independiente contra los vectores publicados. Sus únicas dependencias son cryptography y rfc8785:
git clone https://github.com/vaaraio/vaara
cd vaara
pip install cryptography rfc8785 # the checker's only dependencies
python tests/vectors/external_evidence_v0/_check_independent.py
Re-deriva cada veredicto a partir de los bytes del recibo y la clave pública solamente. La salida muestra la propiedad para la que está construido el registro: un recibo eliminado de dentro de un límite declarado es una brecha demostrable del conjunto mantenido, sin acceso al emisor y sin testigo externo.
Para el ciclo completo en un solo archivo ejecutable, produce un registro firmado, verifícalo tú mismo y luego observa cómo se detecta un solo byte falsificado, consulta examples/prove-it-yourself/. El argumento de registros versus evidencia detrás de esto está en docs/logs-vs-evidence.md.
Cómo se ve la evidencia
vaara compliance report --format json contra un registro real produce un registro de evidencia a nivel de artículo que un auditor lee directamente. Los artículos sin eventos registrados devuelven evidence_insufficient, no un sello de goma.
{
"system_name": "Acme HR Assistant",
"overall_status": "evidence_insufficient",
"trail_integrity": {"size": 105, "chain_intact": true},
"articles": [
{"article": "Article 12(1)", "title": "Record-Keeping (Logging)",
"status": "evidence_sufficient", "strength": "strong", "evidence_count": 105},
{"article": "Article 15(1)", "title": "Accuracy, Robustness and Cybersecurity",
"status": "evidence_insufficient", "strength": "absent", "evidence_count": 0}
]
}
Cada veredicto lleva la instantánea de umbral versus observado, la justificación y los registros subyacentes, por lo que un revisor rastrea status hasta un evento concreto. Los mismos datos se renderizan como un PDF de organismo notificado, un panel HTML estático o un sobre de entrega firmado con Sigstore. Consulta docs/COMPLIANCE.md.
Lo que obtienes
- Controla cada llamada de herramienta que enrutes a través de él contra tu propia política: permitir, bloquear o escalar. La cobertura es lo que envuelvas; cada adaptador documenta la superficie que ve, y el plugin de Claude Code establece sus cuatro explícitamente.
- Un registro a prueba de manipulaciones que una parte externa verifica sin confiar en tu stack, con el encabezado de la cadena anclable a una marca de tiempo externa RFC 3161 / eIDAS para que su existencia sea demostrable contra un reloj que no controlas.
- Evidencia a nivel de artículo de la Ley de IA de la UE, honesta sobre las brechas en lugar de encubrirlas.
- Gobernanza de la llamada al modelo en sí, no solo de las herramientas a su alrededor: un recibo de inferencia con raíz en hardware que un segundo modelo local diferente verifica de forma cruzada. Este es el arnés de inferencia soberana, nuevo en v1.0.
- Aplicación, no solo un registro (v1.1.0): un intermediario de credenciales acuña una credencial firmada de corta duración vinculada al digesto de atestación y limitada a una herramienta, su compromiso de argumento y tenant, con ámbitos de capacidad tipados que limitan lo que una llamada puede hacer. Una puerta de enlace frente a una herramienta protegida rechaza cualquier llamada sin una concesión válida vinculada a la atestación, por lo que una evasión deja de ser silenciosa. Desactivado por defecto.
- Completitud con evidencia de brechas (v1.4.0): cada recibo de autorización puede llevar una secuencia firmada por límite y un conteo continuo, por lo que un recibo eliminado dentro de un límite declarado es una brecha demostrable solo con los recibos mantenidos, sin acceso al emisor y sin testigo externo (
vaara verify-contiguity). Desactivado por defecto. - Re-acuñación independiente (v1.14.0): un segundo generador en cada conjunto de vectores público reproduce el portador firmado byte por byte exacto solo desde la canonicalización declarada, sin importación de Vaara. Un verificador que nunca ha ejecutado software de Vaara reproduce los mismos bytes.
Dónde se conecta
Los adaptadores nativos enrutan los principales frameworks de agentes de Python a través del mismo pipeline, cada uno a través del hook propio del framework, emitiendo eventos de auditoría idénticos:
| Framework | Punto de entrada |
|---|---|
| LangChain | VaaraCallbackHandler, vaara_wrap_tool |
| CrewAI | VaaraCrewGovernance |
| OpenAI Agents SDK | VaaraToolGuardrail, vaara_wrap_function |
| Servidor MCP | vaara.integrations.mcp_server |
Para poner Vaara delante de un servidor MCP, ejecútalo como proxy. Cada tools/call se enruta a través del pipeline antes de llegar al upstream; las llamadas permitidas se reenvían de forma transparente, las llamadas bloqueadas devuelven un error MCP.
vaara-mcp-proxy \
--upstream npx --upstream-arg -y --upstream-arg @sap/mdk-mcp-server \
--db ./mcp_audit.db --shadow
Comienza con --shadow: cada llamada se clasifica, puntúa y registra, nada se bloquea. Después de unos días, vaara trail shadow-report --db ./mcp_audit.db muestra qué habría hecho la aplicación; luego elimina la bandera y aplica, comenzando desde un perímetro listo para servidores MCP comunes en examples/policies/mcp-starters/. Apunta tu cliente MCP (Claude Code, Cursor, cualquier host) al proxy en lugar del upstream. También hay una API HTTP (pip install 'vaara[server]', vaara serve) y un cliente TypeScript de primera parte en npm (@vaara/client) para agentes que no son de Python. Los detalles del framework, los adaptadores de salvaguarda en la nube y OSS (Bedrock, Azure, GCP, NeMo, Guardrails AI, LLM Guard, Rebuff) y el proxy multi-tenant están en docs/adapters.md.
En CI
Una política es código, por lo que pertenece a la solicitud de extracción que la cambia. La acción valida la política, ejecuta sus casos y falla la compilación en una política que no se analiza, un caso que falla o un registro cuya cadena o firma no se sostiene.
- uses: vaaraio/vaara@v1
with:
policy: policies/production.yaml
cases: policies/production.cases.yaml
Apunta trail a un zip firmado para verificar uno que un trabajo produjo. Sin una pubkey que verifica que el registro está internamente intacto; pasa una clave que obtuviste por separado para vincular también al firmante, y la ejecución dice cuál de los dos hizo. Entradas, salidas y fijación están en docs/github-action.md.
Esto verifica artefactos. Controlar al agente es el trabajo del runtime, en el momento de la llamada a la herramienta.
Cómo puntúa
Cada puntuación de riesgo combina cinco señales expertas y se sigue adaptando a medida que llegan los resultados, y lleva un intervalo de confianza con una garantía de cobertura que se mantiene independientemente de la distribución de entrada. En un corpus adversarial reservado, el clasificador alcanza **85.6%** de recall (Wilson 95% [83.4, 87.6]) con una tasa de falsos positivos del **5.1%**, y **0.0%** de FPR en llamadas benignas bajo presión de inyección en vivo. El evaluador de reglas en la ruta crítica añade una media de 140 µs por llamada en CPU comercial; el clasificador ML es opcional (`vaara[ml]`) y está fuera de esa ruta. `make bench` reproduce las cifras del clasificador a continuación contra los paquetes incluidos en el repositorio; requiere `pip install 'vaara[ml]'` y descarga el modelo de embeddings en la primera ejecución.- Corpus adversarial de 25,556 entradas (250 seleccionadas a mano + 25,306 generadas por LLM). La división v0.40 asigna 24,619 de ellas sin fugas por celda (categoría, lote de generación): 15,114 de entrenamiento, 2,921 de validación, 2,980 de prueba, 3,604 de reserva.
- Clasificador v11 (236 características manuales + embeddings MiniLM de 384 dimensiones) con umbral 0.8800 en TEST reservado n=1,827: recall 85.6% [83.4, 87.6] con FPR 5.1% [3.8, 6.9]. El recall sube 0.9 puntos respecto a v9 y la tasa de falsos positivos sube 1.0. Ese intercambio es deliberado y el resto de esta sección explica por qué.
- Recall reservado entre modelos del 86.3% sobre n=5,600, contra ataques escritos por Qwen2.5-72B, un modelo ausente de TRAIN. v9 lee 67.4% en el mismo conjunto. La cifra publicada anteriormente aquí era 66.8% [64.9, 68.7], medida en v8 contra la superficie v0.37; que v9 la reproduzca dentro de un punto en una familia de atacantes diferente y con datos recién generados es la razón por la que ese número sobrevivió dos versiones sin cambios. Este sigue siendo el peor caso honesto, y el número dentro de la distribución anterior es el denominador más fácil.
- En cuatro categorías de ataque que el corpus apenas había cubierto hasta v0.40, medido en 5,600 entradas generadas después de fijar el punto de operación de v11: recall del 63.1% al 87.0% y falsos positivos del 6.6% al 2.5% frente a v9. Solo la exfiltración de credenciales pasa del 45.9% al 80.3% con FPR del 10.0% al 3.9%. Registro completo en bench/V11-CANDIDATE.md, incluido el candidato anterior que fue rechazado y por qué.
- FPR bajo presión BIPIA en llamadas de herramientas benignas: 0.0% [0.0, 1.6] en cuatro backends de agentes (Claude Haiku 4.5, Llama-3.1-8B, Mistral-7B, Qwen-2.5-7B). Baja del 1.2% en v9 y del 35.2% en v8.
- Robustez PAIR multi-atacante: 0/25 éxitos por atacante en Qwen2.5-32B, Qwen2.5-72B, Llama-3.3-70B con semillas idénticas, límite superior de Wilson 13.3%.
- Cobertura conforme libre de distribución en la puntuación; límite de arrepentimiento MWU O(sqrt(T log N)).
- Cadena de custodia: corpus, división, commit de entrenamiento y SHAs de paquetes bloqueados e impresos por cada script.
Método y desglose por celda: docs/architecture.md y bench/.
Estándares y atestación
- vaara.receipt/v1 es la especificación principal canónica para el formato de recibo firmado: encadenado por hash, canonizado con JCS (RFC 8785), verificable sin conexión desde una clave pública. El enlace de liquidación x402 y un perfil de sello de tiempo cualificado eIDAS son perfiles posteriores que se anclan a él en lugar de formatos competidores. Los recibos pueden llevar un sello de tiempo RFC 3161 autoalojado que Vaara emite sin conexión.
- SEP-2828 registros de ejecución firmados, trasladados como el Internet-Draft de la IETF
draft-sirkkavaara-vaara-receipt. Una segunda implementación independiente ha reproducido los vectores de conformidad SEP-2828 desde una copia limpia sin código compartido. Los corpus publicados con verificadores independientes cubren la ruta de enlace de respaldo (tests/vectors/fallback_projection_v0/) y las decisiones de gobernanza de CrewAI (tests/vectors/governance_decision_v0/). - OVERT 1.0 (overt.is): Vaara es el Árbitro y emite Sobres Base del Perfil de Protocolo 1.0 (CBOR canónico, Ed25519) junto con cada registro cuando la atestación está activada.
- Post-cuántico: una firma paralela opcional ML-DSA-65 / FIPS 204 sobre la misma preimagen, de modo que una firma post-cuántica eliminada sea una degradación detectable en lugar de una pérdida silenciosa.
- Evidencia independiente de la raíz: el mismo registro del Artículo 12 es demostrable con o sin TEE de hardware y reexpresable en afirmaciones EAR de IETF RATS (vector AR4SI), ya sea anclado en un host TPM 2.0, una VM confidencial AMD SEV-SNP, o sin TEE en absoluto.
- Arnés de inferencia soberana (v1.0): un modelo local detrás de un proxy de firma que emite un recibo de inferencia anclado en hardware que un segundo modelo local verifica de forma cruzada. Desarrollado de forma privada, publicado aquí bajo AGPL-3.0.
Detalles y los verificadores sin conexión para cada uno: docs/standards.md.
Estabilidad de la superficie
La superficie pública está fijada: el sobre firmado (vaara.receipt/v1), las restricciones de capacidad, la concesión y puerta de enlace de credenciales, y el punto de entrada @vaara.govern. No se planean nuevas primitivas. El nuevo comportamiento se distribuye como perfiles que se anclan a vaara.receipt/v1, no como nuevos tipos centrales, y no se añadirán nuevos enlaces de formato (el último fue v1.13.0). A partir de aquí el trabajo es endurecimiento y sustracción dentro de esta superficie, de modo que cualquiera que construya sobre ella tenga un objetivo estable.
Documentación
| Ruta | Contenido |
|---|---|
| docs/verifying-evidence.md | Cada verificador y su modelo de confianza |
| docs/logs-vs-evidence.md | Registros vs evidencia: probar lo que hizo un agente y lo que realmente exige la Ley de IA |
| docs/prove-what-an-ai-agent-did.md | Las cuatro propiedades que necesita un registro demostrable de acciones de agentes |
| docs/eu-ai-act-article-12.md | Mantenimiento de registros del Artículo 12: qué exige, qué no, qué exigir a las herramientas |
| docs/tamper-evident-audit-trail.md | Cómo funciona el rastro, sus límites honestos y su coste |
| docs/vaara-vs-observability-vs-grc.md | Vaara vs Datadog/Splunk vs Vanta/Drata: tres preguntas diferentes |
| docs/dogfood/ | Nuestro marketing se ejecuta bajo esta puerta; el rastro firmado y la clave para verificarlo |
| docs/architecture.md | Puntuación, cobertura conforme, ancla temporal, propiedades formales |
| SPEC.md | La especificación canónica del formato de recibo vaara.receipt/v1 |
| docs/standards.md | SEP-2828, SEP-2787, OVERT, el arnés de inferencia soberana |
| docs/adapters.md | Adaptadores de frameworks y guardarraíles cloud/OSS, proxy multiinquilino |
| docs/COMPLIANCE.md | Mapeo de artículos de la Ley de IA de la UE y DORA, cifras de evaluación |
| docs/multi-replica-deployment.md | Escalado más allá de un proceso proxy: cadenas por réplica, rotación, índice de archivo |
| docs/kubernetes-rancher.md | Ejecutar el proxy en Kubernetes con Rancher: chart, almacenamiento, aplicación de políticas, aislamiento de red |
| docs/supported-platforms.md | Versiones de Python, contenedor y Kubernetes que Vaara soporta y cuáles se han verificado |
| CHANGELOG.md | Evolución versión a versión |
| docs/PRIOR_ART.md | Cuándo se lanzó cada concepto por primera vez, más trabajo adyacente |
Vaara ayuda a los implementadores a reunir evidencia para su propio trabajo de conformidad. No certifica cumplimiento ni constituye asesoramiento legal. Los implementadores son responsables de sus obligaciones bajo la Ley de IA de la UE y otras leyes aplicables.
Licencia comercial y pilotos de pago disponibles: ver vaara.io o contactar con hello@vaara.io. Los términos de licencia están en LICENSING.md, y la licencia comercial se describe en COMMERCIAL.md.
Agradecimientos
- Incluido en los agradecimientos de la industria del Marco Modelo de Gobernanza de IA del IMDA para IA Agéntica v1.5 (Singapur, 20 de mayo de 2026).
- El Programa de Desarrolladores de IA de AMD realizó un testimonio de desarrollador de Vaara en mayo de 2026.
- Artículo 14 en tiempo de ejecución: por qué la supervisión de la IA agéntica debe evidenciarse como acción, no como modelo, la publicación de posición en el Foro de la Alianza de IA Aplicada de la UE.
- Artículo 12 y la diferencia entre un registro y una evidencia, la publicación de posición complementaria en el Foro de la Alianza de IA Aplicada de la UE.
- Prueba soberana para la Ley de IA, la publicación de posición más reciente en el Foro de la Alianza de IA Aplicada de la UE.
Cita
Si construyes sobre Vaara o su formato de recibo, cita el repositorio (ver CITATION.cff) y la especificación que implementa:
Henri Sirkkavaara. The Vaara Receipt: A Recomputable Receipt Format for Decisions About Agent Actions. IETF Internet-Draft draft-sirkkavaara-vaara-receipt.
Cada versión etiquetada está archivada por Zenodo y recibe un DOI. Cita 10.5281/zenodo.22027975 para el software en su conjunto, que siempre resuelve a la versión más reciente, o el DOI de versión impreso en una versión específica para los bytes exactos que ejecutaste.
Licencia
Copyright © 2026 Henri Sirkkavaara. Licenciado bajo AGPL-3.0-or-later. Ver LICENSE.
