Agent权限与安全
4023 字约 13 分钟
domain/aiai/agentsai/safety
2026-07-24
Agent 能调用工具、访问系统、发起外部请求,这意味着它的安全模型与传统 LLM 应用有本质差异——一个错误的文本最多让人误解,一个错误的行动可能删除数据、泄露机密、执行未授权操作。Agent 权限与安全的核心,是让 Agent 在"能做事"和"不闯祸"之间找到平衡。
一句话解释
Agent 安全 = 最小权限 + 沙箱隔离 + 人工审批门控 + 完整审计,四者缺一不可,因为 Agent 的行动能力使其风险远超纯文本生成。
Agent 安全 vs 传统软件安全
传统软件安全防御的是"代码漏洞被利用"——攻击者通过 buffer overflow、SQL injection 等手段让程序执行非预期逻辑。Agent 安全防御的是"模型推理本身被操纵"——攻击者不需要找代码漏洞,只需用自然语言诱导 LLM 做出错误决策。
| 维度 | 传统软件安全 | Agent 安全 |
|---|---|---|
| 攻击面 | 代码漏洞(注入、溢出、反序列化) | 模型推理(Prompt Injection、上下文污染) |
| 攻击语言 | 机器可读的协议/二进制 | 自然语言,门槛极低 |
| 防御边界 | 输入验证 + 访问控制 + 漏洞修复 | 信任域隔离 + 权限分级 + 行动门控 |
| 错误代价 | 数据损坏、服务中断 | 错误行动(删数据、转账、外发邮件),代价更高 |
| 非确定性 | 行为确定,可复现测试 | LLM 输出非确定,同一输入可能不同结果 |
| 测试方式 | 单元测试 + 红队渗透 | 红队 + 对抗性评估 + 沙箱回归测试 |
关键洞察:传统安全假设"代码逻辑是可信的,只要堵住漏洞就行";Agent 安全必须假设"LLM 推理本身不可信,任何时刻都可能被注入操纵",因此架构隔离比输入过滤更重要。详见 AI 与 Agent 中关于安全挑战的讨论。
最小权限原则与操作分级
最小权限原则(Principle of Least Privilege)要求 Agent 只拥有完成当前任务所必需的最少权限,且权限随任务上下文动态收紧。在 Agent 中的落地方式是操作分级——将 Agent 可执行的操作按风险等级划分,不同级别施加不同强度的控制。
操作分级模型
| 级别 | 操作类型 | 风险 | 控制要求 | 示例 |
|---|---|---|---|---|
| L0 只读 | 读取数据、查询状态 | 低 | 权限校验即可 | 查询文档、读取数据库、搜索网页 |
| L1 写入 | 创建/修改内部数据 | 中 | 权限校验 + 操作日志 | 写入文件、更新记录、发送内部消息 |
| L2 删除 | 删除数据、销毁资源 | 高 | 权限校验 + 日志 + 确认提示 | 删除文件、清空表、终止实例 |
| L3 外部通信 | 调用外部 API、发邮件、转账 | 极高 | 人工审批 + 日志 + 限频 | 发送邮件、调用支付 API、发布到生产环境 |
| L4 系统级 | 执行任意代码、修改系统配置 | 灾难级 | 沙箱隔离 + 人工审批 + 不可逆操作特殊处理 | 执行 Shell 命令、修改权限配置、安装软件 |
动态权限收紧
权限不应是静态的全局配置,而应随任务进度动态调整。例如一个"研究并总结"任务:
原则:权限随阶段"发放→使用→收回",而不是一开始就全部授予。这是将"最小权限"从静态配置升级为动态策略的关键。权限控制的专项讨论见 Agent权限控制。
沙箱执行环境设计
沙箱(Sandbox)是 Agent 执行不可信代码或操作时的隔离边界。隔离强度从弱到强形成一个光谱——选择哪一级取决于"被执行内容有多不可信"和"你能承受多高的开销"。
隔离强度光谱
各级隔离对比
| 隔离级别 | 实现方式 | 隔离边界 | 能防什么 | 不能防什么 | 开销 | 适用场景 |
|---|---|---|---|---|---|---|
| 同UID同进程 | 直接在 Agent 进程内执行 | 无 | 无 | 任何逃逸 | 最低 | 完全可信的内部代码 |
| OS级子进程 | subprocess + 权限降级 | 进程边界 + UID | 进程间数据隔离 | 内核漏洞、共享文件系统逃逸 | 低 | 执行半可信脚本 |
| 浏览器 origin | Web Worker / iframe | 同源策略 + CSP | 网络隔离、DOM 隔离 | 浏览器漏洞 | 中 | 前端代码执行、数据处理 |
| gVisor | 用户态内核拦截系统调用 | 系统调用过滤 | 大部分内核攻击 | 宿主内核 0day | 中高 | 容器化代码执行 |
| VM / microVM | Firecracker / 独立内核 | 硬件虚拟化 | 内核级隔离、完整 OS | 虚拟化逃逸(极罕见) | 高 | 执行完全不可信代码 |
选型决策
关键原则:沙箱不是"选最强的一劳永逸",而是"按风险匹配"。过度隔离会牺牲延迟和成本,而 Agent 的响应速度直接影响体验。更多防御性设计模式见 Agent失败模式。
人工审批(Human-in-the-Loop)
并非所有操作都值得人工审批——审批过多会让 Agent 退化成人肉确认机,审批过少则失去安全网。核心是判断哪些操作的代价高到不可逆或不可承受。
需要人工审批的判断标准
| 信号 | 说明 | 示例 |
|---|---|---|
| 不可逆 | 操作无法回滚 | 删除生产数据、发送对外邮件、执行转账 |
| 高影响范围 | 影响多个用户或系统 | 批量修改、全量部署、修改共享配置 |
| 涉及外部 | 操作跨越信任域边界 | 调用外部 API、发布到公网、外发数据 |
| 超出常规 | 偏离历史行为模式 | 突然请求从未用过的工具、操作量异常飙升 |
| 涉及凭证 | 使用敏感凭据 | 访问密钥库、使用生产 token |
审批门控实现
# 伪代码:操作执行前的审批门控
def execute_action(action, context):
risk = assess_risk(action) # 返回 L0-L4
if risk >= L3 or is_irreversible(action) or is_outbound(action):
# 进入人工审批队列
approval = request_human_approval(action, context)
if not approval.granted:
return ActionBlocked("需人工审批未通过")
if risk >= L2:
# 高风险操作:确认提示 + 日志
log_action(action, context)
if is_anomalous(action, context.history):
# 行为异常:即使低风险也需确认
confirmation = prompt_confirmation(action)
if not confirmation:
return ActionBlocked("异常操作未确认")
return run_in_sandbox(action, isolation_level=risk)设计要点:审批机制不应依赖 Agent 自我判断"我需不需要审批"——因为被注入的 Agent 可能恰好会绕过审批。审批触发条件应由 Agent 控制循环之外的独立安全层判定。这与架构分离原则一致,见 Agent工程架构 中执行层的安全控制设计。
Prompt Injection 对 Agent 的特殊威胁
Prompt Injection 是 Agent 安全面临的最独特、最难防的威胁。OWASP 已将其列为 LLM Application Top 10 的首位。
为什么对 Agent 尤其危险
传统 Prompt Injection 让 LLM 输出不当文本,影响有限。但在 Agent 中,注入的指令可以让 Agent 执行恶意操作——而 Agent 有工具、有权限、有行动能力。
间接注入:最隐蔽的攻击路径
间接注入(Indirect Prompt Injection)的恶意指令不来自用户输入,而是隐藏在 Agent 通过工具读取的外部内容中:
**工具注入(Tool Injection)**是间接注入的变种:恶意内容伪装成工具的返回值,操纵 Agent 的下一步决策。例如一个被污染的搜索 API 返回结果中嵌入指令。更多 Prompt Injection 机制见 Prompt Injection,安全边界总览见 安全边界。
Simon Willison 的"lethal trifecta"
安全研究者 Simon Willison 提出,当 Agent 同时满足以下三个条件时,进入极高风险状态(lethal trifecta / 致命三角):
只要打破三角中的任何一边,风险就大幅降低:
- 移除条件 1:Agent 不持有敏感数据(凭证隔离)
- 移除条件 2:Agent 不处理不可信内容(输入净化)
- 移除条件 3:Agent 无法对外发起请求(出口控制)
这是后续"四种防护方向"的理论基础。
四种安全防护方向
针对 Agent 的特殊威胁模型,安全防护应从四个方向构建纵深防御。
1. 架构分离(Trust Domain Separation)
Agent 的控制循环(LLM 推理、决策、规划)与代码执行(工具调用、脚本运行)不应共享同一信任域。核心思想:即使 LLM 被注入操纵,它能影响的是控制循环,但执行层有独立的安全检查。
实践:执行层的权限检查、审批门控、沙箱选择不应由 LLM 自己决定,而应由硬编码的安全策略强制执行。
2. 凭证隔离(Credential Isolation)
Agent 不应直接持有敏感凭证。凭证应通过短期 token、按需发放、用后即焚的方式管理:
| 策略 | 做法 | 效果 |
|---|---|---|
| 短期 token | 使用 TTL 短的 access token,而非长期 API key | 即使泄露,窗口期有限 |
| 按需发放 | 仅在需要使用某工具时临时授权 | 缩小暴露面 |
| 作用域限定 | token 只授予最小 scope | 限制误操作范围 |
| 不进入上下文 | 凭证不进入 LLM prompt,由执行层直接使用 | 防止通过注入窃取 |
3. 出口控制(Egress Control)
Agent 的所有出站请求必须经过 egress proxy 统一管控,禁止 Agent 直接访问任意网络:
这是打破 lethal trifecta 中"对外发起请求"这一边的直接手段。即使 Agent 被注入,也无法将数据外发到任意地址。
4. 决策门控(Decision Gating)
在 Agent 控制循环的关键节点插入门控检查点,对 LLM 产出的决策进行独立校验:
| 门控点 | 检查内容 | 触发动作 |
|---|---|---|
| 工具选择 | 是否调用了非常规工具? | 告警 / 要求确认 |
| 参数校验 | 参数是否包含敏感数据? | 拦截 / 脱敏 |
| 行为异常 | 是否偏离历史模式? | 降级 / 人工审批 |
| 频率检查 | 是否短时间内大量操作? | 限流 / 暂停 |
核心原则:门控逻辑由确定性代码实现,不依赖 LLM 自我约束。这正是"架构分离"在决策层面的体现。
操作审计与合规
审计不是事后取证的附属品,而是 Agent 安全的事前约束——当 Agent 知道自己的每一步都被记录,攻击者也更难在不留痕迹的情况下操纵它。
审计链内容
完整的审计链应记录 Agent 的决策→行动→结果全过程:
合规要点
- 不可篡改:审计日志应写入 append-only 存储,防止 Agent 或攻击者修改
- 因果可追溯:能从任意一个行动回溯到触发它的决策和输入
- 异常可检测:支持基于行为模式的异常检测(突然访问新工具、操作量飙升)
- 可回放:基于审计链可重建 Agent 的完整执行路径用于调试和取证
审计与可观测性密切相关,详见 Agent工程架构 中可观测性章节,安全性评估维度见 Agent评估。
常见误区
- 只防输入,不防架构:投入大量精力做 Prompt Injection 检测,却不做信任域隔离。正确的优先级是架构隔离 > 出口控制 > 输入过滤。
- 沙箱选最强的一劳永逸:所有操作都用 microVM 会导致延迟和成本不可接受。沙箱应按风险级别匹配。
- 审批依赖 Agent 自判:让 LLM 自己决定"要不要审批"等于让被注入的 Agent 决定要不要绕过安全。审批触发必须由独立安全层控制。
- 忽视间接注入:只防用户输入中的直接注入,忽视工具返回内容中的间接注入——而后者对 Agent 才是主要威胁。
- 凭证进入上下文:将 API key 直接放入 LLM prompt 供"使用",一旦被注入即可被窃取。凭证应由执行层直接持有。
- 静态权限配置:一次性授予全部权限且不收回,违背最小权限的动态收紧原则。
可继续补充的方向
- MCP 协议中的权限模型与安全边界(见 MCP安全边界)
- 多 Agent 系统中的信任传递与权限委托问题
- Agent 安全的自动化红队测试框架
- 不同行业(金融/医疗/政务)的 Agent 合规要求差异
- Agent 行为的形式化验证方法