Ken Huang 在 The Untrusted Tenant: Rethinking Infrastructure for AI Agents 里给了一个很准确的判断:AI agent 的安全问题,不应该只问“模型会不会做坏事”,而应该问“它运行时能碰到什么”。
这句话把问题从模型道德转回了基础设施。LLM 输出本身是不可信数据;当客户端把这些输出交给 shell、浏览器、MCP tool、公司 API、数据库和云资源执行时,它就接近在执行不可信代码。真正可控的不是模型下一步会不会犯错,而是它即使犯错、被 prompt injection、误解任务、调用错工具,损失半径还能不能被限制。
所以我想把之前的想法推进成一个更具体的概念:Agent Jail。
它不是一句“请 AI 不要访问某些文件”的提示词,也不是某个客户端自己的 sandbox 开关,而是一层跨 Codex、Claude Code、Cursor、自研 agent 的企业控制面:每个 agent session 都被当成一个不可信租户,只能在公司声明、策略评估、短期凭证和审计覆盖的边界内工作。
架构图
下面这张图用 next-ai-draw-io 的 MCP server 生成 draw.io 源图,再转成博客可展示的 SVG。
图源文件可以在这里下载继续编辑:/files/agent-jail-architecture.drawio。
这张图想表达一个核心原则:
Agent 客户端不是公司资源的可信主体。Agent Jail session 才是。
Codex、Claude Code、Cursor 或自研 agent 可以是很好的交互界面和执行器,但企业资源不应该直接信任“某个本地进程说自己是 agent”。公司真正应该信任的是一条可验证的链:
用户身份
→ 设备和客户端注册状态
→ Agent Jail session
→ 本次任务的 Capability Manifest
→ Policy Engine 的决策结果
→ Credential Broker 签发的短期凭证
→ MCP/API Gateway 的二次校验
→ 完整审计记录
没有这条链,本地裸跑的 agent 可以继续帮用户写草稿、改私有文件、做离线实验,但不能直接连接公司 GitHub、Jira、内部文档、数据库、生产 API 或私有 MCP server。
为什么现有 sandbox 不够
Codex 已经有 sandbox 和 approval 的概念。Codex sandboxing 文档把 sandbox 定义为限制 Codex 能否访问文件系统、网络和其他资源的执行边界;agent approvals and security 也强调 sandbox 和 approval policy 的组合。Claude Code 也有 settings、permissions、hooks、managed settings 这类机制。
这些能力是必要的,但它们还不是企业级 Agent Jail 的完整答案。
原因有三点。
第一,客户端 sandbox 主要约束“这个客户端自己怎么执行”。企业要解决的是“所有公司资源如何只接受受管 agent session”。如果用户绕过客户端,换一个本地脚本、另一个 agent、一个 curl 或一个自带 token 的 MCP server,单个客户端的 sandbox 就挡不住。
第二,agent 权限不是只有文件读写。真实企业任务会碰到:
- repo 和分支;
- issue、PR、CI;
- 内部文档和聊天记录;
- 数据库、数据仓库和 BI;
- 云资源和部署系统;
- 私有 MCP server;
- 浏览器登录态和本地凭证;
- 网络出口和内网服务。
这些资源分别有自己的权限模型。如果没有统一的 session identity 和 capability schema,权限会散落在每个工具、每个插件、每个 token、每个环境变量里。
第三,企业安全团队需要的是可审计、可复盘、可证明的边界,而不是“这个 agent 大概率没乱来”。审计问题很具体:
这个 agent 当时是谁启动的?
它被允许读哪些文件?
它拿到过哪些凭证?
它调用了哪些 MCP tools?
它访问过哪些域名和 API?
它有没有尝试越权?
它输出的代码 diff 和工具调用 trace 能不能复盘?
这些问题不能靠聊天记录回答,必须由运行时控制面回答。
Agent Jail 的七个组件
1. Capability Manifest
Agent Jail 的入口应该是一份声明式 manifest。它描述本次任务允许 agent 碰什么,而不是描述 agent “应该怎么想”。
一个最小版本可以长这样:
version: 0.1
session:
purpose: fix-billing-tests
ttl: 2h
filesystem:
read:
- src/**
- tests/**
- package.json
write:
- src/**
- tests/**
deny:
- .env*
- secrets/**
network:
default: deny
allow:
- registry.npmjs.org
- api.github.com
commands:
allow:
- npm test
- npm run lint
- git diff
deny:
- rm -rf *
- curl *
mcp:
allow_servers:
- github
- jira
allow_tools:
github:
- pull_request.read
- checks.write
credentials:
issue: short_lived
scopes:
- github:repo:read
- github:checks:write
audit:
log_tool_calls: true
log_network: true
log_file_diffs: true
Manifest 的价值不是格式本身,而是把权限从“散落在 prompt、环境变量和口头约定里”变成一个可版本化、可审核、可编译到不同客户端的 artifact。
Codex 可以把它编译成 sandbox、approval、hooks、MCP allowlist。Claude Code 可以把它编译成 permissions、deny rules、hooks、managed settings。自研 agent 可以把它编译成 container policy、network proxy policy、MCP gateway policy。
2. Runtime Sandbox
Runtime Sandbox 负责最底层的技术隔离:
- 工作目录隔离,比如临时 worktree;
- 文件系统 allowlist 和 denylist;
- OS sandbox、container 或 microVM;
- shell 命令拦截;
- 网络默认 deny;
- 输出 diff 和回滚点。
这层的原则很朴素:agent 不应该从一开始就站在用户整台机器上工作。它应该站在一个为本次任务裁剪出来的工作间里。
对 coding agent 来说,worktree 是一个很实用的默认边界。agent 可以大胆改代码、跑测试、生成文件,但所有变化都落在一个可 diff、可 review、可删除的目录里。再往上,可以用 container 或 OS sandbox 限制进程和网络。
3. Policy Engine
Policy Engine 是 Agent Jail 的大脑。每次高风险动作发生前,执行器把结构化请求交给策略引擎:
{
"session": "aj_123",
"actor": "user_456",
"action": "mcp.github.create_check_run",
"resource": "repo:company/billing-service",
"arguments": {
"commit": "abc123"
},
"context": {
"policy_hash": "sha256:...",
"tool": "github",
"client": "codex"
}
}
策略引擎返回:
allow
deny
require_approval
redact
allow_with_scope_reduction
这里不需要发明一整套新语言,可以接 Open Policy Agent 这类成熟的 policy-as-code 引擎。关键是让 agent 动作变成结构化请求,而不是让安全策略去解析一串自然语言或 shell 字符串。
4. Credential Broker
这是绕过防护的关键。
企业不能再把长期 token 放在本地环境变量里,让 agent 想用就用。Agent Jail 应该通过 Credential Broker 签发短期、窄 scope、绑定 session 的凭证:
subject: agent-session:aj_123
actor: user_456
audience: github.company.com
scope: repo:billing-service:read, checks:write
ttl: 30m
policy_hash: sha256:...
client: codex
这样一来,公司资源不是问“这个请求是不是带了一个 token”,而是问:
- token 是不是 Credential Broker 签的;
- session 是否还活着;
- policy hash 是否匹配;
- scope 是否覆盖这次资源;
- audience 是否正确;
- 设备和用户身份是否还满足条件。
这和 workload identity 的思路类似。SPIFFE 这类体系的核心就是给动态 workload 发可验证、短生命周期的身份。Agent Jail 可以借鉴这个方向,把 agent session 当成新的 workload。
5. MCP Gateway
Model Context Protocol 很适合做 agent 工具连接层,因为它已经把工具、资源、server instructions 和客户端接入抽象出来了。但企业不能让每个 agent 直接连接任意 MCP server。
中间应该有一个 MCP Gateway:
- 只允许注册过的 MCP server;
- 只暴露本次 manifest 允许的 tools;
- 对 tool arguments 做策略评估;
- 对 tool output 做敏感信息过滤;
- 记录 tool call trace;
- 对跨 tool 的数据流做检查。
MCP 的授权规范也在朝 OAuth、resource metadata 和 scope 方向演进。Agent Jail 要做的不是替代 MCP,而是在 MCP 上方加一层企业级 capability enforcement。
一个很现实的例子:GitHub MCP server 可能有很多工具,但修一个测试失败的 PR 未必需要 issue 删除、repo secret 读取、release 发布或组织成员管理。Agent Jail 应该只把当前任务需要的工具暴露给 agent,而不是把整个 GitHub 能力面给出去。
6. Network Egress Proxy
很多 agent 风险来自网络出口:
- 把内部代码发到外部 paste 服务;
- 被网页 prompt injection 诱导访问恶意 URL;
- 下载不可信脚本执行;
- 探测内网服务;
- 调用未经批准的外部模型或代理。
所以 Agent Jail 默认应该是 network deny。需要联网时,走 Egress Proxy:
allow registry.npmjs.org for package install
allow api.github.com for repo metadata
deny arbitrary internet
deny internal network by default
log request domain, method, size, session
这不是为了阻止 agent 做事,而是为了让联网成为明确授权的能力。一个只需要修改本地测试的任务,不应该顺手拥有全网访问权。
7. Audit + Attestation
最后是审计和证明。
Agent Jail 每次启动 session 时都应该产生一个 attestation:
session id
user id
client id
policy hash
runtime image hash
repo commit
start time / ttl
allowed capabilities
执行过程中记录:
file read/write
shell command
network request
MCP tool call
credential issuance
approval event
blocked attempt
final diff
这些日志要能被安全团队、平台团队和代码审查者复盘。Agent 做对了,审计能证明它是在边界内做对的;Agent 被拦住了,审计能证明拦截发生在哪里;Agent 做错了,审计能帮助定位是策略太宽、工具设计太危险、凭证过大,还是用户授权过度。
绕过 Agent Jail 的人,为什么不能连接公司?
这是整套机制最容易被低估的一点。
如果 Agent Jail 只是一个“推荐大家使用的工具”,那它一定会被绕过。用户可以直接运行另一个 agent,可以把 token 塞进环境变量,可以让脚本调公司 API,可以自己连 MCP server。只要公司资源继续接受普通长期凭证,Agent Jail 就只是一个本地安全建议。
真正落地时,企业必须反过来改资源准入:
公司资源不再信任 agent 客户端,只信任 Agent Jail 签发的 session identity。
具体可以这样做。
资源入口只认短期凭证
GitHub、GitLab、Jira、内部文档、数据库、CI/CD、私有 MCP server 都不能直接接受长期个人 token 给 agent 使用。它们应该通过 SSO、API Gateway 或 MCP Gateway 验证短期凭证。
没有 Credential Broker 签发的 token,本地裸跑 agent 就算知道 API 地址,也只能得到 401 或 403。
凭证绑定 session 和策略
凭证里要带 session id、policy hash、audience、scope、TTL。这样公司资源可以拒绝几类请求:
- token 不是 Agent Jail 签发的;
- token 已过期;
- token 的 audience 不是当前服务;
- token 的 scope 不覆盖目标资源;
- token 对应的 policy 已被撤销;
- token 对应 session 没有通过设备态势或用户身份检查。
这一步把“你有没有 token”升级成“你是不是在一个受管 agent session 里,拿着为本次任务签发的最小权限 token”。
私有 MCP server 不开放直连
私有 MCP server 应该默认只接受 MCP Gateway 的连接。Agent 客户端不直接连数据库 MCP、内部文档 MCP、生产运维 MCP,而是先连 Gateway。
Gateway 再根据 manifest 暴露工具子集:
本次任务允许:
- github.pull_request.read
- github.checks.write
- jira.issue.read
本次任务不允许:
- github.secrets.read
- jira.issue.delete
- db.query.production
- deploy.rollback
这样即使用户换了一个客户端,也看不到被策略隐藏的工具。
网络上阻断非受管路径
对内网 API、数据库、私有包仓库、MCP server,可以通过 Zero Trust Proxy、mTLS、设备证书、service identity、IP policy、DNS policy 做入口收敛。只有 Agent Jail runtime 所在的受管执行环境能访问这些入口。
这意味着绕过 Jail 的 agent 不是“违规但能用”,而是技术上拿不到路由、拿不到凭证、拿不到工具列表。
允许本地自由,但切断公司资源
这点很重要。Agent Jail 不应该试图禁止用户在本地运行任何 agent。那既不现实,也不必要。
合理边界是:
本地裸跑 agent:
可以写私有草稿
可以改非公司文件
可以做离线实验
不能拿公司资源凭证
不能连私有 MCP
不能访问受控 repo
不能读内部文档
不能查生产数据
企业要管的是公司资源,不是用户所有本地计算。
对 AI 客户端开放什么标准接口?
如果要让 Codex、Claude Code、Cursor、VS Code 插件、自研 agent 都能接入 Agent Jail,标准化不应该从 UI 开始,而应该从五个接口开始。
1. Agent Capability Manifest
统一描述本次 session 需要什么权限。客户端可以声明需求,企业策略可以裁剪需求,最终 manifest 成为执行边界。
2. Policy Decision API
客户端或 runtime 在高风险动作前调用:
can I read this file?
can I write this file?
can I run this command?
can I call this MCP tool?
can I send this data to this domain?
can I request this credential?
返回 allow、deny、approval、redact。
3. Credential Broker API
客户端不直接读取长期 secrets,只向 broker 请求:
give this session a 30-minute GitHub checks.write token
give this session a readonly docs token for collection X
give this session a masked warehouse query token
Broker 根据策略决定是否签发。
4. MCP Gateway Contract
MCP server 注册到 Gateway,声明工具、scope、风险级别和数据类型。Agent 客户端只看到本次 session 被允许的工具。
这比让每个客户端自己维护 MCP allowlist 更稳,因为真正的 enforcement 在服务端入口。
5. Audit Trace Schema
所有客户端都应该能输出统一 trace:
session event
tool call
file mutation
network event
credential event
approval event
blocked event
final artifact
否则企业会得到一堆不可比较的日志,很难做复盘、告警和合规。
最小可行落地路线
不用一开始就造完整平台。可以分四步。
第一步,做本地 Agent Jail CLI:
agent-jail run --client codex --policy agent-jail.yaml
agent-jail run --client claude-code --policy agent-jail.yaml
它负责编译配置、创建临时 worktree、默认禁网、记录 diff 和命令日志。
第二步,加 MCP Gateway:
只允许注册过的 MCP server
按 manifest 暴露工具
记录每次 tool call
高风险 tool 走 approval
第三步,加 Credential Broker:
不再给 agent 长期 token
只发 session-scoped short-lived token
资源服务校验 token claims
第四步,把公司资源入口改成只认受管 session:
repo provider
issue tracker
docs
database
CI/CD
private MCP
internal API
这一步做完,Agent Jail 才从“客户端沙箱”升级成“企业资源准入控制面”。
失败模式
这个方案也有边界。
如果用户把公司数据复制到私有文件,再交给未受管 agent,Agent Jail 不能凭空防住。这需要 DLP、数据分级、文档水印、终端治理和员工规范配合。
如果某个公司资源继续接受长期 token,绕过路径就还在。所以 Agent Jail 的落地重点不是把本地工具做漂亮,而是改资源入口。
如果 MCP tool 粒度太粗,比如一个 run_any_sql 或 execute_shell,策略会很难写。工具设计必须从模型友好升级到策略友好。
如果审计只记录“agent 最后回复了什么”,那没有意义。真正要记录的是文件、命令、网络、工具、凭证和 approval 的结构化事件。
最后的判断
Agent Jail 的价值不在“又一个 sandbox”。真正的价值是把 agent 权限从客户端习惯变成企业资源协议:
没有 manifest,不进入任务。
没有策略决策,不执行高风险动作。
没有短期凭证,不连接公司资源。
没有 MCP Gateway,不暴露内部工具。
没有审计,不算完成。
没有 Jail session identity,不是公司授权主体。
Codex、Claude Code、Cursor 和未来更多 agent 客户端都会继续变强。企业不应该把安全建立在“哪个客户端更听话”上,而应该建立在“所有客户端进入公司资源前,都必须通过同一套可执行、可审计、可撤销的权限边界”上。
如果 AI agent 真的是新的软件执行者,那 Agent Jail 就是它进入企业网络前必须经过的门禁。