Course: Master Course · Deep-Dive: DD-20 · Duration: 60 min · Prerequisites: Modules 0–12, DD-09 (NemoClaw), DD-18 (MetaClaw), DD-19 (CrabTrap)
550 stars. TypeScript/Node. Apache-2.0. Niels Provos. The agent never holds real credentials. Policy compiled from plain English to deterministic JSON. Zero LLM at runtime. The purest expression of beneath-agent governance.
IronCurtain (github.com/provos/ironcurtain) is a secure runtime that wraps the entire AI agent. Its thesis, quoted by WIRED: "the agent is untrusted; security does not depend on the model being good." Created by Niels Provos — veteran security researcher (formerly Google, creator of bcrypt's hash algorithm).
Two contributions make IronCurtain architecturally distinct:
This is the direct counterpoint to CrabTrap's LLM-as-judge-at-runtime (DD-19). IronCurtain rejects runtime LLM judgment entirely. LLMs are stochastic; security policy must be deterministic.
IronCurtain's own agent writes TypeScript that runs in a V8 isolate (isolated-vm). Every tool call exits the sandbox as a structured MCP request through the policy engine. The V8 isolate provides a hardened execution boundary — not OS-level virtualization, but JavaScript-level isolation with per-call fuel and memory limits.
An external agent (Claude Code, Goose, etc.) runs in a Docker container with no network access. IronCurtain mediates everything outbound:
The network-less container is the key: the agent literally cannot reach the internet except through IronCurtain's controlled channels.
This is IronCurtain's signature mechanism and the most important idea in the project:
FAKE_ANTHROPIC_KEY_abc123Why this matters: Even if the agent is completely compromised via prompt injection, it cannot exfiltrate real credentials because it doesn't have them. The worst it can do is use the fake keys, which only work through IronCurtain's controlled proxy. This is the concrete implementation of removing "ambient authority" — the principle that an agent should never hold credentials it doesn't absolutely need, and in IronCurtain's case, it holds none.
Policy is written as plain English in a constitution.md file. IronCurtain compiles it offline:
constitution.md → [Annotate] → [Compile] → [Resolve Lists] → [Generate Scenarios] → [Verify & Repair]
→ compiled-policy.json (content-hash cached)
@list-name symbols.The critical insight: the LLM is used at build time, not runtime. At runtime, enforcement is deterministic JSON rule evaluation. Zero LLM involvement (except an optional auto-approver for unambiguous cases like "user said push my changes" → auto-approve the subsequent git_push).
Example: a constitution clause "agent must receive human approval before git push" compiles to {"tool":"git_push","decision":"escalate","reason":"..."}.
Three outcomes per tool call:
Escalation uses a terminal multiplexer (ironcurtain mux) with single-key a/d/w (allow/deny/whitelist) or Signal on mobile. The optional LLM auto-approver handles unambiguous cases in trusted-command mode.
These cannot be overridden by the constitution:
IronCurtain's thesis is that CrabTrap's approach (LLM-as-judge at runtime) is fundamentally flawed because LLMs are stochastic. But IronCurtain's compilation step has its own risk: compilation fidelity. If the LLM misinterprets the constitution during compilation, the wrong rule gets baked in — and since runtime enforcement is deterministic, the wrong rule is enforced consistently. You get predictable enforcement of potentially-wrong rules.
This is the honest tradeoff:
The verify-and-repair pipeline mitigates this, but doesn't eliminate it. IronCurtain's documentation is honest about this: "policy-compilation fidelity" is listed as a known limitation.
Like CrabTrap, IronCurtain is evaluated on governance axes, not harness axes:
| Dimension | Score | Notes |
|---|---|---|
| Coverage breadth | 5/5 | Full runtime wrap: MCP tools + LLM proxy + registry proxy + network |
| Enforcement reliability | 4/5 | Deterministic at runtime. Compilation-fidelity risk at build time. |
| Credential safety | 5/5 | Agent never holds real credentials. The fake-key swap. |
| Policy expressiveness | 4/5 | Plain English constitution → deterministic JSON. Scenarios + verification. |
| Production maturity | 2/5 | Explicitly a research prototype. APIs may change. Single author. |
| HITL design | 4/5 | Escalate/allow/deny/whitelist. Terminal mux + Signal. Auto-approver. |
IronCurtain is the purest expression of beneath-agent governance in the roster. The credential quarantine (agent never holds real keys) and deterministic policy compilation (LLM at build time, zero LLM at runtime) are the two strongest security primitives studied. Its limitation is maturity — explicitly a research prototype with unstable APIs. Study IronCurtain as the conceptual north star for agent security; deploy CrabTrap for production egress governance today; work toward IronCurtain's model as the destination.
IronCurtain's credential quarantine is the strongest defense against credential exfiltration studied in this course. Even a fully compromised agent cannot leak real credentials because it doesn't have them. The deterministic-enforcement thesis directly answers CrabTrap's probabilistic-judge vulnerability. Course 2B's attacks against IronCurtain would target: (1) the compilation fidelity gap — trick the build-time LLM into compiling a wrong rule; (2) the V8 isolate boundary — escape the sandbox; (3) escalation fatigue — flood the human with approval requests until they auto-approve.
# Deep-Dive DD-20 — IronCurtain: The Deterministic Governance Runtime
**Course**: Master Course · **Deep-Dive**: DD-20 · **Duration**: 60 min · **Prerequisites**: Modules 0–12, DD-09 (NemoClaw), DD-18 (MetaClaw), DD-19 (CrabTrap)
> *550 stars. TypeScript/Node. Apache-2.0. Niels Provos. The agent never holds real credentials. Policy compiled from plain English to deterministic JSON. Zero LLM at runtime. The purest expression of beneath-agent governance.*
---
## The Subject
IronCurtain (github.com/provos/ironcurtain) is a secure runtime that wraps the entire AI agent. Its thesis, quoted by WIRED: **"the agent is untrusted; security does not depend on the model being good."** Created by Niels Provos — veteran security researcher (formerly Google, creator of bcrypt's hash algorithm).
Two contributions make IronCurtain architecturally distinct:
1. **Credential quarantine**: the agent runs with only fake API keys. A TLS-terminating MITM proxy hot-swaps fake keys for real ones at the boundary. The agent *never holds real credentials*.
2. **Deterministic policy compilation**: you write policy in plain English (a "constitution"). An offline LLM pipeline compiles it to deterministic JSON rules. At runtime, enforcement uses zero LLM — pure if/then checks.
This is the direct counterpoint to CrabTrap's LLM-as-judge-at-runtime (DD-19). IronCurtain rejects runtime LLM judgment entirely. LLMs are stochastic; security policy must be deterministic.
## Architecture — Two Session Modes
### Code Mode (Builtin Agent)
IronCurtain's own agent writes TypeScript that runs in a **V8 isolate** (`isolated-vm`). Every tool call exits the sandbox as a structured MCP request through the policy engine. The V8 isolate provides a hardened execution boundary — not OS-level virtualization, but JavaScript-level isolation with per-call fuel and memory limits.
### Docker Agent Mode
An external agent (Claude Code, Goose, etc.) runs in a **Docker container with no network access**. IronCurtain mediates everything outbound:
- LLM API calls through a TLS-terminating MITM proxy (with the credential swap)
- MCP tool calls through the policy engine
- npm/PyPI installs through a validating registry proxy
The network-less container is the key: the agent literally cannot reach the internet except through IronCurtain's controlled channels.
## The Credential Quarantine
This is IronCurtain's signature mechanism and the most important idea in the project:
1. The agent is configured with **fake API keys** — e.g., `FAKE_ANTHROPIC_KEY_abc123`
2. When the agent makes an LLM API call, the request hits the IronCurtain MITM proxy
3. The proxy **replaces the fake key with the real one** before forwarding to the LLM provider
4. The response comes back through the proxy, which **scrubs any key reflection** from error bodies
5. The agent never sees a real credential
**Why this matters**: Even if the agent is completely compromised via prompt injection, it cannot exfiltrate real credentials because it doesn't have them. The worst it can do is use the fake keys, which only work through IronCurtain's controlled proxy. This is the concrete implementation of removing "ambient authority" — the principle that an agent should never hold credentials it doesn't absolutely need, and in IronCurtain's case, it holds none.
## The Constitution Pipeline (Deterministic Policy Compilation)
Policy is written as plain English in a `constitution.md` file. IronCurtain compiles it offline:
```
constitution.md → [Annotate] → [Compile] → [Resolve Lists] → [Generate Scenarios] → [Verify & Repair]
→ compiled-policy.json (content-hash cached)
```
1. **Annotate** — classify each MCP tool's arguments by role: read-path, write-path, delete-path, or none.
2. **Compile** — translate English to deterministic if/then rules. Categorical references ("major news sites") become `@list-name` symbols.
3. **Resolve Lists** — resolve symbols to concrete values via LLM knowledge or MCP tool-use. User-editable.
4. **Generate Scenarios** — create test cases and run them against the compiled policy.
5. **Verify & Repair** — an LLM judge repairs failures (up to 2 rounds). **Build fails if the policy can't be verified.**
**The critical insight**: the LLM is used at *build time*, not *runtime*. At runtime, enforcement is deterministic JSON rule evaluation. Zero LLM involvement (except an optional auto-approver for unambiguous cases like "user said push my changes" → auto-approve the subsequent `git_push`).
Example: a constitution clause *"agent must receive human approval before git push"* compiles to `{"tool":"git_push","decision":"escalate","reason":"..."}`.
## Enforcement Decisions
Three outcomes per tool call:
- **Allow** — rule matches an allow pattern
- **Deny** — default; no allow-rule match
- **Escalate** — pause the agent and prompt the human
Escalation uses a terminal multiplexer (`ironcurtain mux`) with single-key a/d/w (allow/deny/whitelist) or Signal on mobile. The optional **LLM auto-approver** handles unambiguous cases in trusted-command mode.
## Hardcoded Structural Invariants
These cannot be overridden by the constitution:
- The agent can never modify its own policy files
- The agent can never modify audit logs
- The agent can never modify configuration
- Symlink-aware path resolution prevents traversal/escape
- Append-only JSONL audit log
- Token/step/time/cost budgets
## The Probabilistic vs. Deterministic Debate — Resolved?
IronCurtain's thesis is that CrabTrap's approach (LLM-as-judge at runtime) is fundamentally flawed because LLMs are stochastic. But IronCurtain's compilation step has its own risk: **compilation fidelity**. If the LLM misinterprets the constitution during compilation, the wrong rule gets baked in — and since runtime enforcement is deterministic, the wrong rule is enforced consistently. You get predictable enforcement of potentially-wrong rules.
This is the honest tradeoff:
- **CrabTrap**: probabilistic enforcement of *correct* understanding (the judge understands the request each time)
- **IronCurtain**: deterministic enforcement of *possibly-incorrect* compilation (the rule was compiled once)
The verify-and-repair pipeline mitigates this, but doesn't eliminate it. IronCurtain's documentation is honest about this: "policy-compilation fidelity" is listed as a known limitation.
## Score: N/A (Governance Layer, Not Harness)
Like CrabTrap, IronCurtain is evaluated on governance axes, not harness axes:
| Dimension | Score | Notes |
|---|---|---|
| Coverage breadth | 5/5 | Full runtime wrap: MCP tools + LLM proxy + registry proxy + network |
| Enforcement reliability | 4/5 | Deterministic at runtime. Compilation-fidelity risk at build time. |
| Credential safety | 5/5 | Agent never holds real credentials. The fake-key swap. |
| Policy expressiveness | 4/5 | Plain English constitution → deterministic JSON. Scenarios + verification. |
| Production maturity | 2/5 | Explicitly a research prototype. APIs may change. Single author. |
| HITL design | 4/5 | Escalate/allow/deny/whitelist. Terminal mux + Signal. Auto-approver. |
### Architect's Verdict
> *IronCurtain is the purest expression of beneath-agent governance in the roster. The credential quarantine (agent never holds real keys) and deterministic policy compilation (LLM at build time, zero LLM at runtime) are the two strongest security primitives studied. Its limitation is maturity — explicitly a research prototype with unstable APIs. Study IronCurtain as the conceptual north star for agent security; deploy CrabTrap for production egress governance today; work toward IronCurtain's model as the destination.*
### MLSecOps Relevance
> *IronCurtain's credential quarantine is the strongest defense against credential exfiltration studied in this course. Even a fully compromised agent cannot leak real credentials because it doesn't have them. The deterministic-enforcement thesis directly answers CrabTrap's probabilistic-judge vulnerability. Course 2B's attacks against IronCurtain would target: (1) the compilation fidelity gap — trick the build-time LLM into compiling a wrong rule; (2) the V8 isolate boundary — escape the sandbox; (3) escalation fatigue — flood the human with approval requests until they auto-approve.*
### 3 things IronCurtain does better
1. **Credential quarantine**: the fake-key swap is the single strongest security primitive in the course. Agent never holds real credentials.
2. **Deterministic enforcement**: zero LLM at runtime. Policy is predictable, auditable, and testable via the scenario pipeline.
3. **Full runtime coverage**: MCP tool calls + LLM proxy + registry proxy + network. The broadest interception surface.
### 3 things to fix
1. **Maturity**: explicitly a research prototype. Needs productionization, API stabilization, multi-author governance.
2. **Compilation fidelity**: the build-time LLM could misinterpret the constitution. The verify-and-repair pipeline helps but doesn't eliminate the risk.
3. **Escalation fatigue**: too many approval requests could condition humans to auto-approve. Needs rate limiting on escalations and smart batching.
---
## References
1. **IronCurtain source** — github.com/provos/ironcurtain (TypeScript, Apache-2.0, 550 stars).
2. **Niels Provos blog** — "IronCurtain: A Personal AI Assistant Built Secure from the Ground Up."
3. **WIRED** — "This AI Agent Is Designed to Not Go Rogue."
4. **Help Net Security** — "IronCurtain: an open-source safeguard layer for autonomous AI assistants."
5. **Module 6** — permission/approval/safety; beneath-agent governance as the strongest model.
6. **Module 11** — security; credential isolation, deterministic enforcement, sandbox escape.
7. **DD-09 (NemoClaw)** — NVIDIA's production version of the same beneath-agent thesis.
8. **DD-19 (CrabTrap)** — the probabilistic counterpoint to IronCurtain's deterministic approach.
9. **DD-18 (MetaClaw)** — same proxy position, opposite purpose (learning vs governance).
10. **Course 2B** — IronCurtain is the foundational defense that Course 2B's attacks must overcome.