AI Agent 权限模型:先限制能做什么
一次删库引发的思考
我见过一个真实场景:团队给内部运维 Agent 配了完整的数据库管理员权限,本意是让它「什么都能查,排查问题快一点」。某天凌晨,Agent 在分析慢查询日志时,把一条 DROP TABLE 当成了清理临时表的指令执行了。没有确认弹窗,没有回滚机制,审计日志里只留下一行冷冰冰的 executed successfully。
这不是 Agent 变笨了,而是权限模型从一开始就没打算让它「犹豫」。
人类用户可以理解业务语境——DBA 看到 DROP TABLE 会多想一秒,会确认是不是生产库。Agent 不会。它只会按上下文和工具定义执行。让 Agent 接入真实系统之前,我们必须先回答一个问题:它能做什么、不能做什么、做之前要找谁确认?
这篇文章讨论的就是这件事——Agent 权限模型的设计方法。
动作分级:不是所有操作都一样
权限设计的起点,是把 Agent 可能执行的动作按风险分级。不同等级的动作,对应不同的授权策略和确认机制。
我把动作分成五个层级:
| 层级 | 动作类型 | 风险 | 典型操作 | 授权方式 |
|---|---|---|---|---|
| L0 | 读取 | 低 | 查询数据库、读取文件、获取 API 数据 | 自动放行,记录日志 |
| L1 | 建议 | 低 | 生成分析报告、推荐方案、给出建议 | 自动放行,标注为「建议」 |
| L2 | 生成草稿 | 低-中 | 撰写邮件、生成代码、创建文档 | 自动放行,保存为草稿 |
| L3 | 低风险执行 | 中 | 创建工单、更新内部记录、发送内部通知 | 自动执行,异步通知 |
| L4 | 高风险执行 | 高 | 删除数据、发送邮件、调用支付接口、部署代码 | 需要人工确认后执行 |
这个分级不是学术分类,它直接决定了你的 Agent 在运行时该走哪条代码路径。
区分的关键在于两个维度:是否可逆和影响范围。读取内部文档和往客户邮箱发邮件,风险完全不同。Agent 需要知道自己在做什么级别的事情,系统也需要知道该在哪个环节踩刹车。
三种权限模型:RBAC 不够用了
传统软件系统里,权限控制基本靠 RBAC(基于角色的访问控制)。给 Agent 套 RBAC 能不能用?能用,但会很快碰到天花板。
Oso 的分析指出了一个核心矛盾:RBAC 假设角色和权限之间有稳定的映射关系,但 Agent 的角色在每个任务中都可能变化。一个 Agent 前一分钟在查日志,后一分钟可能需要写数据库。如果你为每种任务场景都创建一个角色,很快就会陷入「角色爆炸」——成百上千个细粒度角色,维护成本比权限问题本身还大。
我整理了三种主流模型的对比:
| 维度 | RBAC(角色) | ABAC(属性) | IBAC(意图) |
|---|---|---|---|
| 核心问题 | 谁在请求? | 请求的上下文是什么? | 为什么要这样做? |
| 授权依据 | 预定义角色 → 权限映射 | 用户属性、资源属性、环境属性 | Agent 当前任务目标 + 执行状态 |
| 适用场景 | 权限稳定的传统系统 | 多因素动态判断 | Agent 动态组合工作流 |
| 对 Agent 的适配 | 差——角色爆炸 | 中——需要大量属性定义 | 好——跟随任务意图变化 |
| 实现复杂度 | 低 | 中-高 | 高 |
| 典型实现 | Casbin RBAC、AWS IAM Roles | OPA/Rego、Cedar | IndyKite KBAC、实验性框架 |
IndyKite 提出的意图访问控制(IBAC)把「意图」作为授权的一等约束。它不再问「这个 Agent 有没有权限调这个 API」,而是问「这个 Agent 调这个 API 是否还在它的任务目标范围内」。如果 Agent 的任务是分析销售数据,它尝试调用邮件发送接口就会被拦截——不是因为角色不允许,而是因为意图不匹配。
arXiv 上的一篇论文提出了 Agent Access Control(AAC)框架,走得更远。它主张把权限判断从外部安全网关变成 Agent 自身的认知能力——用独立的推理引擎评估身份、场景、任务意图和合规性四个维度,然后不是简单地返回 allow/deny,而是动态调整输出的粒度、脱敏内容甚至语义改写。这个思路很前沿,但落地成本也不低。
现实中最务实的做法是组合使用:用 RBAC 做粗粒度控制(哪些工具集可用),用 ABAC 做运行时上下文判断(当前环境是否允许),用意图校验兜底(Agent 行为是否偏离任务目标)。
两个真实案例
案例一:客服 Agent 的邮件事故
某电商团队上线了一个客服 Agent,负责处理退换货请求。初期测试一切正常——Agent 能查订单、读物流信息、生成回复模板。上线后出了问题:Agent 在判断退货理由成立后,直接调用邮件服务给客户发了确认邮件,邮件内容包含了一段内部系统备注(「该用户本月第 3 次申请退货,建议人工复核」)。
问题出在两个地方。第一,Agent 的「发送邮件」动作被配置为 L3(低风险执行),自动放行。但对外发送邮件应该是 L4(高风险执行),需要人工确认。第二,Agent 在生成邮件内容时,把内部备注当成了回复的一部分——它没有「内部信息」和「对外信息」的边界概念。
修复方案:把动作分级调整,所有对外通信升级到 L4;邮件生成时走草稿模式(L2),由人工审核后才发送;在 prompt 层面加入数据分类标注,区分内部字段和可对外字段。
案例二:编码 Agent 的 rm -rf
一个开发团队给编码 Agent 配了 shell 执行权限,允许它运行测试、构建项目。某天 Agent 在清理临时文件时执行了 rm -rf /tmp/build-cache/*,但由于路径拼接错误,实际执行的是 rm -rf /tmp/*。
这个案例的核心问题不是 Agent 犯了错——程序都会犯错。问题是 Agent 拥有的权限太大,一个路径错误就造成了不可逆的损害。如果 shell 权限被限制在特定目录(比如只允许操作项目工作区),或者 rm 命令被替换为安全的移动到回收站操作,损失完全可以避免。
Okta 的建议很直接:给每个 Agent 独立的低权限凭证,凭证的生命周期跟任务绑定。任务结束,凭证失效。这样即使 Agent 被攻破或者自身出错,爆炸半径也是可控的。
权限决策流程
把上面的分级和模型落地,Agent 每次执行动作时的决策流程应该是这样的:
这个流程图里的每一步都应该有代码实现,不能只停留在架构文档里。
代码实现:从概念到落地
下面是几个关键环节的代码实现思路,展示权限模型怎么从纸面设计变成可运行的代码。
动作分级定义
# ❌ 不做分级,所有动作一视同仁
async def execute_action(agent, action):
result = await agent.tools[action.tool].execute(action.params)
return result
# ✅ 定义动作层级,不同层级走不同路径
from enum import IntEnum
class ActionLevel(IntEnum):
READ = 0 # 读取,自动放行
SUGGEST = 1 # 建议,标记输出
DRAFT = 2 # 草稿,保存待审
EXECUTE = 3 # 低风险执行,自动 + 通知
CRITICAL = 4 # 高风险执行,必须人工确认
async def execute_action(agent, action):
level = classify_action(action) # 根据工具和参数分级
match level:
case ActionLevel.READ:
return await execute_and_log(agent, action)
case ActionLevel.SUGGEST:
result = await execute_and_log(agent, action)
return tag_as_suggestion(result)
case ActionLevel.DRAFT:
return await save_as_draft(agent, action)
case ActionLevel.EXECUTE:
if await context_check(agent, action):
return await execute_and_log(agent, action)
return reject(agent, action, reason="上下文检查未通过")
case ActionLevel.CRITICAL:
approval = await request_human_approval(agent, action)
if approval.granted:
return await execute_and_log(agent, action)
return reject(agent, action, reason=approval.reason)上下文感知的权限检查
# ❌ 静态权限检查,只看角色
def check_permission(agent_role, action):
return action in ROLE_PERMISSIONS.get(agent_role, [])
# ✅ 多维度动态检查,结合任务意图
async def context_check(agent, action):
# 1. 基础权限:Agent 是否有权使用这个工具
if not has_tool_permission(agent, action.tool):
return False
# 2. 意图一致性:动作是否在任务目标范围内
if not is_intent_aligned(agent.current_task, action):
return False
# 3. 数据敏感性:是否涉及敏感数据操作
if involves_sensitive_data(action) and not has_data_clearance(agent):
return False
# 4. 环境约束:当前环境是否允许该操作
if action.target_env == "production" and not agent.prod_access:
return False
return True人工确认流程
# ❌ 没有确认流程,直接执行
async def execute_critical_action(agent, action):
return await agent.tools[action.tool].execute(action.params)
# ✅ 暂停执行,等待人工确认
async def request_human_approval(agent, action):
# 构造审批请求,包含完整上下文
approval_request = ApprovalRequest(
agent_id=agent.id,
task_summary=agent.current_task.description,
action=action.to_dict(),
risk_assessment=assess_risk(action),
evidence=await gather_evidence(agent, action),
idempotency_key=generate_idempotency_key(action),
)
# 路由到对应审批人
reviewer = route_to_reviewer(action, agent.current_task)
await notify_reviewer(reviewer, approval_request)
# 等待审批(异步,不阻塞 Agent 其他工作)
decision = await wait_for_decision(
approval_request.id,
timeout=TIMEOUT_SECONDS,
)
# 完整记录审批结果
await audit_log.record(
event="human_approval",
request=approval_request,
decision=decision,
reviewer=reviewer,
timestamp=now(),
)
return decision审计日志
# ❌ 简单日志,缺少关键上下文
logger.info(f"Agent executed {action.tool}")
# ✅ 结构化审计日志,支持事后追溯
@dataclass
class AuditEntry:
trace_id: str # 链路追踪 ID,串联同一任务的所有操作
agent_id: str # Agent 身份标识
task_id: str # 关联任务
action_level: int # 动作风险等级
tool_name: str # 调用的工具
parameters: dict # 调用参数(脱敏后)
target_resource: str # 目标资源
intent_context: str # 任务意图上下文
authorization_result: str # 授权决策结果
approval_chain: list # 审批链(谁批准、谁执行)
result_summary: str # 执行结果摘要
timestamp: datetime # 精确时间戳
environment: str # 执行环境(dev/staging/prod)StackAI 的文章特别强调了审计日志里的「双重身份」记录:每个操作都要同时记录发起请求的业务用户和执行操作的 Agent 身份。这在合规场景下尤其重要——你需要知道是「张三让 Agent 做的」还是「Agent 自己决定做的」。
最小权限不是口号
「最小权限原则」说了很多年,但在 Agent 场景下,它的含义变了。
传统的最小权限是给每个用户分配完成任务所需的最小权限集。Agent 的最小权限更激进——每次任务只给当前需要的权限,任务结束立即回收。Okta 把这叫做「零常驻权限」(Zero Standing Privilege):Agent 在任务之间默认只有最小信任,权限按需授予、按任务过期。
| 维度 | 传统最小权限 | Agent 最小权限 |
|---|---|---|
| 权限授予时机 | 账户创建或角色变更时 | 任务开始时 |
| 权限有效期 | 长期有效,手动回收 | 任务绑定,自动过期 |
| 凭证类型 | 长期密钥 / Token | 短期、有时间边界的 Token |
| 权限粒度 | 系统级或模块级 | 记录级、属性级、关系级 |
| 违规影响 | 持续暴露直到被发现 | Token 过期后自动收敛 |
| 典型实现 | IAM 角色 + 策略 | 短期凭证 + 上下文授权 + JIT 提权 |
Cequence AI 的分析指出了一个容易被忽视的风险:「数据渗漏」。当 Agent 拥有过宽的读取权限时,敏感信息会在不知不觉中进入 LLM 的上下文窗口。Agent 可能把不该看到的数据写进回复、日志或者草稿里。最小权限不只是防止 Agent 做错事,也是防止 Agent 看到不该看的东西。
实施要点:
- 每个 Agent 独立身份:不要共用服务账号,每个 Agent 有自己的凭证和生命周期
- 任务绑定凭证:凭证在任务开始时签发,结束时失效
- 双层权限校验:既检查 Agent 的权限,也检查委托人的权限
- 敏感数据隔离:在数据获取阶段就做权限过滤,不要把过滤留给 prompt
- 实时撤销机制:检测到异常时能立即吊销 Agent 凭证,不等定期审查
上线前检查清单
权限模型设计完了,怎么确认没有遗漏?以下是我在实际项目中使用的检查清单:
动作分级
- 所有 Agent 可用工具都已完成风险分级(L0-L4)
- 分级标准文档化,团队对分级规则有共识
- 分级覆盖了新增工具——每次加工具时同步评估风险等级
授权机制
- Agent 拥有独立身份标识,不与人类用户或其他 Agent 共享凭证
- 凭证生命周期与任务绑定,任务结束后自动失效
- L4 级动作实现了人工确认流程,确认前有完整的上下文展示
- 确认流程支持超时机制——审批超时不会导致任务永久阻塞
- 实现了幂等性保护——同一动作不会因为重试被重复执行
数据保护
- 敏感数据在获取阶段就做权限过滤,不依赖 prompt 层面隔离
- Agent 的读取范围与任务目标一致,没有超出需要的数据访问
- 对外通信(邮件、消息、API 调用)有独立的内容审查机制
审计与监控
- 每个操作都有结构化审计日志,包含 Agent 身份、任务上下文、审批链
- 审计日志不可篡改(append-only 或写入独立审计系统)
- 异常行为有实时告警——比如 Agent 突然尝试访问不相关的资源
- 审计日志的保留期限满足合规要求
应急与回滚
- 有实时撤销 Agent 权限的机制,不依赖代码重新部署
- L4 级动作执行后有验证步骤,确认执行结果符合预期
- 关键操作有回滚方案——即使人工批准了,执行失败也能恢复
写在最后
Agent 权限模型的核心不是「限制」,而是「可控」。一个好的权限设计让 Agent 在能力范围内充分发挥,同时确保出了错不会失控。
我见过太多团队在前期省掉权限设计的功夫,上线后用事故复盘来补课。权限模型不是安全团队的专属工作——它是 Agent 产品设计的一部分,应该在写第一行 Agent 代码之前就想清楚。
从动作分级开始,把每个工具的风险等级定义清楚。然后为不同等级的动作设计对应的授权路径。最后补上审计日志和应急机制。这三步做完,你的 Agent 权限模型就有了基本骨架。
剩下的,是在实际运行中持续调整。权限模型不是一次性设计,它会随着 Agent 能力的扩展和业务场景的变化不断演进。保持「默认最小权限」的原则不变,在这个基础上灵活调整就好。
参考资料
- A Vision for Access Control in LLM-based Agent Systems — arXiv, 2025. 提出 Agent Access Control(AAC)框架,从身份、场景、意图、合规四个维度评估 Agent 权限。
- Access Control in the Era of AI Agents — Auth0, 2025. 讨论 AI Agent 时代的细粒度访问控制需求。
- Why RBAC is Not Enough for AI Agents — Oso Security, 2025. 分析传统 RBAC 在 Agent 场景下的局限性,倡导动态上下文授权。
- Intent-based Access Control for AI Agents — IndyKite, 2026. 提出以任务意图作为一等约束的访问控制模型。
- How to Implement Least Privilege for AI Agents — Okta, 2026. Agent 最小权限实施的五大支柱:身份、动态范围、细粒度授权、可追踪意图、HITL 监督。
- Human-in-the-Loop AI Agents: Approval Workflows — StackAI, 2026. 五种人工审批模式的详细设计指南。
- Least Privilege Access for AI Agents: The Control You're Missing — Cequence AI, 2026. Agent 最小权限访问控制实践。
- Agent Authority Least Privilege Framework — FINOS AIR Governance Framework. Agent 权限最小化治理框架。