AI Agent 能调用工具,却不该拥有无限权限:用 Tenuo 为 FinBot 加上任务级授权
给 Agent 接上数据库、邮件或支付工具,真正难的往往不是让它“会做事”,而是确保它只对当前任务、当前对象做被允许的事。提示词可以告诉模型“不要支付超额发票”,却不能把这句话变成可靠的权限边界:模型仍可能被业务话术说服,也可能绕开一个被保护的工具,改调另一个能力相近的入口。
Tenuo 团队发布的 FinBot CTF defended mode,展示了一种更接近能力授权的思路:为每个任务签发 warrant(授权凭证),限定 Agent 可调用的工具及其参数;每次工具执行前都检查该凭证,而不是只依赖提示词或模型自我约束。它不是万能的安全证明,但提供了一个值得动手验证的工程模式。
从“拒绝批准”到“钱确实没转出去”
FinBot 是 OWASP GenAI Security Project 的金融场景挑战环境,包含发票审批、付款、供应商沟通等 Agent 工作流。Tenuo 的示例仓库在此基础上加入可选的 defended mode;README 写明通过 TENUO_ENFORCE=true 启用。仓库说明,原有 Agent、提示词和漏洞保持不变,关闭防护时仍可按原挑战运行。
这个演示指出一个重要边界:只约束“审批发票”的 Agent 并不够。如果付款 Agent 还能绕过受保护的 process_payment,直接调用另一个转账工具,钱仍可能离开账户。因此,防护应覆盖每个能产生副作用的工具执行点,而不只是决策链上最显眼的一个 Agent。
Warrant 如何缩小权限
仓库给出的设计是由可信代码根据数据库中的任务记录构建授权,而不是让模型从用户提示中自行决定授权范围。发票 Agent 的 warrant 可限定它处理哪张发票;付款 Agent 只能对已批准的发票、档案中的收款账户以及不超过发票金额的范围执行付款。沟通 Agent 的收件人也被限制在记录中的供应商地址和内部部门。
多 Agent 委派时,根授权从可信路由信息构造;子 Agent 获得从根授权进一步收窄的凭证。子凭证不能比父凭证拥有更多权限。这样,编排模型即使给子 Agent 传入另一个供应商 ID,也不应凭空扩张它的访问范围。实际安全性仍取决于授权签发端是否可信、所有副作用工具是否都经过检查,以及凭证校验是否覆盖完整调用路径。
可信任务记录 ──> 根 warrant ──> 子 Agent 的收窄 warrant
│
Agent 工具调用 ──────────────────> 执行前校验 ──> 允许 / 拒绝
仓库报告还特别提到模型的文字总结不一定等于系统实际状态:被拒绝的邮件调用,Agent 仍可能声称“已发送”;被拒绝的审批也可能被描述成“财务已批准”。因此审计与验证应读取业务数据库或工具执行记录,而不是把 Agent 的自然语言回复当作事实来源。
本地跑一次演示
仓库 README 给出的前置条件包括 Docker(用于 Redis)以及 OpenAI API,或支持工具调用的 Ollama 模型。以下是其说明中的启动步骤骨架;密钥应通过环境变量提供,不要写入仓库:
git clone https://github.com/tenuo-ai/finbot-ctf
cd finbot-ctf
uv sync
docker run -d --name finbot-redis -p 6379:6379 redis:7-alpine
# 选择 OpenAI,或配置本地 Ollama 的 OpenAI 兼容接口
export OPENAI_API_KEY="${OPENAI_API_KEY}"
export PYTHONPATH=.
export DATABASE_URL=sqlite://
若使用 Ollama,README 展示了拉取 qwen2.5:14b、设置 OPENAI_BASE_URL=http://localhost:11434/v1,以及配置模型名和超时的做法。实际运行前应以仓库当前 README 和项目依赖为准;不要把示例密钥或本地数据库设置直接用于生产环境。启用防护时再设置 TENUO_ENFORCE=true,并按项目说明完成其余配置。
适合把这个示例用于安全评估或内部原型:先跑未防护基线,再启用 warrant,对照同一组攻击和正常业务任务;同时记录数据库中的最终状态、被拒绝的调用及误拦截情况。尤其要测试“模型改用另一个工具绕过限制”、跨供应商 ID、超额金额、伪造收件人等路径,而非只测提示注入文本。
如何看待项目给出的结果
Tenuo 仓库 README 报告了其 Promptfoo 测试结果,包括多个挑战入口在启用 Tenuo 后的攻击成功次数为零;也报告了一项正常发票任务在受保护模式下完成次数更多。它们是项目作者针对特定 FinBot 配置、模型与攻击集的实验结果,不代表所有 Agent、工具集或生产系统都能达到同样效果。测试次数和攻击流程也会影响比例,不应把表格数字外推成通用安全保证。
更稳妥的结论是:权限约束应该尽量落在工具调用执行边界,并由可信业务数据决定授权范围;模型负责提出动作,策略层负责判断动作是否在任务授权内。即使采用 warrant,也要配合最小权限、完整审计、拒绝路径测试和业务状态核验。对于真实支付或数据删除流程,还应保留人工审批、幂等控制和可追溯的回滚设计。