
Um runtime seguro* para agentes de IA autônomos. Política a partir de constituições em inglês simples. (*https://ironcurtain.dev)
Um runtime seguro* para agentes de IA autónomos, onde a política de segurança é derivada de uma constituição legível por humanos.
*Quando alguém escreve "seguro", deve ficar imediatamente cético. O que queremos dizer com seguro?
[!WARNING] Protótipo de Pesquisa. IronCurtain é um projeto de pesquisa em estágio inicial que explora como tornar agentes de IA seguros o suficiente para serem genuinamente úteis. APIs, formatos de configuração e arquitetura podem mudar. Contribuições e feedback são bem-vindos.
Pede-se ao agente que clone um repositório e envie alterações. Tanto git_clone como git_push são escalados pelo motor de política, mas o aprovador automático aprova-os automaticamente — a entrada confiável do utilizador a partir do modo de comando (Ctrl-A) forneceu intenção clara, pelo que não foi necessária uma /approve manual.
Os agentes de IA autónomos podem gerir ficheiros, executar comandos git, enviar mensagens e interagir com APIs em seu nome. Mas as frameworks de agentes atuais dão ao agente os mesmos privilégios que o utilizador, como acesso total ao sistema de ficheiros, credenciais e rede. Os investigadores de segurança chamam a isto autoridade ambiente, e significa que uma única injeção de prompt ou desvio multi-turno pode fazer com que um agente apague ficheiros, exfiltre dados ou envie código malicioso.
A resposta comum é ou restringir os agentes a uma sandbox estreita (limitando a sua utilidade) ou pedir ao utilizador que aprove cada ação (limitando a sua autonomia). Nenhuma das opções é satisfatória.
O IronCurtain segue um caminho diferente: expresse a sua intenção de segurança em inglês simples e deixe o sistema descobrir a aplicação.
Escreve uma constituição — um documento curto que descreve o que o seu agente pode ou não fazer. O IronCurtain compila isto numa política de segurança determinística usando um pipeline LLM, valida as regras compiladas contra cenários de teste gerados e aplica a política em tempo de execução em cada chamada de ferramenta. O resultado é um agente que pode trabalhar autonomamente dentro de limites que define em linguagem natural.
As ideias-chave:
O IronCurtain suporta dois modos de sessão com diferentes modelos de confiança:
Agente Integrado (Modo Código) — O próprio agente LLM do IronCurtain escreve snippets TypeScript que são executados numa sandbox V8. O IronCurtain controla o agente, a sandbox e o motor de política. Cada chamada de ferramenta sai da sandbox como um pedido MCP estruturado, passa pelo motor de política (permitir / negar / escalar) e só então chega ao servidor MCP real.
Modo Agente Docker — Um agente externo (Claude Code, Goose, etc.) é executado dentro de um contentor Docker sem acesso à rede. O IronCurtain medeia os efeitos externos: as chamadas à API LLM passam por um proxy MITM de terminação TLS (lista branca de hosts, troca de chave falsa para real), as chamadas de ferramentas MCP passam pelo mesmo motor de política e as instalações de pacotes (npm/PyPI) passam por um proxy de registo validador.
Em ambos os modos, o agente não é confiável. A segurança não depende de o modelo seguir instruções — é aplicada na fronteira.
Consulte SANDBOXING.md para a arquitetura completa com diagramas, análise de confiança camada por camada e notas sobre a plataforma macOS.
isolated-vm; 24 e 26 instalam binários pré-construídos, o Node 22 compila a partir da fonte na instalação e precisa de uma toolchain C/C++). As linhas de número ímpar (23, 25) funcionam mas não são testadas — o ironcurtain doctor avisa.container funciona como backend alternativo (VM por contentor; usado automaticamente quando os seus serviços estão em execução — veja containerRuntime em ironcurtain config)Como ferramenta global CLI (utilizadores finais):```bash npm install -g @provos/ironcurtain
**Da fonte (desenvolvimento):**```bash
git clone https://github.com/provos/ironcurtain.git
cd ironcurtain
npm install
1. Defina sua chave de API:```bash export ANTHROPIC_API_KEY=sk-ant-...
Você também pode colocar chaves em um arquivo `.env` na raiz do projeto (carregadas automaticamente via `dotenv`), ou adicioná-las em `~/.ironcurtain/config.json` através de `ironcurtain config`. As variáveis de ambiente têm precedência sobre os valores do arquivo de configuração. Suportadas: `ANTHROPIC_API_KEY`, `GOOGLE_GENERATIVE_AI_API_KEY`, `OPENAI_API_KEY`.
**2. Execute o assistente de primeira inicialização** (execute isso explicitamente antes de usar o caminho mux recomendado; também é executado automaticamente na primeira vez que você der `ironcurtain start` sem mux):```bash
ironcurtain setup
Orienta você na configuração do token do GitHub, provedor de pesquisa web, seleção de modelo e outras configurações. Cria ~/.ironcurtain/config.json com suas escolhas.
O IronCurtain vem com uma política padrão voltada para a experiência do desenvolvedor — operações somente leitura são permitidas, mutações (escritas, pushes, criação de PRs) exigem aprovação humana. Você pode começar a usá-lo imediatamente após a configuração.
A maneira recomendada de usar o IronCurtain. Ele oferece todo o poder da TUI interativa do seu agente (Claude Code ou Goose) enquanto o IronCurtain media cada chamada de ferramenta através de seu mecanismo de política — tudo em um único terminal.```bash ironcurtain mux
**Principais capacidades:**
- **TUI completa do agente** — O agente executa num PTY dentro de um contentor Docker sem acesso à rede. Interage com ele exatamente como se estivesse a correr localmente.
- **Gestão de escalação inline** — Quando uma chamada de ferramenta necessita de aprovação, um seletor de escalação sobrepõe-se à viewport com ações de tecla única (a/d/w para aprovar/negar/whitelist). Use `/approve+ N` para colocar um domínio ou caminho na whitelist para o resto da sessão.
- **Entrada de utilizador confiável** — O texto digitado no modo de comando (Ctrl-A) é capturado no lado do anfitrião antes de entrar no contentor. Isto cria um sinal de intenção verificado que o aprovador automático pode usar — por exemplo, digitar "push my changes to origin" aprovará automaticamente uma escalação `git_push` subsequente.
- **Gestão de separadores** — Crie múltiplas sessões concorrentes (`/new`), alterne entre elas (`/tab N`, Alt-1..9), feche-as (`/close`). Várias instâncias do mux podem ser executadas em paralelo.
Veja [DEVELOPER_GUIDE.md](https://github.com/provos/ironcurtain/blob/master/DEVELOPER_GUIDE.md) para o guia completo: modos de entrada, modelo de segurança de entrada confiável, fluxo de trabalho de escalação e referência do teclado.
### Sessões não-mux
Use `ironcurtain start` para tarefas rápidas únicas, scripts, ou quando quiser explicitamente o agente integrado local. Para trabalho interativo normal com agente Docker, use `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 também suporta retomada de sessão (--resume <session-id>), um modo legado raw PTY/debug, um transporte de mensagens Signal para aprovação móvel, e um modo daemon para tarefas cron agendadas. O daemon possui uma interface web opcional (--web-ui) para monitoramento baseado em navegador e tratamento de escalonamento. Veja RUNNING_MODES.md para detalhes.
IronCurtain orquestra múltiplos agentes de IA através de fluxos de trabalho estruturados. O fluxo de trabalho descoberta de vulnerabilidades integrado caça bugs de segurança de memória e lógicos em código nativo por meio de um pipeline de harness em camadas (Tier 1 função isolada → Tier 2 multicomponente → Tier 3 compilação completa) com controle de cobertura libFuzzer/AFL++, estados discover/triage orientados por hipóteses, e uma porta final de revisão de relatório humano. O fluxo de trabalho design-and-code executa ciclos de planejar / projetar / implementar / revisar, também com portas humanas. Cada agente executa em seu próprio contêiner Docker com limites de política específicos para o papel; o mecanismo gerencia transições de estado, passagem de artefatos e checkpointing de retomada de falhas automaticamente. Código aberto, executa inteiramente em sua máquina, aplica políticas de segurança por agente através do mecanismo de políticas baseado em constituição, e funciona com qualquer agente containerizado com Docker — comparável em escopo ao Amazon Kiro e Google Jules para tarefas de codificação, mas com segurança de primeira classe e um formato de definição de fluxo de trabalho extensível.

A interface web é a interface pretendida para execuções de fluxo de trabalho. Inicie o daemon, abra a URL impressa e conduza execuções a partir da página Workflows — o gráfico da máquina de estados acima é ao vivo, a linha do tempo de mensagens do agente flui com renderização Markdown, as revisões de porta incluem um navegador de workspace + artefatos, e execuções passadas permanecem listadas.```bash ironcurtain daemon --web-ui
O acesso via CLI está disponível para scripts, automação e depuração:```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"
Veja WORKFLOWS.md para a documentação completa.
A política padrão funciona bem para desenvolvimento geral, mas você pode adaptá-la ao seu fluxo de trabalho:
1. Personalize sua constituição (opcional, mas recomendado):```bash ironcurtain customize-policy
Uma conversa assistida por LLM que gera uma constituição adaptada ao seu fluxo de trabalho, salva em `~/.ironcurtain/constitution-user.md`. Você também pode editar este arquivo diretamente.
**2. Compile a política:**```bash
ironcurtain compile-policy
Traduz sua constituição em regras determinísticas, gera cenários de teste e os verifica. Os artefatos compilados vão para ~/.ironcurtain/generated/.
Personas são perfis de política nomeados — cada um agrupa uma constituição, política compilada, espaço de trabalho persistente e memória semântica. Use-os para executar agentes com diferentes funções ou níveis de acesso.```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"
Em modo mux, `/new my-assistant` abre uma aba usando essa persona. Personas também podem ser atribuídas a cron jobs. Veja [DAEMON.md](https://github.com/provos/ironcurtain/blob/master/DAEMON.md) para configuração de tarefas agendadas.
Personas também podem ser gerenciadas pela [interface web](https://github.com/provos/ironcurtain/blob/master/DAEMON.md#persona-policy-management) — navegar, criar, editar constituições e compilar políticas com progresso ao vivo. Como uma política é um limite de segurança, os controles de mutação da interface web são somente leitura, a menos que o daemon seja iniciado com `--allow-policy-mutation` (desativado por padrão).
### Habilidades
Coloque pacotes SKILL.md em `~/.ironcurtain/skills/<name>/` para disponibilizar orientações específicas para um propósito (scripts auxiliares, verificações determinísticas, conhecimento de domínio) para cada sessão do agente Docker. O conjunto mesclado é preparado em um diretório do host por pacote e montado como bind **somente leitura** dentro do contêiner no caminho que a descoberta nativa do agente ativo percorre — Claude Code é apontado para o diretório preparado via `--add-dir`, Goose verifica `~/.config/goose/skills/<name>/SKILL.md`. O agente os descobre automaticamente e decide quando lê-los com base na descrição do frontmatter de cada skill. O _formato_ do SKILL.md é o padrão aberto adotado por Claude Code, Goose e Codex; apenas o _caminho de descoberta_ difere por agente. Fluxos de trabalho podem enviar habilidades por estado dentro do pacote de fluxo de trabalho — veja [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md#skills).
## Política: Constituição → Aplicação
Você escreve a intenção em inglês simples; o IronCurtain a compila em regras determinísticas:```
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, editável pelo usuário. Ignorado quando não há listas presentes.Todos os artefatos são armazenados em cache por hash de conteúdo — apenas entradas alteradas acionam recompilação.
Uma cláusula da constituição como:```markdown
Compila para:```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" }
]
Qualquer chamada que não corresponda a uma regra explícita allow ou escalate é negada por padrão.```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
Revise o arquivo `~/.ironcurtain/generated/compiled-policy.json` gerado — estas são as regras exatas aplicadas em tempo de execução.
## Configuração
O IronCurtain armazena dados de configuração e sessão em `~/.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)
Execuções de sessão única (ironcurtain start, abas mux, jobs cron) escrevem em sessions/. Execuções de fluxo de trabalho em contêiner compartilhado escrevem em workflow-runs/ em vez disso — veja a próxima seção.
Uma definição de fluxo de trabalho pode optar por um contêiner Docker compartilhado definindo settings.sharedContainer: true em seu YAML. Nesse modo, cada estado do agente é executado dentro do mesmo contêiner de longa duração e compartilha uma única instância do mecanismo de política; entre os estados, o orquestrador troca a política ativa em tempo real para que cada persona veja suas próprias regras. Todos os artefatos para a execução ficam em uma única árvore:```
~/.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
Nenhuma entrada por sessão é criada em `~/.ironcurtain/sessions/` para uma execução de workflow em contêiner compartilhado. Os comandos visíveis ao usuário (`ironcurtain workflow start|resume|inspect|list`) permanecem inalterados. Veja [WORKFLOWS.md](https://github.com/provos/ironcurtain/blob/master/WORKFLOWS.md) para criar definições de workflow e o ciclo de vida completo.
Editar configuração interativamente:```bash
ironcurtain config
Áreas-chave de configuração: modelos e chaves de API, orçamentos de recursos (limites de token/etapa/tempo/custo), escalações de aprovação automática, provedor de pesquisa web, redação de auditoria e configurações do LLM do servidor de memória. Consulte CONFIG.md para a referência completa.
Para rotear o tráfego LLM através de um gateway como LiteLLM ou OpenRouter (tanto no Code Mode quanto no Docker Agent Mode), consulte MODEL_ROUTING.md.
Roteie agentes Docker através de perfis de provedor de modelo (por exemplo, GLM-5.2 via OpenRouter, sem sidecar) com ironcurtain config → Model Providers, em seguida, escolha um perfil em /new ou com --provider-profile — consulte MODEL_ROUTING.md.
O IronCurtain vem com seis servidores MCP pré-configurados. Todas as chamadas de ferramenta (exceto memória) são governadas pela sua política compilada.
Operações somente leitura são permitidas por política padrão; mutações (escritas, pushes, criação de PR) escalam para aprovação humana. Ferramentas usam nomenclatura server.tool (por exemplo, filesystem.read_file, memory.recall). Consulte ADDING_MCP_SERVERS.md para adicionar as suas.
No Docker Agent Mode, o contêiner não tem acesso à rede — todo o tráfego passa pelo proxy MITM do IronCurtain. Por padrão, apenas domínios de provedores LLM são acessíveis. O agente pode solicitar acesso a domínios adicionais em tempo de execução através do servidor MCP virtual proxy (add_proxy_domain). Cada solicitação requer aprovação humana através do fluxo de escalação.
Domínios aprovados recebem um túnel de passagem bruto — conexões HTTP, HTTPS e WebSocket são encaminhadas sem inspeção de conteúdo ou injeção de credenciais. Isso dá ao agente maior utilidade (chamar APIs de terceiros, transmitir dados de serviços externos), mas significa que o tráfego para esses domínios é não mediado. Consulte SECURITY_CONCERNS.md Seção 2b-i para o modelo de ameaça e DEVELOPER_GUIDE.md para detalhes de uso.
O IronCurtain é projetado em torno de um modelo de ameaça específico: o LLM se torna desonesto. Isso pode acontecer através de injeção de prompt (um e-mail malicioso ou página web sequestra o agente) ou através de deriva de múltiplas voltas (o agente gradualmente se desvia da intenção do usuário ao longo de uma longa sessão).
Este é um protótipo de pesquisa. Lacunas conhecidas incluem:
compiled-policy.json compilado.Consulte docs/SECURITY_CONCERNS.md para uma análise de ameaças detalhada.
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 o guia completo de testes, incluindo flags de teste de integração e convenções.
### Estrutura do Projeto```
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 | Ferramentas | Principais capacidades |
|---|
| Filesystem | 14 | Ler, escrever, editar, pesquisar arquivos; árvore de diretórios; mover; cálculo de diff |
| Git | 28 | Fluxo de trabalho git completo: status, diff, log, commit, branch, push/pull/fetch, clone, stash, blame |
| Fetch | 2 | HTTP GET com conversão de HTML para markdown; pesquisa web (Brave, Tavily, SerpAPI) |
| GitHub | 41 | Issues, PRs, pesquisa de código, revisões via ghcr.io/github/github-mcp-server; requer um token de acesso pessoal do GitHub |
| Google Workspace | 128 | Gmail, Calendar, Drive, Docs, Sheets — requer configuração OAuth via ironcurtain auth |
| Memory | 5 | Memória semântica persistente com pesquisa híbrida vetorial+por palavras-chave, sumarização LLM e compactação automática. Ativado para sessões de persona e cron. |
| Problema | Orientação |
|---|
| Chave de API ausente | Defina a variável de ambiente (ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, ou OPENAI_API_KEY) ou adicione a chave correspondente a ~/.ironcurtain/config.json. |
| Sandbox indisponível | O sandboxing a nível de SO requer bubblewrap e socat. Instale ambos, ou defina "sandboxPolicy": "warn" na configuração do seu servidor MCP para desenvolvimento. |
| Orçamento esgotado | Ajuste os limites em ~/.ironcurtain/config.json sob resourceBudget. Defina qualquer limite individual como null para desativá-lo. |
| Erros de versão do Node | As linhas suportadas do Node.js são 22, 24 e 26 — as linhas principais pares que o IronCurtain testa (isolated-vm). 24 e 26 instalam binários pré-construídos; Node 22 compila isolated-vm a partir do código fonte e precisa de um toolchain C/C++. Linhas ímpares (23, 25) não são testadas — ironcurtain doctor as sinaliza com um aviso em vez de uma falha grave. |
| Política não corresponde à intenção | Revise compiled-policy.json para ver as regras geradas. Execute ironcurtain customize-policy para refinar sua constituição, depois ironcurtain compile-policy para recompilar. Redação específica produz melhores regras — frases vagas levam a políticas vagas. |
| Aprovação automática não acionando | O aprovador automático só aprova quando a mensagem do usuário autoriza explicitamente a ação (por exemplo, "push to origin" para git_push). Mensagens vagas sempre escalam para revisão humana. Verifique se autoApprove.enabled está true em config.json. |
| Terminal PTY/mux corrompido após saída | Execute reset nesse terminal para restaurar o modo normal. Isso é necessário quando o processo é morto abruptamente e o modo raw não é restaurado. |
| Mux/listener: "already running" | Apenas um mux ou escalation-listener pode executar por vez. O bloqueio em ~/.ironcurtain/escalation-listener.lock é automaticamente limpo se o processo anterior estiver morto. Se persistir, verifique o PID no arquivo de bloqueio. |
| Bot do Signal não respondendo | Verifique se o contêiner signal-cli está em execução (docker ps | grep ironcurtain-signal). Verifique se o Signal está configurado (ironcurtain setup-signal). Consulte TRANSPORT.md para solução de problemas detalhada. |