[控场AI]
· 5 分钟阅读· 2,784 字

LLM权限检查为何总是太晚?AI Agent访问控制的关键盲区

LLM权限检查为何总是太晚?AI Agent访问控制的关键盲区

Agent安全的漏洞在顺序而非判断:权限检查须前移到模型选择工具之前。

文章指出,搜索"LLM访问控制最佳实践"的人往往搞反了方向:日志记录的是已发生的事,访问控制决定的才是能发生什么。AI Agent安全的本质,是约束一个持有凭证的非确定性系统能做什么,其攻击面在于不可信文本会驱动模型当场选择工具并构造参数。多数实现把权限检查放在工具处理器内部,为时已晚——漏洞源于检查顺序而非判断逻辑。正确做法是把白名单决策放在身份解析与工具暴露之间:从请求而非模型输出解析身份,按身份推导工具白名单,只暴露白名单内的工具,并在参数求值前拒绝越界调用。拒绝事件比允许更有价值,同一身份的拒绝激增应触发告警。reskSecure负责边界执行,ReskPoints负责记录决策流,二者缺一不可。

工程师真正该问的问题

搜索"LLM访问控制最佳实践"的人,大多已经上线了Agent,现在想知道该记录哪些日志。这恰恰搞反了方向。日志告诉你发生了什么,访问控制决定什么可以发生。如果控制点放错了位置,日志不过是一份损失清单。

真正值得追问的不是"该记什么",而是"该在哪里做决定"。

LLM访问控制与监控:权限检查为何为时已晚

AI Agent安全到底是什么问题

AI Agent安全的核心,是约束一个自主或半自主LLM系统用它所持有的凭证能做什么。它不是提示词过滤,也不是模型对齐。它和任何特权集成面对的是同一类问题:一个持有token的actor发出请求,你需要判断哪些请求是合法的。

区别在于,这个actor是非确定性的。传统服务调用的是代码里写死的端点;Agent调用的端点是模型在运行时根据文本当场决定的,而那些文本可能来自不可信来源。这一个差异,就把传统权限模型的假设全部推翻了。

提示词注入(Prompt Injection) 是理解本文攻击场景的关键背景。它指攻击者通过把恶意指令嵌入到模型会读到的文本中(用户输入、检索到的文档、邮件正文、网页内容等),使模型将这些指令误当作合法任务的一部分来执行。与传统的代码注入不同,提示词注入利用的是模型对"指令"与"数据"缺乏结构性区分这一特性——对模型而言,二者都只是token序列。间接提示词注入(Indirect Prompt Injection)尤其危险,因为恶意文本不经用户之手,而是经由Agent读取的外部数据进入上下文,用户往往毫不知情。本文客服Agent的例子正属此类:客户消息里的隐藏指令劫持了工具选择过程。需要强调的是,提示词过滤无法根治该问题,因为绕过手法层出不穷且模型行为非确定性;真正的防线在于权限边界——即便模型被诱导,也不应拥有执行越权操作的能力。

攻击面:一个具体场景

设想一个客服Agent配了三个工具:读取客户记录、发起退款、发送邮件。集成用同一个服务token完成认证,这个token三个都能做。

Agent读取了一条客户消息。消息里藏着一段指令,模型把它当成了任务的一部分。模型随即调用退款工具,金额和账户号都取自那条消息。

token是有效的,调用格式是合法的,请求路径里没有任何畸形数据。唯一出问题的地方是:模型被允许选择一个调用者本就不该触发的工具。

这不是假想中的漏洞类别,而是"给Agent一个覆盖所有能力的单一凭证"的直接后果。一条注入指令的爆炸半径,等于那个凭证的授权范围。

常规做法为何失效

多数实现把权限检查放在工具处理器内部,流程大致是:

  1. 对Agent做认证
  2. 把工具定义发给模型
  3. 模型选择工具并生成参数
  4. 处理器校验调用方并执行

第4步已经太晚了。处理器运行时,工具早已被选中,参数也早已由模型输出构造完毕。你可以拒绝这次调用,但不可信文本已经驱动了工具选择这个过程本身。检查发生之前产生的任何副作用——包括处理器在校验时发起的下游调用——都已在你的控制之外。

漏洞不在某个判断写错了,而在顺序本身。

TOCTOU(Time-of-Check to Time-of-Use,检查时机与使用时机的竞态) 是理解"顺序本身就是漏洞"这一论断的经典安全模型。它描述的是:系统在某一点检查某个条件成立,但到真正使用该条件所保护的对象时,状态可能已经改变,导致检查失效。在传统软件中,TOCTOU常表现为文件权限检查后、文件打开前被替换。在LLM Agent场景中,它是逻辑层面的:权限检查发生在工具处理器内部(使用点),而驱动这一使用的决策(模型选择工具、生成参数)早已在上下文被污染时完成。检查所依据的假设——"被检查的调用是正当的"——在检查之前就已不成立。因此修复方向不是把校验写得更严,而是把检查前移到决策产生之前,使恶意输入无法进入决策环节。这也解释了为何"拒绝发生在参数求值之前"是一条硬性要求。

把决策移到模型之前

控制点应该在身份解析和工具暴露之间。正确的顺序是:

  1. 从请求中解析调用者身份,而不是从模型输出中解析
  2. 将该身份映射到一份明确的工具白名单
  3. 只向模型暴露白名单内的工具
  4. 在参数被求值之前,拒绝任何不在名单上的工具名
  5. 记录决策、工具名、参数与结果

两个性质至关重要。其一,白名单由调用者身份推导,模型无法自我扩权。其二,拒绝发生在参数求值之前,畸形或恶意参数根本到不了处理器。

监控建立在这之上。每一次允许和拒绝都是一个事件,而拒绝才是真正有意思的那个——它意味着有东西试图越出自己的范围。来自同一身份的大量拒绝,是值得告警的信号。

最小权限原则(Principle of Least Privilege, PoLP) 是白名单按身份推导这一设计的理论根基。它要求任何主体只应被授予完成其任务所必需的最小权限集合,且权限应随时间、上下文收敛而非扩张。在多租户或角色化系统中,这通常体现为:权限绑定到身份(调用者是谁),而非绑定到资源或进程本身。本文的反对对象正是"给Agent一个覆盖所有能力的单一服务token"这种粗粒度授权——它让一个凭证同时拥有读、退款、发信三项能力,等于让最小权限原则失效。按身份推导白名单,意味着不同调用者即便共用同一个Agent运行时,其可触及的工具集合也可以不同,从而将单点被攻破的爆炸半径限制在该身份应有的范围内。白名单的定期审查,也是最小权限原则"持续收敛"要求的体现。

用RESK落地

reskSecure在边界上执行白名单,位置早于工具定义被交给模型之前。你声明每个身份可以调用哪些工具,reskSecure拒绝该集合之外的一切。模型根本看不到它无权调用的工具,自然无从选择。

ReskPoints记录决策流。每条记录携带身份、工具名、参数以及调用是被允许还是被拒绝。审计轨迹和告警面因此集中在一处,而不必在事故之后从应用日志里反推意图。

两者合起来覆盖问题的两半:reskSecure做决定,ReskPoints做记录。单独使用任何一个都不够。只有白名单却看不到拒绝记录,等于盲人;只有日志却没有执行,不过是一本日记。

检查清单

  • 从请求中解析调用者身份,绝不从模型输出中解析
  • 白名单由身份推导,而非来自全局Agent配置
  • 在参数求值之前拒绝不在白名单上的工具名
  • 只向模型暴露白名单内的工具
  • 记录每一次允许和拒绝,含身份、工具名、参数与结果
  • 对每个身份的拒绝激增进行告警
  • 用与其他特权访问相同的节奏审查白名单
#LLM访问控制#AI Agent安全#权限检查#工具白名单#reskSecure#ReskPoints#提示词注入#最小权限原则
分享:

相关推荐