代理架构中的安全边界
Source: Vercel Blog
概述
当今大多数代理运行生成的代码,拥有对您机密的完全访问权限。
随着越来越多的代理采用 coding‑agent 模式——读取文件系统、运行 shell 命令以及生成代码——它们变成了多组件系统,每个组件需要不同的信任级别。
虽然许多团队将所有这些组件放在单一的安全上下文中运行(因为默认工具就是如此),但我们建议 以不同的方式思考安全边界。
以下我们将逐项说明:
- coding‑agent 架构的兴起
- 提示注入 + 代码执行的核心风险
- 四类不同的参与者及其信任等级
- 设计原则
- 常见架构(从最不安全到最安全)
1. 编码‑Agent 架构正成为常态
- 代理 读取并写入文件系统。
- 他们 运行 Bash、Python 或类似程序 来探索其环境。
- 他们 生成代码 以解决特定问题。
即使是那些并未标榜为 “coding agents” 的代理,也将代码生成作为最灵活的工具。
示例:一个生成并运行 SQL 来查询账户数据的客服代理,使用的正是相同的模式——只是指向数据库而非文件系统。能够编写并执行脚本的代理能够解决比仅限于固定工具调用更广泛的问题。
2. Core Risk: Prompt Injection + Code Execution
Consider an agent debugging a production issue:
- The agent reads a log file that contains a crafted prompt injection.
- The injection tells the agent to write a script that sends the contents of
~/.sshand~/.aws/credentialsto an external server. - The agent generates the script, executes it, and the credentials are exfiltrated.
Key point: Prompt injection gives attackers influence over the agent, and code execution turns that influence into arbitrary actions on your infrastructure.
The agent can be tricked into:
- Exfiltrating data from its own context
- Generating malicious software (which can steal credentials, delete data, or compromise any reachable service)
The attack works because the agent, the code it generates, and the underlying infrastructure all share the same level of access.
3. 四类不同的参与者及其信任级别
| Actor | Description | Trust Considerations |
|---|---|---|
| The Agent | 由 LLM 驱动的运行时,由其上下文、工具和模型定义。运行在 agent harness(编排软件、工具、外部服务连接)之中。 | 易受到提示注入和不可预测行为的影响。应仅在 按需知情 的原则下向其提供信息(例如,它不需要原始数据库凭证即可运行 SQL‑tool)。 |
| Agent Secrets | 系统运行所需的凭证(API 令牌、数据库密码、SSH 密钥等)。 | 由 harness 负责安全管理,但如果其他组件能够直接访问这些凭证,则会变得危险。 |
| Generated Programs | 代理生成并执行的代码。这是 通配符——它可以做任何语言运行时允许的操作。 | 若将生成的代码直接授予对凭证的访问权限,任何提示注入或模型错误都可能导致凭证被窃取或执行其他恶意行为。 |
| Filesystem & Environment | 底层主机(笔记本、虚拟机、Kubernetes Pod 等)。 | 可以信任 harness,但 不应信任 agent 拥有不受限制的访问权或在没有安全边界的情况下运行任意程序。 |
这四个参与者在 每个 代理系统中都存在。核心的架构问题是 是否在它们之间划分安全边界,还是让它们全部运行在同一信任域中。
4. 设计原则
- 最小特权访问 – 只授予每个参与者其真正需要的权限。
- 生成代码的隔离 – 在沙箱或独立的执行环境中运行生成的程序。
- 机密管理 – 将机密信息保持在代理的直接视野之外;仅在需要时注入。
- 边界强制 – 明确定义并强制四个参与者之间的安全边界。
5. 实际架构(从最不安全 → 最安全)
5.1 无边界(基线)
- 描述:所有四个角色共享同一个安全上下文。
- 影响:
- 在开发者的笔记本电脑上,代理可以读取
~/.ssh文件和 SSH 密钥。 - 在服务器上,它可以访问环境变量、数据库凭证和 API 令牌。
- 生成的代码可以窃取上述任何信息、删除数据,并访问环境能够访问的任何服务。
- 在开发者的笔记本电脑上,代理可以读取
- 缓解措施:工具链可能在执行某些操作前提示用户确认,但一旦工具运行后没有强制的边界。
5.2 密钥注入代理
[Agent] → [Proxy] → [External Service]
- 工作原理:代理位于主安全边界之外,拦截出站网络流量,仅在请求前往目标端点时注入凭证。
- 配置方式:工具链在代理中配置凭证和域白名单规则;生成的代码永远看不到原始的密钥值。
- 优势:
- 防止凭证外泄(凭证无法被复制出执行上下文)。
- 局限:
- 不能阻止运行时的滥用;生成的软件仍然可以使用注入的凭证发起意外的 API 调用。
- 权衡:从零边界架构的向后兼容升级——无需大幅重构,但代理和生成的代码仍共享同一安全上下文,唯一例外是密钥本身。
5.3 共享沙箱
- 概念:将代理工具链和生成代码一起封装在共享的虚拟机或沙箱中。
- 优势:
- 将两者都与更广阔的环境隔离。
- 生成的程序无法渗透到更大的基础设施。
- 考虑因素:
- 代理和生成的程序仍共享同一沙箱环境,因此沙箱内部的任何妥协都会影响双方。
- 可能需要额外的控制措施(例如网络出站过滤、只读文件系统挂载)来进一步提升安全性。
5.4 完全隔离执行(最安全)
- 代理工具链运行在受信任的特权环境中。
- 生成代码在独立的高度受限沙箱中执行(例如具有限制能力的容器、seccomp 配置、只读文件系统)。
- 密钥注入通过专用的密钥注入服务完成,该服务仅向沙箱进程提供短期、范围受限的凭证。
- 网络出站由零信任代理控制,依据每个请求的白名单进行过滤。
- 结果:即使提示注入导致恶意生成代码,代码也无法:
- 访问原始密钥(密钥从不离开注入服务)。
- 访问未授权的服务(代理阻止意外的出站流量)。
- 影响宿主环境(沙箱阻止文件系统或进程层面的攻击)。
6. 要点
- 识别您代理系统中的四个角色 并分配适当的信任级别。
- 引入边界——从秘密注入代理开始是一种低摩擦的改进;迁移到共享或完全隔离的沙箱可提供更强的保障。
- 对代理和任何生成的代码 均应用最小权限原则。
- 持续监控 提示注入尝试和异常代码执行模式。
通过重新思考安全边界的设定位置,您可以保持编码代理的灵活性,同时显著降低凭证被盗、数据外泄以及更广泛基础设施受损的风险。
概述
Agents and the code they generate must run in separate security contexts.
If they share the same context, generated code can:
- Steal the harness’s credentials.
- Misuse credentials via a secret‑injection proxy.
The sandbox protects the environment from the agent, but it does not protect the agent from its own generated code.
缺失的环节
在 独立计算(独立的虚拟机或沙箱)上运行 代理外壳 和 代理生成的程序,并使用不同的安全上下文:
| 上下文 | 其中包含什么? |
|---|---|
| 代理外壳 | 外壳代码、其机密以及所需的文件系统。 |
| 生成代码执行 | 生成程序的文件系统,无法访问外壳的机密。 |
当前格局
- Claude Code 和 Cursor 已经提供沙箱执行模式,但由于沙箱可能导致兼容性问题,桌面采纳率低。
- 在 云端,分离要实用得多:你可以为生成的代码提供一个匹配其运行所需软件的虚拟机,通常还能提升兼容性。
为什么这种分离是直接的
- 工具调用抽象 – 代理已经通过抽象层调用工具。
- 路由 – 该抽象层使得将代码执行路由到独立环境变得自然,无需重写代理。
计算配置
| 工作负载 | 配置 | 理想平台 |
|---|---|---|
| Agent harness | 大多数时间空闲,等待 LLM API 响应。 | Vercel – 在 I/O 期间计费暂停,仅计入活跃 CPU 时间(成本与实际工作量成比例)。 |
| Generated code | 短命、不可预测、不可信。 | Vercel Sandbox – 为每次执行启动一个 ephemeral Linux VM,执行后销毁。VM 边界实现安全上下文隔离。 |
沙箱双向工作:
- 它保护代理的机密不被生成的代码获取。
- 它保护更广泛的环境免受生成代码的任何行为影响。
最强架构:应用沙箱 + 密钥注入
| 属性 | 实现方式 |
|---|---|
| 密钥从不暴露给生成的代码 | 在网络层进行密钥注入(覆盖请求头,防止凭证替换攻击)。 |
| 计算隔离 | 代理 harness 在受信任的计算环境中运行;生成的代码在隔离的沙箱中运行。 |
对生产级代理系统的建议
- 在标准计算环境上将 agent harness 作为受信任的软件运行。
- 在隔离的沙箱中运行 generated code。
- 仅在网络层注入密钥;绝不将其暴露给沙箱进程。
这种分离将成为代理系统的标准架构。现在采用的团队将在代理处理更敏感工作负载时获得显著的安全优势。
安全的密钥注入现已在 Vercel Sandbox 可用。
代理系统中的角色与期望的安全边界
Agent
│
├─ Agent secrets
│
└─ Generated‑code execution
└─ Filesystem (isolated)
关键原则
- 永不直接向代理暴露系统凭证。
- 工具调用必须严格限定范围。
- 示例:为特定客户提供支持的代理应只收到针对该客户数据的工具,而不是接受客户‑ID 参数的通用工具(这会导致提示注入漏洞)。
- 需要凭证的生成程序 应通过 secret‑injection 代理 处理,而不是直接向代码提供访问权限。
期望的隔离
- 完全隔离 代理系统与生成程序之间——每个程序在各自的安全上下文中运行。
- 生成代码不能直接访问凭证;只能通过注入代理使用密钥。
- 注入的 Header 会覆盖 沙箱代码设置的同名 Header,防止凭证替换攻击。
没有边界会出现什么问题
代理系统中的四个角色
- Agent – 由 LLM 驱动的编排器。
- Agent secrets – API 密钥、令牌等。
- Generated code execution – 代理生成的程序。
- Filesystem – 由 harness 与生成代码共同使用的存储。
零边界(当前默认)
- 所有角色共享同一进程和文件系统。
- 生成的代码可以读取或外泄机密。
未进行沙箱的机密注入
- 机密被传递,但代码仍在同一环境中运行 → 仍然容易被外泄或滥用。
将 Agent 计算与沙箱计算分离
- Agent 在受信任的计算环境中运行。
- 生成的代码在隔离的沙箱中运行。
带机密注入的应用沙箱
- 结合两种方法的优势:隔离 + 可控的机密访问。
摘要
- 为代理框架和生成的代码提供独立计算。
- 使用 临时沙箱(例如 Vercel Sandbox)来运行生成的程序。
- 在网络层 注入密钥,绝不直接暴露它们。
- 将工具的作用范围严格限定,以避免提示注入攻击。
采用此架构可让团队在技术成熟时,构建 安全、可扩展且具成本效益 的代理系统。