
Un runtime sicuro* per agenti AI autonomi. Policy da costituzioni in inglese semplice. (*https://ironcurtain.dev)
Un runtime sicuro* per agenti AI autonomi, in cui la policy di sicurezza è derivata da una costituzione leggibile dall'uomo.
*Quando qualcuno scrive "sicuro", dovresti subito essere scettico. Cosa intendiamo per sicuro?
[!WARNING] Prototipo di ricerca. IronCurtain è un progetto di ricerca in fase iniziale che esplora come rendere gli agenti AI sufficientemente sicuri da essere realmente utili. API, formati di configurazione e architettura possono cambiare. Contributi e feedback sono benvenuti.
All'agente viene chiesto di clonare un repository e di eseguire il push delle modifiche. Sia git_clone che git_push vengono sottoposti a escalation dal motore delle policy, ma l'auto-approvatore li approva automaticamente — l'input attendibile dell'utente dalla modalità comando (Ctrl-A) ha fornito un'intenzione chiara, quindi non è stato necessario alcun /approve manuale.
Gli agenti AI autonomi possono gestire file, eseguire comandi git, inviare messaggi e interagire con le API per tuo conto. Ma i framework per agenti di oggi concedono all'agente gli stessi privilegi dell'utente, come l'accesso completo al filesystem, alle credenziali e alla rete. I ricercatori di sicurezza chiamano questo ambient authority, e significa che una singola prompt injection o una deriva multi-turno può portare un agente a cancellare file, esfiltrare dati o pushare codice dannoso.
La risposta comune è limitare gli agenti a un sandbox ristretto (riducendone l'utilità) oppure chiedere all'utente di approvare ogni azione (limitandone l'autonomia). Nessuna delle due è soddisfacente.
IronCurtain prende una strada diversa: esprimi la tua intenzione di sicurezza in inglese semplice, lascia poi che sia il sistema a occuparsi dell'applicazione.
Scrivi una costituzione, un breve documento che descrive cosa l'agente può e non può fare. IronCurtain la compila in una policy di sicurezza deterministica usando una pipeline LLM, valida le regole compilate su scenari di test generati e poi applica la policy a runtime su ogni chiamata di strumento. Il risultato è un agente che può lavorare in autonomia entro i confini che definisci in linguaggio naturale.
Le idee chiave:
IronCurtain supporta due modalità di sessione con modelli di fiducia diversi:
Agente integrato (Code Mode) — L'agente LLM di IronCurtain scrive snippet TypeScript che vengono eseguiti in una sandbox V8. IronCurtain controlla l'agente, la sandbox e il motore delle policy. Ogni chiamata di strumento esce dalla sandbox come richiesta MCP strutturata, passa attraverso il motore delle policy (allow / deny / escalate), e solo allora raggiunge il vero server MCP.
Docker Agent Mode — Un agente esterno (Claude Code, Goose, ecc.) viene eseguito all'interno di un container Docker senza accesso alla rete. IronCurtain media gli effetti esterni: le chiamate API LLM passano attraverso un proxy MITM che termina TLS (allowlist degli host, scambio di chiavi da fake a reale), le chiamate di strumenti MCP passano attraverso lo stesso motore delle policy e le installazioni di pacchetti (npm/PyPI) passano attraverso un proxy di registro validante.
In entrambe le modalità, l'agente è non attendibile. La sicurezza non dipende dal fatto che il modello segua le istruzioni: viene applicata al confine.
Consulta SANDBOXING.md per l'architettura completa con diagrammi, analisi della fiducia livello per livello e note sulla piattaforma macOS.
isolated-vm; 24 e 26 installano binari precompilati, Node 22 compila dal sorgente durante l'installazione e richiede una toolchain C/C++). Le versioni dispari (23, 25) funzionano ma non sono testate — ironcurtain doctor emette un avviso.container funziona come backend alternativo (una VM per container; usato automaticamente quando i suoi servizi sono in esecuzione — vedi containerRuntime in ironcurtain config)Come strumento CLI globale (utenti finali):```bash npm install -g @provos/ironcurtain
**Dalla sorgente (sviluppo):**```bash
git clone https://github.com/provos/ironcurtain.git
cd ironcurtain
npm install
1. Imposta la tua chiave API:```bash export ANTHROPIC_API_KEY=sk-ant-...
Puoi anche inserire le chiavi in un file `.env` nella directory principale del progetto (caricato automaticamente tramite `dotenv`), oppure aggiungerle a `~/.ironcurtain/config.json` tramite `ironcurtain config`. Le variabili d'ambiente hanno precedenza sui valori del file di configurazione. Supportate: `ANTHROPIC_API_KEY`, `GOOGLE_GENERATIVE_AI_API_KEY`, `OPENAI_API_KEY`.
**2. Esegui la procedura guidata di primo avvio** (eseguila esplicitamente prima di utilizzare il percorso mux consigliato; viene eseguita anche automaticamente al primo `ironcurtain start` senza mux):```bash
ironcurtain setup
Ti guida attraverso la configurazione del token GitHub, il provider di ricerca web, la selezione del modello e altre impostazioni. Crea ~/.ironcurtain/config.json con le tue scelte.
IronCurtain viene fornito con una policy predefinita orientata all'esperienza dello sviluppatore: le operazioni di sola lettura sono consentite, mentre le mutazioni (scritture, push, creazione di PR) passano per l'approvazione umana. Puoi iniziare a usarlo subito dopo la configurazione.
Il modo consigliato per usare IronCurtain. Offre tutta la potenza della TUI interattiva del tuo agente (Claude Code o Goose) mentre IronCurtain intermedia ogni chiamata di tool attraverso il suo motore di policy, il tutto in un unico terminale.```bash ironcurtain mux
**Capacità principali:**
- **TUI completa per l'agente** — L'agente esegue in un PTY all'interno di un container Docker senza accesso alla rete. Interagisci con esso esattamente come se fosse eseguito localmente.
- **Gestione inline delle escalation** — Quando una chiamata a uno strumento richiede approvazione, un selettore di escalation sovrappone l'area di visualizzazione con azioni a tasto singolo (a/d/w per approvare/negare/whitelistare). Usa `/approve+ N` per whitelistare un dominio o un percorso per il resto della sessione.
- **Input utente attendibile** — Il testo digitato in modalità comando (Ctrl-A) viene catturato sul lato host prima di entrare nel container. Questo crea un segnale di intento verificato che l'auto-approver può usare — ad esempio, digitare "push my changes to origin" approverà automaticamente un'escalation `git_push` successiva.
- **Gestione delle schede** — Avvia più sessioni simultanee (`/new`), passa da una all'altra (`/tab N`, Alt-1..9), chiudile (`/close`). Più istanze mux possono essere eseguite in parallelo.
Vedi [DEVELOPER_GUIDE.md](https://github.com/provos/ironcurtain/blob/master/DEVELOPER_GUIDE.md) per la guida completa: modalità di input, modello di sicurezza dell'input attendibile, flusso di escalation e riferimento alla tastiera.
### Sessioni non-mux
Usa `ironcurtain start` per attività rapide one-shot, script o quando vuoi esplicitamente l'agente builtin locale. Per il normale lavoro interattivo con agenti Docker, 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 supporta anche la ripresa delle sessioni (--resume <session-id>), una modalità legacy raw PTY/debug, un trasporto di messaggistica Signal per l'approvazione mobile e una modalità daemon per i job cron pianificati. Il daemon dispone di un'interfaccia web opzionale (--web-ui) per il monitoraggio tramite browser e la gestione delle escalation. Vedi RUNNING_MODES.md per i dettagli.
IronCurtain orchestra più agenti AI attraverso workflow strutturati. Il workflow integrato di scoperta delle vulnerabilità caccia bug di memory-safety e logica nel codice nativo tramite una pipeline di harness a livelli (Tier 1 funzione isolata → Tier 2 multi-componente → Tier 3 build completa) con gating di copertura libFuzzer/AFL++, stati discover/triage guidati da ipotesi e un gate finale di revisione del report umano. Il workflow design-and-code esegue cicli plan / design / implement / review, anch'essi con gate umani. Ogni agente viene eseguito nel proprio container Docker con confini di policy specifici per ruolo; il motore gestisce automaticamente le transizioni di stato, il passaggio di artefatti e il checkpointing per il ripristino dopo crash. Open source, viene eseguito interamente sulla tua macchina, applica policy di sicurezza per agente tramite il motore di policy basato su costituzione e funziona con qualsiasi agente containerizzato Docker — paragonabile per portata ad Amazon Kiro e Google Jules per attività di codifica, ma con sicurezza di prima classe e un formato di definizione dei workflow estensibile.

L'interfaccia web è l'interfaccia prevista per l'esecuzione dei workflow. Avvia il daemon, apri l'URL stampato e gestisci le esecuzioni dalla pagina Workflows: il grafico della macchina a stati sopra è in tempo reale, la timeline dei messaggi dell'agente scorre con rendering markdown, le revisioni dei gate includono un browser di workspace e artefatti e le esecuzioni passate rimangono elencate.```bash ironcurtain daemon --web-ui
L'accesso CLI è disponibile per lo scripting, l'automazione e il debug:```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"
Vedi WORKFLOWS.md per la documentazione completa.
La policy predefinita funziona bene per lo sviluppo generale, ma puoi adattarla al tuo flusso di lavoro:
1. Personalizza la tua costituzione (facoltativo ma consigliato):```bash ironcurtain customize-policy
Una conversazione assistita da LLM che genera una costituzione su misura per il tuo flusso di lavoro, salvata in `~/.ironcurtain/constitution-user.md`. Puoi anche modificare questo file direttamente.
**2. Compila la policy:**```bash
ironcurtain compile-policy
Traduce la tua costituzione in regole deterministiche, genera scenari di test e li verifica. Gli artefatti compilati finiscono in ~/.ironcurtain/generated/.
Le personas sono profili di policy denominati — ciascuna raggruppa una costituzione, una policy compilata, uno spazio di lavoro persistente e una memoria semantica. Usale per eseguire agent con ruoli o livelli di accesso differenti.```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"
In mux mode, `/new my-assistant` apre una scheda usando quella persona. Le persona possono anche essere assegnate ai cron job. Vedi [DAEMON.md](https://github.com/provos/ironcurtain/blob/master/DAEMON.md) per la configurazione dei job pianificati.
Le persona possono anche essere gestite dall'[interfaccia web](https://github.com/provos/ironcurtain/blob/master/DAEMON.md#persona-policy-management) — sfoglia, crea, modifica costituzioni e compila policy con avanzamento in tempo reale. Poiché una policy è un perimetro di sicurezza, i controlli di modifica dell'interfaccia web sono in sola lettura a meno che il daemon non venga avviato con `--allow-policy-mutation` (disattivato per impostazione predefinita).
### Competenze
Inserisci i pacchetti SKILL.md in `~/.ironcurtain/skills/<name>/` per rendere disponibile a ogni sessione di agenti Docker una guida specifica per lo scopo (script di supporto, controlli deterministici, conoscenza di dominio). Il set unificato viene preparato in una directory host per bundle e montato tramite bind mount in **sola lettura** nel container nel percorso esplorato dalla discovery nativa dell'agente attivo — Claude Code viene puntato alla directory di staging tramite `--add-dir`, Goose esegue la scansione di `~/.config/goose/skills/<name>/SKILL.md`. L'agente li scopre automaticamente e decide quando leggerli in base alla descrizione frontmatter di ciascuna skill. Il _formato_ SKILL.md è lo standard aperto adottato da Claude Code, Goose e Codex; solo il _percorso di discovery_ cambia da un agente all'altro. I workflow possono includere skill per stato all'interno del pacchetto workflow — vedi [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md#skills).
## Policy: Costituzione → Attuazione
Scrivi l'intento in inglese semplice; IronCurtain lo compila in regole deterministiche:```
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, modificabile dall'utente. Saltato quando non sono presenti liste.Tutti gli artefatti sono memorizzati nella cache con hash del contenuto — solo gli input modificati attivano la ricompilazione.
Una clausola della costituzione come:```markdown
compila in:```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" }
]
Qualsiasi chiamata che non corrisponde a una regola esplicita allow o escalate viene negata per impostazione predefinita.```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
Esamina il `~/.ironcurtain/generated/compiled-policy.json` generato — queste sono le regole esatte applicate in fase di esecuzione.
## Configurazione
IronCurtain memorizza i dati di configurazione e di sessione in `~/.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)
Single-session runs (ironcurtain start, schede mux, processi cron) scrivono sotto sessions/. Le esecuzioni di workflow con contenitore condiviso scrivono invece sotto workflow-runs/ — vedi la sezione successiva.
Una definizione di workflow può aderire a un contenitore Docker condiviso impostando settings.sharedContainer: true nel proprio YAML. In questa modalità, ogni stato dell'agente viene eseguito all'interno dello stesso contenitore di lunga durata e condivide un'unica istanza del motore di policy; tra gli stati, l'orchestratore sostituisce a caldo la policy attiva, così ogni persona vede le proprie regole. Tutti gli artefatti dell'esecuzione vengono collocati in un unico albero:```
~/.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
Non viene creata alcuna voce per-sessione sotto `~/.ironcurtain/sessions/` per un'esecuzione di workflow con contenitore condiviso. I comandi visibili all'utente (`ironcurtain workflow start|resume|inspect|list`) sono invariati. Vedi [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md) per la creazione di definizioni di workflow e l'intero ciclo di vita.
Modifica la configurazione in modo interattivo:```bash
ironcurtain config
Key configuration areas: modelli e chiavi API, budget delle risorse (limiti di token/passi/tempo/costi), escalation ad approvazione automatica, provider di ricerca web, redazione dell'audit e impostazioni LLM del server di memoria. Vedi CONFIG.md per il riferimento completo.
Per instradare il traffico LLM attraverso un gateway come LiteLLM o OpenRouter (sia in Code Mode che in Docker Agent Mode), vedi MODEL_ROUTING.md.
Instrada gli agenti Docker attraverso i profili dei provider di modelli (ad es. GLM-5.2 via OpenRouter, senza sidecar) con ironcurtain config → Model Providers, quindi scegli un profilo in /new o con --provider-profile — vedi MODEL_ROUTING.md.
IronCurtain include sei server MCP preconfigurati. Tutte le chiamate agli strumenti (tranne la memoria) sono governate dalla tua policy compilata.
Le operazioni di sola lettura sono consentite dalla policy predefinita; le mutazioni (scritture, push, creazione di PR) richiedono l'approvazione umana. Gli strumenti usano la convenzione di denominazione server.tool (ad es., filesystem.read_file, memory.recall). Vedi ADDING_MCP_SERVERS.md per aggiungere i tuoi.
In Docker Agent Mode, il container non ha accesso alla rete — tutto il traffico passa attraverso il proxy MITM di IronCurtain. Per impostazione predefinita, sono raggiungibili solo i domini dei provider LLM. L'agente può richiedere l'accesso a domini aggiuntivi in fase di esecuzione tramite il server MCP virtuale proxy (add_proxy_domain). Ogni richiesta richiede l'approvazione umana tramite il flusso di escalation.
I domini approvati ricevono un tunnel di pass-through grezzo — le connessioni HTTP, HTTPS e WebSocket vengono inoltrate senza ispezione del contenuto o iniezione di credenziali. Questo offre all'agente una maggiore utilità (chiamare API di terze parti, streaming di dati da servizi esterni) ma significa che il traffico verso quei domini è non mediato. Vedi SECURITY_CONCERNS.md Sezione 2b-i per il modello di minaccia e DEVELOPER_GUIDE.md per i dettagli d'uso.
IronCurtain è progettato attorno a un modello di minaccia specifico: l'LLM va fuori controllo. Ciò può accadere tramite prompt injection (un'email o una pagina web dannosa dirotta l'agente) o tramite deriva multi-turno (l'agente si allontana gradualmente dall'intento dell'utente durante una lunga sessione).
Questo è un prototipo di ricerca. Le lacune note includono:
compiled-policy.json compilato.Vedi docs/SECURITY_CONCERNS.md per un'analisi dettagliata delle minacce.
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
Vedi [TESTING.md](https://github.com/provos/ironcurtain/blob/master/TESTING.md) per la guida completa ai test, inclusi i flag e le convenzioni dei test di integrazione.
### Struttura del Progetto```
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)
| Server | Tools | Funzionalità principali |
|---|
| Filesystem | 14 | Lettura, scrittura, modifica, ricerca di file; albero delle directory; spostamento; calcolo delle differenze |
| Git | 28 | Flusso di lavoro git completo: status, diff, log, commit, branch, push/pull/fetch, clone, stash, blame |
| Fetch | 2 | HTTP GET con conversione da HTML a markdown; ricerca web (Brave, Tavily, SerpAPI) |
| GitHub | 41 | Issues, PR, ricerca nel codice, revisioni tramite ghcr.io/github/github-mcp-server; richiede un personal access token di GitHub |
| Google Workspace | 128 | Gmail, Calendar, Drive, Docs, Sheets — richiede la configurazione OAuth tramite ironcurtain auth |
| Memory | 5 | Memoria semantica persistente con ricerca ibrida vettoriale+per parole chiave, riassunto tramite LLM e compattazione automatica. Abilitata per le sessioni persona e cron. |
| Problema | Guida |
|---|
| Chiave API mancante | Imposta la variabile d'ambiente (ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY o OPENAI_API_KEY) oppure aggiungi la chiave corrispondente a ~/.ironcurtain/config.json. |
| Sandbox non disponibile | Il sandboxing a livello di sistema operativo richiede bubblewrap e socat. Installali entrambi, oppure imposta "sandboxPolicy": "warn" nella configurazione del server MCP per lo sviluppo. |
| Budget esaurito | Regola i limiti in ~/.ironcurtain/config.json sotto resourceBudget. Imposta qualsiasi limite individuale a null per disabilitarlo. |
| Errori di versione di Node | Le linee Node.js supportate sono 22, 24 e 26 — le linee major pari che IronCurtain testa (isolated-vm). La 24 e la 26 installano binari precompilati; Node 22 compila isolated-vm dal sorgente e richiede una toolchain C/C++. Le linee dispari (23, 25) non sono testate — ironcurtain doctor le segnala con un avviso piuttosto che con un errore bloccante. |
| La policy non corrisponde all'intento | Rivedi compiled-policy.json per vedere le regole generate. Esegui ironcurtain customize-policy per perfezionare la tua costituzione, quindi ironcurtain compile-policy per ricompilare. Una formulazione specifica produce regole migliori — una formulazione vaga porta a policy vaghe. |
| L'auto-approvazione non si attiva | L'auto-approvatore approva solo quando il messaggio dell'utente autorizza esplicitamente l'azione (ad es., "push to origin" per git_push). I messaggi vaghi vengono sempre inoltrati alla revisione umana. Verifica che autoApprove.enabled sia true in config.json. |
| Terminale PTY/mux alterato dopo l'uscita | Esegui reset in quel terminale per ripristinare la modalità normale. È necessario quando il processo viene terminato in modo anomalo e la modalità raw non viene ripristinata. |
| Mux/listener: "already running" | Può girare un solo mux o escalation-listener alla volta. Il lock in ~/.ironcurtain/escalation-listener.lock viene cancellato automaticamente se il processo precedente è morto. Se persiste, controlla il PID nel file di lock. |
| Il bot Signal non risponde | Verifica che il container signal-cli sia in esecuzione (docker ps | grep ironcurtain-signal). Controlla che Signal sia configurato (ironcurtain setup-signal). Vedi TRANSPORT.md per la risoluzione dei problemi dettagliata. |