IronCurtain: Secure AI Agent Runtime
IronCurtain is a research-prototype runtime that constrains autonomous AI agents (Claude Code, Goose, or its own builtin agent) by compiling a human-written "constitution" into deterministic policy rules enforced on every MCP tool call. It treats the LLM as untrusted, mediating all filesystem/git/network/API access through a policy engine (allow/deny/escalate), a V8 isolate sandbox for its builtin agent, and a network-isolated Docker mode with a TLS-terminating MITM proxy for external agent tools. It also ships multi-agent workflow orchestration (e.g., a vulnerability-discovery pipeline with libFuzzer/AFL++ fuzzing gates) with human approval checkpoints.
What it is
IronCurtain (@provos/ironcurtain) is an early-stage research prototype CLI for running autonomous AI agents under a deterministic policy compiled from a plain-English "constitution." The summary covers that architecture; below are the operational specifics it omits — the two trust models, the extra Docker-mode defenses, version constraints, and default behavior.
How it works — the two modes differ materially
The summary lumps "V8 isolate or Docker" together, but the modes carry different trust models and different mediation:
- Builtin Agent (Code Mode): IronCurtain's own agent writes TypeScript that runs in a V8 isolate; every tool call exits as a structured MCP request through the policy engine.
- Docker Agent Mode (strongest isolation): an external agent (Claude Code, Goose) runs in a network-isolated container. Beyond the MCP policy engine, IronCurtain adds two mediations the summary does not mention: LLM API calls pass through a TLS-terminating MITM proxy with a host allowlist and a fake-to-real key swap (the agent never sees real keys), and npm/PyPI installs go through a validating registry proxy.
An auto-approver exists: escalated calls can be approved automatically when the user's trusted command-mode input (Ctrl-A) established clear intent, so not every escalation blocks on a manual /approve.
Preconditions
- Node.js 24 or 26 only — even-numbered lines; Node 25 is unsupported and untested (needs prebuilt
isolated-vmbinaries). - Docker recommended for the strongest mode; on macOS 26+ Apple silicon, Apple container is used automatically as the backend.
- An API key for Anthropic, Google, or OpenAI.
What to do
Install and configure:
npm install -g @provos/ironcurtain
export ANTHROPIC_API_KEY=sk-ant-...
ironcurtain setupsetup writes ~/.ironcurtain/config.json (GitHub token, search provider, model). Run it explicitly before the recommended mux path; it otherwise auto-runs on first non-mux start. The recommended entry point:
ironcurtain muxThis runs the agent's TUI in a PTY inside a network-isolated container while mediating every tool call. On escalation, an inline picker offers single-key a/d/w (approve/deny/whitelist); /approve+ N whitelists.
Default policy: read-only operations are allowed; mutations (writes, pushes, PR creation) escalate for human approval — usable immediately after setup.
Environment variables take precedence over the config file; a project-root .env is loaded via dotenv.
Caveats
The authors flag this as a research prototype — APIs, config formats, and architecture may change — and explicitly hedge the word "secure." Treat trust claims as unvalidated; the deeper layer-by-layer trust analysis and macOS notes live in SANDBOXING.md, not the README.
Technologies named here
- IronCurtain
- Node.js
- V8 isolate
- Docker
- macOS
- Apple Container
- Claude Code
- Docker Desktop
- goose
- Native Linux Engine
- Codex
- TLS-terminating MITM proxy
- libical
- Package proxies
- libFuzzer
- AFL++
- LiteLLM
- OpenRouter
- Signal messaging transport
- isolated-vm
- Model Context Protocol
- TypeScript
Techniques named here
- Prompt Injection
- Multi-turn drift
- Ambient authority
- Path traversal / symlink-escape attacks
- Semantic interposition
- Defense in depth
- Data exfiltration via outbound content encoding
- V8 sandbox escape
- Escalation fatigue
Related in AI Security
