IronCurtain – A secure* runtime for autonomous AI agents IronCurtain is a research prototype runtime that enforces security policies for autonomous AI agents using a human-readable constitution. The system compiles natural-language rules into deterministic policies, assuming the LLM may be compromised, and mediates all agent actions through MCP servers with allow/deny/escalate decisions. It aims to provide a secure alternative to ambient authority in agent frameworks. A secure runtime for autonomous AI agents, where security policy is derived from a human-readable constitution. When someone writes "secure," you should immediately be skeptical. What do we mean by secure? Warning Research Prototype. IronCurtain is an early-stage research project exploring how to make AI agents safe enough to be genuinely useful. APIs, configuration formats, and architecture may change. Contributions and feedback are welcome. The agent is asked to clone a repository and push changes. Both git clone and git push are escalated by the policy engine, but the auto-approver approves them automatically — the user's trusted input from command mode Ctrl-A provided clear intent, so no manual /approve was needed. Autonomous AI agents can manage files, run git commands, send messages, and interact with APIs on your behalf. But today's agent frameworks give the agent the same privileges as the user such as full access to the filesystem, credentials, and network. Security researchers call this ambient authority , and it means a single prompt injection or multi-turn drift can cause an agent to delete files, exfiltrate data, or push malicious code. The common response is to either restrict agents to a narrow sandbox limiting their usefulness or to ask the user to approve every action limiting their autonomy . Neither is satisfactory. IronCurtain takes a different path: express your security intent in plain English, then let the system figure out enforcement. You write a constitution which is a short document describing what your agent is and isn't allowed to do. IronCurtain compiles this into a deterministic security policy using an LLM pipeline, validates the compiled rules against generated test scenarios, and then enforces the policy at runtime on every tool call. The result is an agent that can work autonomously within boundaries you define in natural language. The key ideas: The agent is untrusted. IronCurtain assumes the LLM may be compromised by prompt injection or drift. Security does not depend on the model "being good." English in, enforcement out. You write intent "no destructive git operations without approval" ; the system compiles it into deterministic rules that are enforced without further LLM involvement at runtime. Semantic interposition. Instead of giving the agent raw system access, all interactions go through MCP https://modelcontextprotocol.io/ servers filesystem, git, etc. . Every tool call passes through a policy engine that can allow , deny , or escalate to the user for approval. Defense in depth. Agent code runs in a V8 isolate with no direct access to the host. The only way out is through semantically meaningful MCP tool calls and every one is checked against policy. IronCurtain supports two session modes with different trust models: - Builtin Agent Code Mode — IronCurtain's own LLM agent writes TypeScript snippets that execute in a V8 sandbox. IronCurtain controls the agent, the sandbox, and the policy engine. Every tool call exits the sandbox as a structured MCP request, passes through the policy engine allow / deny / escalate , and only then reaches the real MCP server. - Docker Agent Mode — An external agent Claude Code, Goose, etc. runs inside a Docker container with no network access. IronCurtain mediates the external effects: LLM API calls pass through a TLS-terminating MITM proxy host allowlist, fake-to-real key swap , MCP tool calls pass through the same policy engine, and package installations npm/PyPI go through a validating registry proxy. In both modes, the agent is untrusted . Security does not depend on the model following instructions — it is enforced at the boundary. See SANDBOXING.md /provos/ironcurtain/blob/master/SANDBOXING.md for the full architecture with diagrams, layer-by-layer trust analysis, and macOS platform notes. - Node.js 22, 24, or 26 — the even-numbered major lines IronCurtain tests required by isolated-vm ; 24 and 26 install prebuilt binaries, Node 22 compiles from source at install and needs a C/C++ toolchain . Odd-numbered lines 23, 25 run but are untested — ironcurtain doctor warns. - Docker — not required but strongly recommended for Docker Agent Mode, which provides the strongest isolation. On macOS 26+ Apple silicon , Apple https://github.com/apple/container works as an alternative backend VM per container; used automatically when its services are running — see container containerRuntime in ironcurtain config - An API key for at least one LLM provider Anthropic, Google, or OpenAI As a global CLI tool end users : npm install -g @provos/ironcurtain From source development : git clone https://github.com/provos/ironcurtain.git cd ironcurtain npm install 1. Set your API key: export ANTHROPIC API KEY=sk-ant-... You can also place keys in a .env file in the project root loaded automatically via dotenv , or add them to ~/.ironcurtain/config.json via ironcurtain config . Environment variables take precedence over config file values. Supported: ANTHROPIC API KEY , GOOGLE GENERATIVE AI API KEY , OPENAI API KEY . 2. Run the first-start wizard run this explicitly before using the recommended mux path; it also runs automatically on first non-mux ironcurtain start : ironcurtain setup Walks you through GitHub token setup, web search provider, model selection, and other settings. Creates ~/.ironcurtain/config.json with your choices. IronCurtain ships with a default policy geared towards the developer experience — read-only operations are allowed, mutations writes, pushes, PR creation escalate for human approval. You can start using it immediately after setup. The recommended way to use IronCurtain. It gives you the full power of your agent's interactive TUI Claude Code or Goose while IronCurtain mediates every tool call through its policy engine — all in a single terminal. ironcurtain mux Key capabilities: Full agent TUI — The agent runs in a PTY inside a Docker container with no network access. You interact with it exactly as if it were running locally. Inline escalation handling — When a tool call needs approval, an escalation picker overlays the viewport with single-key actions a/d/w for approve/deny/whitelist . Use /approve+ N to whitelist a domain or path for the rest of the session. Trusted user input — Text typed in command mode Ctrl-A is captured on the host side before entering the container. This creates a verified intent signal that the auto-approver can use — e.g., typing "push my changes to origin" will auto-approve a subsequent git push escalation. Tab management — Spawn multiple concurrent sessions /new , switch between them /tab N , Alt-1..9 , close them /close . Multiple mux instances can run in parallel. See DEVELOPER GUIDE.md /provos/ironcurtain/blob/master/DEVELOPER GUIDE.md for the full walkthrough: input modes, trusted input security model, escalation workflow, and keyboard reference. Use ironcurtain start for quick one-shot tasks, scripts, or when you explicitly want the local builtin agent. For normal interactive Docker-agent work, use ironcurtain mux . 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 also supports session resume --resume