provos/ironcurtain
GitHub: provos/ironcurtain
一个为自主 AI agent 打造的安全运行时,通过自然语言编写的 constitution 编译为确定性策略,在运行时对每次工具调用进行强制执行和审批控制。
Stars: 563 | Forks: 76
# IronCurtain
[](https://github.com/provos/ironcurtain/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@provos/ironcurtain)
[](LICENSE)
[](https://ironcurtain.dev)
**一个为自主 AI agent 打造的安全\* runtime,其安全策略源自人类可读的 constitution。**
_\*当有人写下“安全”时,你应该立刻保持怀疑。[我们所说的安全是什么意思?](https://ironcurtain.dev)_
## 演示
`)、传统的原始 PTY/调试模式、用于移动端审批的 Signal 消息传输,以及用于计划 cron 作业的守护进程模式。该守护进程有一个可选的 [Web UI](DAEMON.md#web-ui)(`--web-ui`),用于基于浏览器的监控和升级处理。详情请参阅 [RUNNING_MODES.md](RUNNING_MODES.md)。
### 多 agent 工作流
IronCurtain 通过结构化的工作流编排多个 AI agent。内置的**漏洞发现**工作流通过分层的 harness pipeline(第一层:隔离函数 → 第二层:多组件 → 第三层:完整构建)结合 libFuzzer/AFL++ 覆盖率门控、假设驱动的 `discover`/`triage` 状态,以及最终的人工报告审查门,在原生代码中寻找内存安全和逻辑错误。**设计与编码**工作流运行计划/设计/实现/审查循环,同样带有人工门。每个 agent 都在自己的 Docker 容器中运行,具有特定于角色的策略边界;引擎会自动管理状态转换、产物传递和崩溃恢复检查点。它是开源的,完全在你的机器上运行,通过基于 constitution 的策略引擎强制执行针对每个 agent 的安全策略,并适用于任何 Docker 容器化的 agent——在编码任务的范围上可与 Amazon Kiro 和 Google Jules 相媲美,但具有一流的安全性且支持可扩展的工作流定义格式。

**Web UI 是工作流运行的预期界面。** 启动守护进程,打开打印出的 URL,并从工作流页面驱动运行——上面的状态机图表是实时的,带有 Markdown 渲染的 agent 消息时间轴流,门审查包括工作区 + 产物浏览器,并且过去的运行记录会保留在列表中。
```
ironcurtain daemon --web-ui
```
CLI 访问可用于脚本编写、自动化和调试:
```
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"
```
有关完整的文档,请参阅 [WORKFLOWS.md](WORKFLOWS.md)。
## 自定义你的策略
默认策略适用于一般开发,但你可以根据自己的工作流进行调整:
**1. 自定义你的 constitution**(可选但推荐):
```
ironcurtain customize-policy
```
一场由 LLM 辅助的对话将生成一份量身定制以适应你工作流的 constitution,并保存到 `~/.ironcurtain/constitution-user.md`。你也可以直接编辑此文件。
**2. 编译策略:**
```
ironcurtain compile-policy
```
将你的 constitution 转换为确定性规则,生成测试场景,并验证它们。编译后的产物会输出到 `~/.ironcurtain/generated/`。
### Personas
Personas 是命名的策略配置文件——每个都捆绑了一个 constitution、编译后的策略、持久化工作区和语义记忆。使用它们来运行具有不同角色或访问级别的 agent。
```
ironcurtain persona create my-assistant # Create a persona
ironcurtain persona compile my-assistant # Compile its policy
ironcurtain start --persona my-assistant "Check my calendar"
```
在 mux 模式下,`/new my-assistant` 会使用该 persona 派生一个标签页。Personas 也可以分配给 cron 作业。请参阅 [DAEMON.md](DAEMON.md) 了解计划任务配置。
也可以从 [Web UI](DAEMON.md#persona-policy-management) 管理 Personas —— 浏览、创建、编辑 constitution,并带有实时进度地编译策略。因为策略是一种安全边界,所以除非使用 `--allow-policy-mutation`(默认关闭)启动守护进程,否则 Web UI 的变更控制是只读的。
### 技能
将 SKILL.md 包放在 `~/.ironcurtain/skills//` 下,即可让每个 Docker agent 会话使用特定目的的指南(辅助脚本、确定性检查、领域知识)。合并后的集合将被暂存到每个包对应的主机目录中,并以**只读**方式绑定挂载到活动 agent 的原生发现路径会扫描的容器路径中——Claude Code 通过 `--add-dir` 指向暂存目录,Goose 扫描 `~/.config/goose/skills//SKILL.md`。Agent 会根据每个技能的 frontmatter 描述自动发现它们,并决定何时读取它们。SKILL.md 的_格式_是 Claude Code、Goose 和 Codex 采用的开放标准;只有每个 agent 的_发现路径_不同。工作流可以在工作流包内部发布特定于状态的技能——请参阅 [WORKFLOWS.md](WORKFLOWS.md#skills)。
## 策略:Constitution → 执行
你用纯英语编写意图;IronCurtain 将其编译为确定性规则:
```
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)
```
1. **标注** —— 按角色(read-path、write-path、delete-path、none)对每个 MCP 工具的参数进行分类。
2. **编译** —— 将英语 constitution 转换为确定性的 if/then 规则。类别引用(“主要新闻网站”、“我的联系人”)将作为 `@list-name` 符号引用发出。
3. **解析列表** —— 通过 LLM 知识或 MCP 工具调用(例如,查询联系人数据库)将符号列表解析为具体值。写入 `dynamic-lists.json`,用户可编辑。当不存在列表时跳过。
4. **生成场景** —— 根据 constitution 以及强制手写的不变性测试创建测试场景。
5. **验证与修复** —— 针对真实的策略引擎运行场景。LLM 裁决分析失败情况并生成有针对性的修复(最多 2 轮)。如果无法验证策略,则构建失败。
所有产物均按内容哈希进行缓存——只有更改的输入才会触发重新编译。
### 编译后的规则是什么样的
一个 constitution 条款,如:
```
- The agent may perform read-only git operations (status, diff, log) within the sandbox without approval.
- The agent must receive human approval before git push, pull, fetch, or any remote-contacting operation.
```
编译后为:
```
[
{ "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" }
]
```
任何不匹配显式 `allow` 或 `escalate` 规则的调用都**默认被拒绝**。
```
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
```
检查生成的 `~/.ironcurtain/generated/compiled-policy.json`——这些是在 runtime 强制执行的准确规则。
## 配置
IronCurtain 将配置和会话数据存储在 `~/.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)
```
单会话运行(`ironcurtain start`、mux 标签页、cron 作业)写入 `sessions/` 下。共享容器的工作流运行则改为写入 `workflow-runs/` 下——请参阅下一节。
### 工作流运行布局
工作流定义可以通过在其 YAML 中设置 `settings.sharedContainer: true` 来选择加入共享 Docker 容器。在该模式下,每个 agent 状态都在同一个长生命周期的容器内运行,并共享一个策略引擎实例;在状态之间,编排器会热切换活动策略,以便每个 persona 都能看到自己的规则。运行的所有产物都集中存放在一个单一的树状结构中:
```
~/.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
```
共享容器工作流运行不会在 `~/.ironcurtain/sessions/` 下创建每个会话的条目。面向用户的命令(`ironcurtain workflow start|resume|inspect|list`)保持不变。有关编写工作流定义和完整生命周期,请参阅 [WORKFLOWS.md](WORKFLOWS.md)。
交互式编辑配置:
```
ironcurtain config
```
关键配置区域:模型和 API 密钥、资源预算(token/步骤/时间/成本限制)、自动批准升级、Web 搜索提供商、审计脱敏和记忆服务器 LLM 设置。有关完整参考,请参阅 [CONFIG.md](CONFIG.md)。
要(在代码模式和 Docker Agent 模式下)通过 LiteLLM 或 OpenRouter 等网关路由 LLM 流量,请参阅 [MODEL_ROUTING.md](MODEL_ROUTING.md)。
## 内置功能
IronCurtain 附带了六个预配置的 MCP 服务器。所有工具调用(记忆除外)均受你编译后的策略管辖。
| 服务器 | 工具 | 核心功能 |
| -------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Filesystem** | 14 | 读取、写入、编辑、搜索文件;目录树;移动;计算 diff |
| **Git** | 28 | 完整的 git 工作流:status、diff、log、commit、branch、push/pull/fetch、clone、stash、blame |
| **Fetch** | 2 | 带有 HTML 到 Markdown 转换的 HTTP GET;Web 搜索 (Brave, Tavily, SerpAPI) |
| **GitHub** | 41 | 通过 `ghcr.io/github/github-mcp-server` 进行 Issues、PRs、代码搜索、代码审查;需要 GitHub 个人访问令牌 |
| **Google Workspace** | 128 | Gmail、Calendar、Drive、Docs、Sheets —— 需要通过 `ironcurtain auth` 进行 OAuth 设置 |
| **Memory** | 5 | 持久的语义记忆,具有混合向量+关键词搜索、LLM 摘要和自动压缩功能。为 persona 和 cron 会话启用。 |
默认策略允许只读操作;变更(写入、推送、创建 PR)则需升级以供人工审批。工具使用 `server.tool` 命名方式(例如,`filesystem.read_file`、`memory.recall`)。请参阅 [ADDING_MCP_SERVERS.md](ADDING_MCP_SERVERS.md) 添加你自己的服务器。
### 网络直通(Docker Agent 模式)
在 Docker Agent 模式下,容器没有网络访问权限——所有流量都通过 IronCurtain 的 MITM 代理。默认情况下,只能访问 LLM 提供商域名。Agent 可以在 runtime 通过 `proxy` 虚拟 MCP 服务器(`add_proxy_domain`)请求访问额外的域名。每个请求都需要通过升级流程获得人工批准。
批准的域名将获得一个**原始直通隧道** —— HTTP、HTTPS 和 WebSocket 连接将被转发,不进行内容检查或凭证注入。这赋予了 agent 更大的实用性(调用第三方 API、从外部服务流式传输数据),但也意味着发往这些域名的流量是**不受中介的**。有关威胁模型,请参阅 [SECURITY_CONCERNS.md](docs/SECURITY_CONCERNS.md) 第 2b-i 节,有关用法详情,请参阅 [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md)。
## 安全模型
IronCurtain 是围绕特定的威胁模型设计的:**LLM 发生叛逆。** 这可能通过 prompt 注入(恶意电子邮件或网页劫持 agent)或多轮对话漂移(agent 在长时间会话中逐渐偏离用户意图)发生。
### IronCurtain 强制执行的内容
- **文件系统遏制** —— 具备符号链接感知的路径解析可防止路径遍历和符号链接逃逸攻击。
- **基于工具的策略** —— 每个 MCP 工具调用都会根据编译后的规则进行评估。策略引擎按角色(read-path、write-path、delete-path)对工具参数进行分类,从而做出细粒度的决策。
- **结构性不变量** —— 某些保护是硬编码的,无法被 constitution 覆盖:agent 永远不能修改自己的策略文件、审计日志或配置。
- **人工升级** —— 当策略显示为“升级”时,agent 会暂停,用户必须明确批准或拒绝。可选地,基于 LLM 的自动审批器可以处理明确的案例(请参阅 [CONFIG.md](CONFIG.md))。
- **审计追踪** —— 每次工具调用和策略决策都会记录到仅可追加的 JSONL 审计日志中。
- **资源限制** —— Token、步骤、时间和成本预算可防止会话失控。
### 已知限制
这是一个研究原型。已知的差距包括:
- **策略编译保真度** —— 基于 LLM 的编译器可能会误解 constitution 的意图。验证 pipeline 能捕获许多错误,但并不详尽。务必检查编译后的 `compiled-policy.json`。
- **V8 isolate 边界** —— 代码模式使用的是 V8 isolate,而不是操作系统级别的虚拟化。V8 的零日漏洞可能会允许逃逸。
- **无出站内容检查** —— 被允许写入文件的 agent 可以通过对敏感数据进行编码来绕过内容级别的控制。计划中:对出站内容进行基于 LLM 的可理解性检查。
- **升级疲劳** —— 过多的误报升级可能会导致习惯性批准。调整你的 constitution 以尽量减少不必要的提示。
有关详细的威胁分析,请参阅 [docs/SECURITY_CONCERNS.md](docs/SECURITY_CONCERNS.md)。
## 故障排除
| 问题 | 指导 |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **缺少 API 密钥** | 设置环境变量(`ANTHROPIC_API_KEY`、`GOOGLE_GENERATIVE_AI_API_KEY` 或 `OPENAI_API_KEY`)或将相应的密钥添加到 `~/.ironcurtain/config.json`。 |
| **沙箱不可用** | 操作系统级别的沙箱需要 `bubblewrap` 和 `socat`。安装两者,或者在 MCP 服务器配置中设置 `"sandboxPolicy": "warn"` 以便进行开发。 |
| **预算耗尽** | 在 `~/.ironcurtain/config.json` 的 `resourceBudget` 下调整限制。将任何单独的限制设置为 `null` 可将其禁用。 |
| **Node 版本错误** | 需要 Node.js 22+(`isolated-vm` 需要 `>=22.0.0`)。最高支持 Node 25(`<26`)。 |
| **策略与意图不匹配** | 查看 `compiled-policy.json` 以了解生成的规则。运行 `ironcurtain customize-policy` 以优化你的 constitution,然后运行 `ironcurtain compile-policy` 重新编译。具体的措辞会产生更好的规则——模糊的措辞会导致模糊的策略。 |
| **自动批准未触发** | 自动审批器仅在用户消息明确授权该操作时(例如,针对 `git_push` 的“push to origin”)才批准。模糊的消息总是会升级为人工审查。请验证 `config.json` 中的 `autoApprove.enabled` 是否为 `true`。 |
| **PTY/mux 终端退出后乱码** | 在该终端中运行 `reset` 以恢复正常模式。当进程被异常终止且未恢复原始模式时,需要执行此操作。 |
| **Mux/listener:“已在运行”** | 一次只能运行一个 mux 或升级监听器。如果前一个进程已死,则位于 `~/.ironcurtain/escalation-listener.lock` 的锁会自动清除。如果仍然存在,请检查锁文件中的 PID。 |
| **Signal 机器人无响应** | 验证 signal-cli 容器是否正在运行(`docker ps \| grep ironcurtain-signal`)。检查 Signal 是否已配置(`ironcurtain setup-signal`)。有关详细的故障排除,请参阅 [TRANSPORT.md](TRANSPORT.md)。 |
## 开发
```
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
```
有关完整的测试指南,包括集成测试标志和约定,请参阅 [TESTING.md](TESTING.md)。
### 项目结构
```
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)
```
## License
[Apache-2.0](LICENSE)
标签:AI代理, MITM代理, 人工智能, 暗色界面, 权限控制, 用户模式Hook绕过, 策略引擎, 网络安全挑战, 自动化攻击, 请求拦截