AI Agent 工具权限设计方法详解(RBAC、最小权限与高危操作审批的落地分层)

把模型当”超管用户”配权限,是 Agent 系统最常见的灾难。工具权限控制必须按”身份可识别 → 范围可收敛 → 凭据短效 → 高危操作审批 → 全量审计”五层同步推进;缺任何一层,prompt injection 或一次意外的写库调用都可能让整个生产数据裸奔。下文把权限分层、场景差异、审批门控与一段可复用代码逐项拆开。

一、Agent 权限控制的五层模型

把 Agent 当成”会说话的脚本用户”是错误起点。OWASP 在 LLM Top 10(2025 版)里把 excessive agency(LLM06)单列为风险项,意思是模型被赋予了超出它完成本职所需的工具和数据访问能力。工业实践里通常把权限切成五层,缺一不可:

层级 关注问题 典型实现
身份(Identity) 谁在调用?代表谁? OAuth、M2M Token、Entra Agent ID
范围(Scope) 每个工具的最小权限 工具 manifest、显式 allow/deny 列表
凭据(Credential) 短效、不可落地 10 分钟 JWT、动态签发、托管 Vault
审批(Approval) 写库/对外发消息/扣款必须人审 HITL 门控 + 强认证
审计(Audit) 出事能查、行为可追溯 不可篡改的事件日志

把 Agent 的身份和人类用户身份解耦是近年共识。Microsoft Entra Agent ID、WorkOS Connect 都提供”Agent 作为一等公民”的注册方式——Agent 拿到自己的 client_id,而不是借用某个服务账号。

二、不同场景的工具权限差异

权限设计不是”一套打天下”。按工具的”读/写、可逆性、影响半径”分类,差异极大:

工具类型 风险级别 处理方式 典型示例
只读信息查询 低 自动放行 + 日志 知识库检索、订单详情查询
内部状态变更 中 自动执行 + 可回滚 创建工单、CRM 草稿
对外通信 高 强制审批 + 强认证 发送邮件、Slack 通知
资金/权限变更 极高 多因素 + 职责分离 + 限额 转账、删除数据、修改 RBAC
不可逆写 极高 必须人在环路、逐次确认 drop_table、强制 push、撤销证书

经验上,”中”级别是工程上最容易被忽视的:很多人以为”创建工单”是只读,但工单一上线就触发下游分单、写 IM、写邮件——一个看似无害的”中”风险操作,影响半径可能横跨三个系统。

三、最小权限与工具 manifest

最小权限(Least Privilege)不是口号,要落地到具体的工具 manifest 描述里。每条工具声明都应明确”它能做什么”和”它不能做什么”——后者用”默认拒绝 + 显式允许”实现,而不是反过来。OpenAI 的 function schema 只描述入参,不限制行为;所以真实的权限控制必须在应用层做。

权限 manifest 落地有 5 个必做步骤,顺序不能乱:

  1. 枚举工具清单:把所有可用工具列出来(哪怕只是临时调试用的),每条配 name、description、scope、tier 四个字段;
  2. 逐条标记风险等级:按”读/写、可逆性、影响半径”三类属性给 tier 赋 low / medium / high / critical;
  3. 声明高危操作的审批要求:needsapproval、approverrole、mfarequired、amountlimit_cents 等必须显式写;
  4. 配置执行器侧的 scope 校验:每次工具调用前用 set(manifest["scope"]).issubset(set(agent_scopes)) 做白名单匹配;
  5. 接入审计与告警:把”被拒绝”和”被审批放行”两类事件送到监控,关键事件触发即时告警。
from typing import Literal, List

# 工具权限 manifest:与工具 schema 解耦,由执行器加载
TOOL_MANIFEST = {
    "kb.search": {
        "scope": ["read:kb"],
        "tier": "low",
        "needs_approval": False,
        "rate_limit": "60/min",
    },
    "crm.create_ticket": {
        "scope": ["write:crm"],
        "tier": "medium",
        "needs_approval": False,
        "rate_limit": "30/min",
        "rollback_supported": True,
    },
    "email.send": {
        "scope": ["write:mail"],
        "tier": "high",
        "needs_approval": True,
        "approver_role": "team_lead",
        "mfa_required": True,
    },
    "billing.transfer": {
        "scope": ["write:billing"],
        "tier": "critical",
        "needs_approval": True,
        "approver_role": "finance_admin",
        "mfa_required": True,
        "amount_limit_cents": 1_000_00,  # 单笔上限 1000 元
    },
}


def authorize(tool_name: str, agent_scopes: List[str], context: dict) -> dict:
    """每次工具调用前都过这一道闸。"""
    manifest = TOOL_MANIFEST.get(tool_name)
    if manifest is None:
        return {"allow": False, "reason": "tool_not_in_manifest"}  # 默认拒绝

    # 1. scope 校验
    if not set(manifest["scope"]).issubset(set(agent_scopes)):
        return {"allow": False, "reason": "scope_missing"}

    # 2. 审批门控:高危/极高必须走 HITL
    if manifest["needs_approval"]:
        approved = request_human_approval(
            tool=tool_name, args=context["args"],
            approver_role=manifest["approver_role"],
            mfa_required=manifest.get("mfa_required", False),
        )
        if not approved:
            return {"allow": False, "reason": "human_rejected"}

    # 3. 限速与金额阈值
    rate_limiter.hit(tool_name, manifest["rate_limit"])
    if "amount_limit_cents" in manifest:
        if context["args"]["amount_cents"] > manifest["amount_limit_cents"]:
            return {"allow": False, "reason": "amount_exceeds_limit"}

    return {"allow": True, "tier": manifest["tier"]}

代码块展示了三件事:① 默认拒绝(未列入 manifest 的工具直接拒);② scope 与审批分两步走,避免”scope 通过就放行”;③ 金额、速率等业务阈值作为单独维度叠加,不会被单一 scope 覆盖。真正部署时,agent_scopes 应来自短期 JWT,由 AgentCore、AuthKit 等控制平面动态签发,而不是写在 prompt 里。

四、Human-in-the-Loop 审批的最佳实践

审批不是”每步都问人”,而是”按风险分级”。高危操作(发邮件、转账、删数据)必须经过人审,且审批必须绑定具体的参数快照——避免 Agent 改完参数复用上次同意。Powercode Group 提出的”action preview”模式值得借鉴:审批界面同时展示操作名、目标、影响记录、关键参数、数据来源、模型给出的理由。审批者点”通过”后,该授权仅对本次调用有效,参数变化即作废。

五、审计日志与零常驻权限

审计是事后追责的最后一根稻草。每条工具调用都应记录:发起用户、Agent 身份、工具名、参数、policy 决策、审批人、最终结果。Microsoft、Permit.io 等都在推”零常驻权限(zero standing permissions)”模式:Agent 启动时不持有任何长期凭据,每次任务开始时按 tier 和 task 申请短效 grant,任务结束或超时自动回收。这与”长期 PAT + RBAC”思路是根本不同的设计——后者一旦被 prompt injection 击中即全线失守。

到这里,工具权限从分层、场景差异、manifest 设计到审计的链路就完整了。

常见问题(FAQ)

Q1:Agent 权限和用户权限是一回事吗?

不是。Agent 应有独立身份与 scope,只继承它完成任务所需的最小能力。

Q2:所有高危操作都强制人审吗?

对,转账、删数据、对外发消息都应强制审批,参数变更需重新审批。

Q3:最小权限写在 prompt 里能生效吗?

不能。权限必须由运行时执行器校验,模型无法真正限制自己。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
赵其鑫的头像赵其鑫管理团队

相关推荐

返回顶部