
Un runtime* seguro para agentes de IA autónomos. Política a partir de constituciones en inglés sencillo. (*https://ironcurtain.dev)
Un runtime seguro* para agentes de IA autónomos, donde la política de seguridad se deriva de una constitución legible por humanos.
*Cuando alguien escribe "seguro", deberías ser escéptico de inmediato. ¿Qué queremos decir con seguro?
[!WARNING] Prototipo de investigación. IronCurtain es un proyecto de investigación en etapa temprana que explora cómo hacer que los agentes de IA sean lo suficientemente seguros como para ser genuinamente útiles. Las APIs, los formatos de configuración y la arquitectura pueden cambiar. Las contribuciones y comentarios son bienvenidos.
Se le pide al agente que clone un repositorio y realice cambios. Tanto git_clone como git_push son escalados por el motor de políticas, pero el aprobador automático los aprueba automáticamente — la entrada confiable del usuario desde el modo de comando (Ctrl-A) proporcionó una intención clara, por lo que no fue necesaria una /approve manual.
Los agentes de IA autónomos pueden gestionar archivos, ejecutar comandos git, enviar mensajes e interactuar con APIs en tu nombre. Pero los frameworks actuales de agentes otorgan al agente los mismos privilegios que al usuario, como acceso completo al sistema de archivos, credenciales y red. Los investigadores de seguridad llaman a esto autoridad ambiental, y significa que una sola inyección de prompt o una deriva en múltiples turnos puede hacer que un agente elimine archivos, exfiltre datos o envíe código malicioso.
La respuesta común es restringir a los agentes a un sandbox estrecho (limitando su utilidad) o pedir al usuario que apruebe cada acción (limitando su autonomía). Ninguna de las dos es satisfactoria.
IronCurtain toma un camino diferente: expresa tu intención de seguridad en inglés sencillo, luego deja que el sistema determine la aplicación.
Escribes una constitución, que es un documento breve que describe lo que tu agente puede y no puede hacer. IronCurtain compila esto en una política de seguridad determinista utilizando un pipeline de LLM, valida las reglas compiladas frente a escenarios de prueba generados, y luego aplica la política en tiempo de ejecución en cada llamada a herramienta. El resultado es un agente que puede trabajar de forma autónoma dentro de los límites que defines en lenguaje natural.
Las ideas clave:
IronCurtain admite dos modos de sesión con diferentes modelos de confianza:
Agente Integrado (Modo Código) — El propio agente LLM de IronCurtain escribe fragmentos TypeScript que se ejecutan en un sandbox V8. IronCurtain controla el agente, el sandbox y el motor de políticas. Cada llamada a herramienta sale del sandbox como una solicitud MCP estructurada, pasa por el motor de políticas (permitir / denegar / escalar), y solo entonces llega al servidor MCP real.
Modo Agente Docker — Un agente externo (Claude Code, Goose, etc.) se ejecuta dentro de un contenedor Docker sin acceso a la red. IronCurtain media los efectos externos: las llamadas a la API LLM pasan a través de un proxy MITM que termina TLS (lista blanca de hosts, intercambio de clave falsa por real), las llamadas a herramientas MCP pasan por el mismo motor de políticas, y las instalaciones de paquetes (npm/PyPI) pasan por un proxy de registro validador.
En ambos modos, el agente no es confiable. La seguridad no depende de que el modelo siga instrucciones — se aplica en el límite.
Consulta SANDBOXING.md para la arquitectura completa con diagramas, análisis de confianza capa por capa y notas sobre la plataforma macOS.
isolated-vm; 24 y 26 instalan binarios precompilados, Node 22 compila desde la fuente en la instalación y necesita un conjunto de herramientas C/C++). Las líneas impares (23, 25) se ejecutan pero no están probadas — ironcurtain doctor advierte.container funciona como backend alternativo (VM por contenedor; se usa automáticamente cuando sus servicios están en ejecución — consulta containerRuntime en ironcurtain config)Como herramienta CLI global (usuarios finales):```bash npm install -g @provos/ironcurtain
**Desde el código fuente (desarrollo):**```bash
git clone https://github.com/provos/ironcurtain.git
cd ironcurtain
npm install
1. Establece tu clave API:```bash export ANTHROPIC_API_KEY=sk-ant-...
También puedes colocar las claves en un archivo `.env` en la raíz del proyecto (cargado automáticamente a través de `dotenv`), o agregarlas a `~/.ironcurtain/config.json` mediante `ironcurtain config`. Las variables de entorno tienen prioridad sobre los valores del archivo de configuración. Soportadas: `ANTHROPIC_API_KEY`, `GOOGLE_GENERATIVE_AI_API_KEY`, `OPENAI_API_KEY`.
**2. Ejecuta el asistente de primera ejecución** (ejecuta esto explícitamente antes de usar la ruta mux recomendada; también se ejecuta automáticamente en el primer `ironcurtain start` que no sea mux):```bash
ironcurtain setup
Te guía a través de la configuración del token de GitHub, el proveedor de búsqueda web, la selección del modelo y otras opciones. Crea ~/.ironcurtain/config.json con tus elecciones.
IronCurtain viene con una política predeterminada orientada a la experiencia del desarrollador: las operaciones de solo lectura están permitidas, las mutaciones (escrituras, envíos, creación de PR) escalan para aprobación humana. Puedes comenzar a usarlo inmediatamente después de la configuración.
La forma recomendada de usar IronCurtain. Te brinda todo el poder de la TUI interactiva de tu agente (Claude Code o Goose) mientras IronCurtain media cada llamada de herramienta a través de su motor de políticas, todo en una sola terminal.```bash ironcurtain mux
**Capacidades clave:**
- **TUI completa del agente** — El agente se ejecuta en una PTY dentro de un contenedor Docker sin acceso a la red. Interactúas con él exactamente como si se ejecutara localmente.
- **Manejo de escalación en línea** — Cuando una llamada de herramienta necesita aprobación, un selector de escalación se superpone en el viewport con acciones de una sola tecla (a/d/w para aprobar/denegar/lista blanca). Usa `/approve+ N` para agregar a la lista blanca un dominio o ruta por el resto de la sesión.
- **Entrada de usuario confiable** — El texto escrito en modo comando (Ctrl-A) se captura en el lado del host antes de ingresar al contenedor. Esto crea una señal de intención verificada que el auto-aprobador puede usar — p. ej., escribir "push my changes to origin" aprobará automáticamente una escalación `git_push` posterior.
- **Gestión de pestañas** — Genera múltiples sesiones concurrentes (`/new`), cambia entre ellas (`/tab N`, Alt-1..9), ciérralas (`/close`). Varias instancias de mux pueden ejecutarse en paralelo.
Consulta [DEVELOPER_GUIDE.md](https://github.com/provos/ironcurtain/blob/master/DEVELOPER_GUIDE.md) para la guía completa: modos de entrada, modelo de seguridad de entrada confiable, flujo de trabajo de escalación y referencia del teclado.
### Sesiones no-mux
Usa `ironcurtain start` para tareas rápidas de un solo uso, scripts, o cuando quieras explícitamente el agente integrado local. Para trabajo interactivo normal con Docker-agent, usa `ironcurtain mux`.```bash
ironcurtain start "Summarize the files in ./src" # Single-shot mode
ironcurtain start -w ./my-project "Fix the tests" # Single-shot workspace mode
ironcurtain start --agent builtin # Local builtin REPL, no Docker
ironcurtain start --persona my-assistant "Check my email" # Use a persona
IronCurtain también admite reanudación de sesión (--resume <session-id>), un modo PTY/depuración heredado, un transporte de mensajería Signal para aprobación móvil y un modo daemon para trabajos cron programados. El daemon tiene una interfaz web opcional (--web-ui) para monitoreo basado en navegador y manejo de escalaciones. Consulte RUNNING_MODES.md para más detalles.
IronCurtain orquesta múltiples agentes de IA a través de flujos de trabajo estructurados. El flujo de trabajo descubrimiento de vulnerabilidades integrado busca errores de seguridad de memoria y lógica en código nativo a través de un pipeline de harnesses escalonado (Nivel 1 función aislada → Nivel 2 multicomponente → Nivel 3 compilación completa) con control de cobertura de libFuzzer/AFL++, estados discover/triage impulsados por hipótesis, y una compuerta final de revisión de informe humano. El flujo de trabajo diseño y código ejecuta ciclos de planificación / diseño / implementación / revisión, también con compuertas humanas. Cada agente se ejecuta en su propio contenedor Docker con límites de política específicos del rol; el motor gestiona las transiciones de estado, el paso de artefactos y los puntos de control de reanudación ante fallos automáticamente. Es de código abierto, se ejecuta completamente en su máquina, aplica políticas de seguridad por agente mediante el motor de políticas basado en constitución, y funciona con cualquier agente contenerizado con Docker — comparable en alcance a Amazon Kiro y Google Jules para tareas de codificación, pero con seguridad de primera clase y un formato de definición de flujo de trabajo extensible.

La interfaz web es la interfaz prevista para las ejecuciones de flujo de trabajo. Inicie el daemon, abra la URL impresa y ejecute desde la página Workflows — el gráfico de la máquina de estados de arriba está en vivo, la línea de tiempo de mensajes de agente se transmite con representación Markdown, las revisiones de compuerta incluyen un navegador de espacio de trabajo y artefactos, y las ejecuciones pasadas permanecen listadas.```bash ironcurtain daemon --web-ui
El acceso CLI está disponible para scripting, automatización y depuración:```bash
ironcurtain workflow start vuln-discovery \
"Find memory-safety bugs in libical" --workspace ~/src/libical
ironcurtain workflow start design-and-code \
"Build a REST API with authentication"
Consulta WORKFLOWS.md para la documentación completa.
La política predeterminada funciona bien para el desarrollo general, pero puedes adaptarla a tu flujo de trabajo:
1. Personaliza tu constitución (opcional pero recomendado):```bash ironcurtain customize-policy
Una conversación asistida por LLM que genera una constitución adaptada a tu flujo de trabajo, guardada en `~/.ironcurtain/constitution-user.md`. También puedes editar este archivo directamente.
**2. Compilar la política:**```bash
ironcurtain compile-policy
Traduce tu constitución en reglas deterministas, genera escenarios de prueba y los verifica. Los artefactos compilados se guardan en ~/.ironcurtain/generated/.
Las personas son perfiles de política con nombre — cada una agrupa una constitución, política compilada, espacio de trabajo persistente y memoria semántica. Úsalas para ejecutar agentes con diferentes roles o niveles de acceso.```bash ironcurtain persona create my-assistant # Create a persona ironcurtain persona compile my-assistant # Compile its policy ironcurtain start --persona my-assistant "Check my calendar"
En modo mux, `/new my-assistant` abre una pestaña usando esa persona. Las personas también pueden asignarse a trabajos cron. Consulta [DAEMON.md](https://github.com/provos/ironcurtain/blob/master/DAEMON.md) para la configuración de trabajos programados.
Las personas también pueden gestionarse desde la [interfaz web](https://github.com/provos/ironcurtain/blob/master/DAEMON.md#persona-policy-management) — navegar, crear, editar constituciones y compilar políticas con progreso en vivo. Debido a que una política es un límite de seguridad, los controles de mutación de la interfaz web son de solo lectura a menos que el daemon se inicie con `--allow-policy-mutation` (desactivado por defecto).
### Habilidades
Coloca paquetes SKILL.md en `~/.ironcurtain/skills/<name>/` para que las guías de propósito específico (scripts auxiliares, verificaciones deterministas, conocimiento del dominio) estén disponibles para cada sesión del agente Docker. El conjunto fusionado se prepara en un directorio del host por paquete y se monta en modo **solo lectura** dentro del contenedor en la ruta que el descubrimiento nativo del agente activo recorre — Claude Code apunta al directorio de preparación mediante `--add-dir`, Goose escanea `~/.config/goose/skills/<name>/SKILL.md`. El agente los descubre automáticamente y decide cuándo leerlos según la descripción en el frontmatter de cada skill. El _formato_ SKILL.md es el estándar abierto adoptado por Claude Code, Goose y Codex; solo la _ruta de descubrimiento_ difiere por agente. Los flujos de trabajo pueden incluir skills por estado dentro del paquete del flujo de trabajo — consulta [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md#skills).
## Política: Constitución → Aplicación
Escribes la intención en inglés simple; IronCurtain la compila en reglas deterministas:```
constitution.md → [Annotate] → [Compile] → [Resolve Lists] → [Generate Scenarios] → [Verify & Repair]
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
tool-annotations compiled-policy dynamic-lists test-scenarios verified policy
.json .json .json .json (or build failure)
@list-name.dynamic-lists.json, editable por el usuario. Se omite cuando no hay listas presentes.Todos los artefactos se almacenan en caché mediante hash de contenido — solo las entradas modificadas desencadenan una recompilación.
Una cláusula de constitución como:```markdown
compila a:```json
[
{ "tool": "git_status", "decision": "allow", "condition": { "directory": { "within": "$SANDBOX" } } },
{ "tool": "git_diff", "decision": "allow", "condition": { "directory": { "within": "$SANDBOX" } } },
{ "tool": "git_push", "decision": "escalate", "reason": "Remote-contacting git operations require human approval" }
]
Cualquier llamada que no coincida con una regla explícita de allow o escalate es denegada por defecto.```bash
ironcurtain annotate-tools --server filesystem # Annotate one server (merge with existing)
ironcurtain annotate-tools --all # Re-annotate all servers
ironcurtain compile-policy # Compile constitution into rules and verify
ironcurtain refresh-lists # Re-resolve dynamic lists without full recompilation
ironcurtain refresh-lists --list major-news # Refresh a single list
Revisa el archivo generado `~/.ironcurtain/generated/compiled-policy.json` — estas son las reglas exactas que se aplican en tiempo de ejecución.
## Configuración
IronCurtain almacena la configuración y los datos de sesión en `~/.ironcurtain/`:```
~/.ironcurtain/
├── config.json # User configuration
├── constitution.md # User-local base constitution (overrides package default)
├── constitution-user.md # Your policy customizations (generated by customize-policy)
├── generated/ # User-compiled policy artifacts (overrides package defaults)
├── personas/ # Persona directories (constitution, policy, workspace, memory)
├── skills/ # User-global SKILL.md packages, mounted into every Docker session
├── jobs/ # Cron job definitions, workspaces, and run records
├── sessions/
│ └── {sessionId}/
│ ├── sandbox/ # Per-session filesystem sandbox
│ ├── escalations/ # File-based IPC for human approval
│ ├── audit.jsonl # Per-session audit log
│ └── session.log # Diagnostics
└── workflow-runs/ # Shared-container workflow runs (see below)
Las ejecuciones de una sola sesión (ironcurtain start, pestañas de mux, trabajos cron) se escriben en sessions/. Las ejecuciones de flujo de trabajo en contenedor compartido se escriben en workflow-runs/ por el contrario — consulte la siguiente sección.
Una definición de flujo de trabajo puede optar por un contenedor Docker compartido estableciendo settings.sharedContainer: true en su YAML. En ese modo, cada estado del agente se ejecuta dentro del mismo contenedor de larga duración y comparte una instancia del motor de políticas; entre estados, el orquestador intercambia en caliente la política activa para que cada persona vea sus propias reglas. Todos los artefactos de la ejecución se almacenan en un solo árbol:```
~/.ironcurtain/workflow-runs//
├── audit.jsonl # Persona-tagged append-only audit
├── messages.jsonl # Orchestrator message log
├── workspace/ # Agent workspace (filesystem MCP root)
├── bundle/ # Shared container support (claude-state, orientation, sockets, escalations, system-prompt.txt)
├── states/
│ └── ./ # session.log + session-metadata.json per invocation
└── proxy-control.sock # Coordinator UDS for policy hot-swap
No se crean entradas por sesión en `~/.ironcurtain/sessions/` para una ejecución de flujo de trabajo con contenedor compartido. Los comandos visibles para el usuario (`ironcurtain workflow start|resume|inspect|list`) no cambian. Consulte [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md) para crear definiciones de flujos de trabajo y el ciclo de vida completo.
Editar configuración interactivamente:```bash
ironcurtain config
Áreas clave de configuración: modelos y claves API, presupuestos de recursos (límites de tokens/pasos/tiempo/costo), escalaciones de aprobación automática, proveedor de búsqueda web, redacción de auditoría y configuración del LLM del servidor de memoria. Consulte CONFIG.md para obtener la referencia completa.
Para enrutar el tráfico LLM a través de una puerta de enlace como LiteLLM u OpenRouter (tanto en Modo Código como en Modo Agente Docker), consulte MODEL_ROUTING.md.
Enrute los agentes Docker a través de perfiles de proveedor de modelos (p. ej., GLM-5.2 a través de OpenRouter, sin sidecar) con ironcurtain config → Proveedores de modelos, luego elija un perfil en /new o con --provider-profile — consulte MODEL_ROUTING.md.
IronCurtain incluye seis servidores MCP preconfigurados. Todas las llamadas a herramientas (excepto la memoria) se rigen por su política compilada.
Las operaciones de solo lectura están permitidas por la política predeterminada; las mutaciones (escrituras, envíos, creación de PR) escalan para aprobación humana. Las herramientas usan nomenclatura server.tool (p. ej., filesystem.read_file, memory.recall). Consulte ADDING_MCP_SERVERS.md para agregar las suyas propias.
En el Modo Agente Docker, el contenedor no tiene acceso a la red — todo el tráfico pasa a través del proxy MITM de IronCurtain. De manera predeterminada, solo los dominios del proveedor LLM son accesibles. El agente puede solicitar acceso a dominios adicionales en tiempo de ejecución a través del servidor MCP virtual proxy (add_proxy_domain). Cada solicitud requiere aprobación humana mediante el flujo de escalada.
Los dominios aprobados obtienen un túnel de paso directo sin procesar — las conexiones HTTP, HTTPS y WebSocket se reenvían sin inspección de contenido ni inyección de credenciales. Esto le da al agente una mayor utilidad (llamar a APIs de terceros, transmitir datos de servicios externos) pero significa que el tráfico hacia esos dominios es sin mediación. Consulte SECURITY_CONCERNS.md Sección 2b-i para el modelo de amenazas y DEVELOPER_GUIDE.md para detalles de uso.
IronCurtain está diseñado en torno a un modelo de amenazas específico: el LLM se vuelve rebelde. Esto puede ocurrir mediante inyección de indicaciones (un correo electrónico o página web maliciosa secuestra al agente) o mediante desviación de múltiples turnos (el agente se desvía gradualmente de la intención del usuario durante una sesión larga).
Este es un prototipo de investigación. Las brechas conocidas incluyen:
compiled-policy.json compilado.Consulte docs/SECURITY_CONCERNS.md para un análisis detallado de amenazas.
npm test # Run all tests npm test -- test/policy-engine.test.ts # Run a single test file npm test -- -t "denies delete_file" # Run a single test by name npm run lint # Lint npm run build # TypeScript compilation + asset copy
Consulte [TESTING.md](https://github.com/provos/ironcurtain/blob/master/TESTING.md) para la guía completa de pruebas, incluyendo las banderas de pruebas de integración y las convenciones.
### Estructura del Proyecto```
src/
├── index.ts # Entry point
├── cli.ts # CLI command dispatcher
├── config/ # Configuration loading, constitution, MCP server definitions
├── session/ # Multi-turn session management, budgets, loop detection
├── sandbox/ # V8 isolated execution environment
├── trusted-process/ # Policy engine, MCP proxy, audit log, escalation handler
├── pipeline/ # Constitution → policy compilation pipeline
├── escalation/ # Escalation listener: session registry, TUI dashboard, state
├── mux/ # Terminal multiplexer: PTY bridge, renderer, trusted input
├── persona/ # Persona management (create, compile, resolve)
├── memory/ # Memory server integration (config, annotations, path resolution)
├── signal/ # Signal messaging transport (bot daemon, setup, formatting)
├── daemon/ # Unified daemon (Signal + cron scheduler, control socket)
├── cron/ # Cron job management (scheduler, job store, git sync, policy)
├── docker/ # Docker agent mode, PTY session, MITM proxy, registry proxy
├── workflow/ # Multi-agent workflow engine (orchestrator, state machine, gates)
├── web-ui/ # Web UI backend (JSON-RPC dispatch, event bus, workflow manager)
├── servers/ # Built-in MCP servers (fetch, web search providers)
└── types/ # Shared type definitions
packages/
└── memory-mcp-server/ # Standalone memory MCP server (publishable npm package)
| Servidor | Herramientas | Capacidades clave |
|---|
| Filesystem | 14 | Leer, escribir, editar, buscar archivos; árbol de directorios; mover; cálculo de diferencias |
| Git | 28 | Flujo de trabajo git completo: status, diff, log, commit, branch, push/pull/fetch, clone, stash, blame |
| Fetch | 2 | GET HTTP con conversión de HTML a Markdown; búsqueda web (Brave, Tavily, SerpAPI) |
| GitHub | 41 | Incidencias, PRs, búsqueda de código, revisiones a través de ghcr.io/github/github-mcp-server; requiere un token de acceso personal de GitHub |
| Google Workspace | 128 | Gmail, Calendar, Drive, Docs, Sheets — requiere configuración OAuth a través de ironcurtain auth |
| Memory | 5 | Memoria semántica persistente con búsqueda híbrida vectorial + por palabras clave, resumen LLM y compactación automática. Habilitada para sesiones de persona y cron. |
| Problema | Orientación |
|---|
| Falta clave API | Establezca la variable de entorno (ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY o OPENAI_API_KEY) o agregue la clave correspondiente a ~/.ironcurtain/config.json. |
| Sandbox no disponible | El sandboxing a nivel de SO requiere bubblewrap y socat. Instale ambos, o establezca "sandboxPolicy": "warn" en la configuración de su servidor MCP para desarrollo. |
| Presupuesto agotado | Ajuste los límites en ~/.ironcurtain/config.json bajo resourceBudget. Establezca cualquier límite individual a null para deshabilitarlo. |
| Errores de versión de Node | Las líneas de Node.js compatibles son 22, 24 y 26 — las líneas principales pares que IronCurtain prueba (isolated-vm). 24 y 26 instalan binarios precompilados; Node 22 compila isolated-vm desde el fuente y necesita un toolchain C/C++. Las líneas impares (23, 25) no se prueban — ironcurtain doctor las marca con una advertencia en lugar de un fallo grave. |
| La política no coincide con la intención | Revise compiled-policy.json para ver las reglas generadas. Ejecute ironcurtain customize-policy para refinar su constitución, luego ironcurtain compile-policy para recompilar. Un redacción específica produce mejores reglas — un fraseo vago conduce a una política vaga. |
| La aprobación automática no se activa | El aprobador automático solo aprueba cuando el mensaje del usuario autoriza explícitamente la acción (p. ej., "push to origin" para git_push). Los mensajes vagos siempre escalan a revisión humana. Verifique que autoApprove.enabled esté en true en config.json. |
| Terminal PTY/mux distorsionada después de salir | Ejecute reset en esa terminal para restaurar el modo normal. Esto es necesario cuando el proceso se mata de manera no elegante y el modo raw no se restaura. |
| Mux/listener: "ya en ejecución" | Solo un mux o escalation-listener puede ejecutarse a la vez. El bloqueo en ~/.ironcurtain/escalation-listener.lock se limpia automáticamente si el proceso anterior está muerto. Si persiste, verifique el PID en el archivo de bloqueo. |
| Bot de Signal no responde | Verifique que el contenedor signal-cli esté ejecutándose (`docker ps |