ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI Agent数据探索权限沙箱:动态边界让效率与安全兼得

AI Agent数据探索权限沙箱:动态边界让效率与安全兼得 AI Agent跑起来有多爽数据安全那边就有多慌。我们团队在衡石平台上落地AI Agent数据探索能力时业务方说的是效率革命安全团队说的是你请了个精力旺盛的实习生把公司数据库当练习场。两边都有道理。Agent自治性越强探索越深入它就越可能撞出安全边界。传统做法是干脆把权限收紧到只读但那样Agent就成了一个只能查固定报表的机器人根本谈不上探索。真正的问题不是要不要给权限而是怎么给、给到什么程度、边界画在哪里。我们后来做的这套方案就是衡石权限沙箱。核心思路一句话把AI的探索能力关在一个透明的笼子里它可以自由飞来飞去但飞不出笼子。这篇文章从边界划分、动态授权、动作分级、技术实现到真实踩坑完整讲一遍。1. AI Agent接入数据平台后传统权限为什么一夜之间失灵1.1 传统数据权限的隐形假设数据平台的传统权限模型无论RBAC还是ABAC底层都有一堆默认假设操作者是人人有固定的角色角色有稳定的数据集范围人在登录后身份固定能做的就是通过SQL或报表工具查询。这套模型在人和BI工具的时代没有问题。人在查数据的时候潜意识里会自我约束我知道自己没权限看某些列我不会去硬拼SQL我知道某个字段涉及敏感信息查到了也会注意。这些礼貌不是系统强制的但系统默认人类操作者会遵守规则。传统系统还有个特点权限判定发生在登录、授权、执行这条链路的早期。人登录之后后端给一套凭证后续的查询基本信任这个凭证。会话期内的行为没有太多二次判定。这在安全上其实是有漏洞的但人类操作者数量少、节奏慢问题不至于集中爆发。1.2 AI Agent带来的三个质变Agent进来之后三个变化直接击穿了传统模型的根基。第一意图不可控。Agent不是人它不会自觉。给它一个目标它会产生一连串推测、试探、验证行为。它可能先查A表看结构再查B表试关联再猜测某个字段的含义然后写一个复杂的JOIN去验证自己的假设。这个过程本身就是发散性的人脑判断不了它下一步要干什么。第二上下文超长。很多人低估了这一点。人在多轮取数对话里会自己记住哪些权限有、哪些权限没有不会再重复申请。Agent的多轮对话可能长达几十轮它会不断重构自己的查询计划。如果权限判定只在第一轮做后面几十轮就全是裸奔。第三目标漂移。Agent在探索过程中可能发现一些有趣的数据然后脱离最初的任务目标顺着这条新线索继续深挖。这在人身上叫好奇心在AI身上叫越权路径。我们现在用的Agent框架有基于Python的也有Rust实现的底层差别很大但共同点都是通过工具调用tool calling去操作外部系统。数据查询就是最常见的工具调用之一。你给Agent一个数据库连接器它就能自主生成SQL自主执行自主解读结果。权限问题瞬间被放到显微镜下。1.3 衡石权限沙箱的定位我们当时内部讨论了很久是做一个Agent专用只读账号——这是最省事的所有Agent请求都走同一个低权限账号查不到就报错。但这个方案一测就死了。Agent面对权限报错时不会像人一样停下来。它会换一种写法重试换一张表再试换一个函数再试甚至把查询拆成多个小块绕过限制。一个只读账号挡不住这种强度的试探反而会产生大量错误日志把真正的问题淹没掉。衡石权限沙箱的思路完全不同不是给Agent一个固定账号而是给每次Agent会话一个身份令牌令牌上绑定明确的边界描述。这个边界不是账号级的而是查询级的。每次Agent发起查询沙箱会重新计算边界、重新注入约束。也就是说Agent虽然拥有自主探索的能力但每走一步脚下都有护栏。2. 边界长什么样行级、列级、查询级三层沙箱2.1 行级边界让Agent只能看到属于自己的那部分数据行级安全Row-Level Security是权限沙箱的第一层。实现方式不复杂在Agent生成的SQL后面绑定一组谓词条件把它的视角限制在授权范围内。比如销售数据表sales登录用户是华东大区经理Agent会话绑定他名下区域的数据那么Agent不管怎么写SQL最终执行前都会被注入WHERE region 华东如果Agent写了SELECT customer_name, SUM(amount) FROM sales GROUP BY customer_name;沙箱改写后变成SELECT customer_name, SUM(amount) FROM sales WHERE region 华东 GROUP BY customer_name;这层边界的关键不在注入谓词这个动作而在谓词从哪来。衡石的做法是数据模型层维护一张授权的维度映射表记录每个身份标识用户、角色、组织节点能看到哪些维度值。Agent会话启动时沙箱读取映射表动态生成一组谓词片段这个片段对Agent是不可见的它只知道自己查到的是合法数据。行级边界的另一个细节AI Agent经常写子查询不能只在最外层注入。比如Agent在子查询里统计某个城市的总量外层再过滤一遍如果只改外层子查询里的全量数据命中依然会发生。所以改写要基于AST语法树遍历所有表引用逐表注入而不是简单的字符串追加。2.2 列级边界敏感字段不是不让你看是让你看脱敏后的有些字段不能整列拒绝——比如订单表中的金额字段是分析必需但负责人手机号就不是。直接拒绝会让Agent无法完成合理任务放任又出事。折中方案是列级脱敏与字段白名单结合。衡石在数据模型里对每个字段定义可见级别完全可见普通业务字段脱敏可见手机号、身份证、邮箱等用掩码函数包裹统计可见只允许聚合函数触碰不允许明细返回完全不可见连字段名都不暴露当Agent查询含脱敏字段时沙箱自动改写列引用-- Agent原始写法 SELECT customer_phone, order_id, amount FROM orders; -- 沙箱改写后 SELECT mask_mobile(customer_phone) AS customer_phone, order_id, amount FROM orders;有一类坑特别值得注意Agent会通过SELECT *或者查询INFORMATION_SCHEMA来探测表结构试图绕过列级白名单。我们当时在元数据层做了一层字段名混淆——给Agent展示的虚拟字段名和真实存储字段名不一致沙箱在改写时完成映射。这个方案收益很大Agent就算暴力枚举字段名碰撞到的也是虚拟名拿不到真实名就没法构造针对敏感列的查询。2.3 查询级边界不能让它把数据库当自助餐行和列管住了看什么查询级边界管怎么查。AI Agent在探索时可能产生大量重型查询甚至无意中触发全表扫描、跨表笛卡尔积、超长窗口函数。这不只是数据泄露问题还是资源占用问题。查询级边界我们主要配了这几项边界项默认策略说明单次查询最大返回行数5000行防止Agent拉全表单次查询扫描行数上限100万行防止无过滤的全表扫描单次查询运行时长30秒超时自动kill数据源白名单已授权的项目/数据源防止Agent跨项目join写入类操作全部拦截只允许查询不允许写库临时表操作池化隔离临时表只存在于沙箱内部会话结束回收查询级边界里最容易被忽略的是JOIN。Agent为了探索数据经常会关联多张表但授权往往是按单表配置的。A表有权限B表没有Agent写一个A JOIN B就同时拿到了两边的信息。查询级边界要求沙箱对所有涉及的表逐一核验权限任何一张表越权整个查询直接拒绝而不是只保护A表。3. 静态边界会困死探索动态放行才是平衡术的关键3.1 为什么静态边界必然失败如果沙箱只是一个静态过滤器AI Agent探索时马上会被卡死。它想查一张不在预设白名单里的表查询被拦截Agent会尝试换条件再查又被拦截几个来回之后Agent就退化成只能查固定几张表的填空机器人了。真正的数据探索一定包含超出预期的部分——Agent发现了某个关联关系需要临时查看另外一张表的相关字段这是探索价值所在。一刀切禁止等于把探索消灭了。所以衡石权限沙箱的第二层设计是动态放行机制。3.2 授权令牌每一次动态放行都有生命周期设计核心是一个临时授权令牌机制。Agent发起一个需要额外权限的查询时沙箱不直接拒绝而是返回一个授权请求标记。Agent可以把查询意图包括目标表、目标字段、筛选条件一起提交给策略引擎。策略引擎根据三件事做判断本次会话的基础边界、请求的敏感等级、当前用户的历史行为画像。如果判断属于低风险请求策略引擎直接签发一个一次性授权令牌。令牌绑定以下信息可访问的表和字段清单有效期默认5分钟探索类请求最长15分钟查询扫描量上限允许的SQL模式比如允许聚合不允许明细导出Agent拿到令牌后它的下一次查询会被令牌和基础边界叠加校验。令牌是一次性的用完即焚。同一张表如果Agent要再次访问必须重新发起授权请求。这个设计在初期开发时争议很大有人觉得用一次就失效太麻烦但实际跑下来AI Agent的探索路径是高度重复的如果令牌不一次性Agent会在第一轮把所有权限拿齐后面全部绕过沙箱那沙箱就名存实亡了。3.3 二次确认与人工审批的接入低风险放行进自动化流程高风险放行必须进人工审批。我们把审批流设计成可嵌入Agent对话的形态。Agent发起高危请求时策略引擎会把这个请求推给数据OwnerOwner在审批页面能看到的不只是谁申请了什么还有Agent的完整探索路径——它前面分别查了哪些表、基于什么推断要查这张表。这就是Agent可解释性的价值。人审批虽然慢但能拦住完全背离任务目标的方向。比如有个Agent在分析用户留存却申请访问薪资表Owner一眼就能发现问题。这套机制上线后人工审批通过率不到40%大量看似合理的请求其实都偏离了任务主轴。3.4 可撤销会话结束、疑似越权、立即吊销动态授权必须和会话生命周期强绑定。我们的实现方式是每个Agent会话有唯一的沙箱标识所有令牌都挂在这个标识下面。一旦会话结束或者行为风控触发告警整个标识下所有凭据全部吊销已创建的临时表一并回收。可撤销机制里有个容易被忽视的细节Agent的异步任务。Agent经常我现在查一个数据结果出来后继续处理这个继续处理可能在后台异步执行。如果异步任务不挂会话标识它就会在会话结束后继续运行带着已经失效的令牌访问数据。我们后续专门在任务调度队列里加了令牌快照校验任务开始执行前还要再验一次权限两次都通过才准跑。4. 动作分级与策略映射让Agent知道什么能碰、什么要申请4.1 四级动作模型AI Agent在数据平台上的所有行为可以抽象成四个等级。等级划分的意义在于让Agent自身也建立起边界感——它不是被系统事后拦截而是在规划阶段就选择合规路径。L0 元数据级浏览表名、字段名、统计信息、数据字典L1 聚合级count、sum、avg、group by、窗口函数聚合L2 明细级查看原始数据行带脱敏L3 物理导出级把查询结果写到外部存储、生成数据文件、推送消息L0是Agent探索的起点它需要先了解数据长什么样才能决定下一步查询。默认放行但要做频控——曾经出现过Agent在元数据层疯狂轮询表结构的行为本质上是它在枚举可用数据集。L1是真正的分析级操作可以放行但必须限制资源。聚合查询计算量大要配合扫描量上限和运行时间上限。L2明细级是最敏感的一档。Agent返回原始数据行哪怕是脱敏后的也会产生真正的信息暴露。策略是必须命中至少一个授权维度条件且返回行数不超过500行超过就必须走动态审批。L3物理导出在任何场景下都需要人工审批且审计日志永久保留。我们甚至不让Agent直接调用导出API而是要求Agent提交导出请求由数据平台生成一条带审计标识的下载链接链接有效期2小时点击行为被记录。4.2 策略表达用策略模板约束Agent的探索路径策略不能写在代码里要配置化。我们参考了OPAOpen Policy Agent的思路把策略做成声明式规则集- action: L1_AGG_QUERY allowed: true conditions: scan_limit: 1000000 runtime_limit: 30s datasources: [dw_main, adhoc_analytics] - action: L2_DETAIL_QUERY allowed: conditional conditions: row_limit: 500 must_hit_scope: true mask_fields: [customer_phone, identity_no, email] fallback: request_approval - action: L3_EXPORT allowed: false fallback: request_approval audit: mandatory这套策略的好处是安全团队可以独立更新规则不需要改Agent代码。实际运行中策略调整的频率比预期高很多——新的数据源接入、新角色上线、某个Agent出现异动都需要快速调整。4.3 行为风控探索路径的异常识别动作分级解决单次行为合不合法行为风控解决一串行为合不合逻辑。AI Agent异常行为的典型特征是循环试探。正常Agent的查询路径是树形的从一个主题发散出去每个分支深度有限。异常Agent的路径是锯齿形的——同一张表反复查询但条件略微变化连续多次尝试访问未被授权的高敏感表单次查询返回行数突然暴增。我们在沙箱日志上做统计窗口三个核心指标5分钟内同一Agent会话的查询次数上限默认30次10分钟内命中高敏感表的次数上限默认3次单会话累计扫描行数上限默认200万行指标可以配置但默认值不要调得太松。调太松的后果是Agent在不知不觉间完成了数据集的拼接探测——这次查A表一列下次查B表一列拼接起来就逼近真实信息。行为风控发现的是组合路径这是单次校验发现不了的。4.4 会话级沙箱与请求级沙箱的区别最后补一个设计决策点这也是我们纠结最久的地方。沙箱模式有两种会话级和请求级。会话级指Agent整个对话生命期内所有查询共享同一套边界和令牌。配置简单系统压力小但有状态漂移风险——上下文超长时权限状态可能和当前任务对不上。请求级指每次查询都要重新组装边界、重新校验实现成本高但状态无共享最安全。我们的方案是混合模式基础边界使用会话级动态放行的临时权限使用请求级。基础边界在会话创建时一次性绑定稳定不变而每次动态放行都是独立的一次性令牌和会话状态无关只跟具体这一次查询绑定。这既控制了性能开销又把最危险的临时权限超期使用堵死了建议参考这套思路的时候把这两个层级彻底分开不要合并成一个会话权限去管理。5. 实现沙箱不能只靠拦截SQL改写与语境注入是硬功夫5.1 SQL改写的核心原理与边界表达沙箱拦截式防护在AI Agent场景下不靠谱因为Agent天生会绕。所以真正的实现核心是SQL改写让Agent永远感知不到护栏的存在但它每次查询实际执行的SQL已经变了。衡石的SQL改写基于语法解析而不是字符串拼接。Agent生成的SQL先被解析成抽象语法树语法树上遍历出所有表引用、列引用、聚合函数、子查询和关联条件然后逐节点注入边界约束。这里有一个关键设计边界条件注入的位置要足够深。以行级安全为例如果只注入最外层WHERE子查询里依然可能暴露全量数据。正确的做法是在语法树的每个表节点上都注入对应的行级谓词这样无论Agent怎么写子查询、嵌套多深每一层的数据入口都被过滤过。5.2 绕过的常见手法与对抗我们在红蓝对抗测试中总结出几类绕过手段给大家排雷UNION拼接Agent构造两个查询用UNION合并如果只注入一侧另一侧就泄露。应对对UNION两侧分别注入。子查询别名逃逸在子查询里给表起别名外层引用别名简单字符串改写找不到。应对基于AST的别名解析。BETWEEN/IN模糊匹配不直接查region 华东而是查region NOT IN (华北,华南,西南,西北)逻辑等价但文本完全变形。应对行级谓词注入必须和Agent查询条件做AND合并而不是覆盖或替换。时间函数探测通过日期字段的时间范围反推数据分布判断自己是否被过滤。这个拦截不了但可以通过审计日志监控异常的时间条件模式。函数包含将目标字段包在自定义标量函数里绕过列级匹配。应对函数展开解析剥掉任何包在敏感列外的函数层。对抗绕过的意义不是把每个攻击都拦掉而是提高被绕过的成本。Agent的试探逻辑本质上是收益评估如果每条越权路径都需要大量尝试且大概率失败它的目标规划就会转向安全路径。5.3 结果集过滤兜底无论SQL改写做得多严密都存在一个终极兜底方案结果集过滤。在Agent查询的返回值离开数据源之前沙箱对结果集做最后一层校验。逐行逐列检查是否存在未授权数据对脱敏字段再执行一次掩码对超级行数进行截断对包含未授权维度值的行进行剔除。结果集过滤不建议在所有查询中都开启它有可观的性能损耗。我们的策略是L0和L1查询只做采样检查L2明细查询必须全量过滤L3导出前全量过滤并输出合规报告。也就是说越是数据暴露风险高的动作兜底检查越严格。5.4 临时表与物化视图的权限继承Agent探索时经常要求先算个中间结果后面基于中间结果继续分析。这就涉及到临时表和物化视图。安全坑在于如果Agent在沙箱内创建了一张临时表临时表里的数据是过滤后的但如果Agent绕过沙箱直接创建一张物理表物化后的数据就脱离了预测级管控后续所有查询都绕过了行级过滤。我们的规则是沙箱内一切物化操作产出的新表自动继承创建者的权限边界包括行级谓词和列级脱敏规则。物理表落地后权限继承元数据写入表本身任何后续查询都要重新校验原边界。这条规则实现起来不复杂但必须在存储层做不能靠应用层自觉。6. 上线半年踩过的三个大坑与最终效果6.1 JOIN越权谓词只注入主表漏了关联表第一次红蓝对抗测试安全同事就发现了一个致命口子。Agent查询订单表JOIN客户表订单表有行级过滤客户表当时因为某种原因没有配置权限映射结果整个查询执行时客户表的全量数据通过JOIN间接暴露了。根因是我们的SQL改写器在AST遍历时只给主表注入了行级谓词关联表被忽略了。修复方案是把逐表注入做成强制规则——所有出现在FROM和JOIN中的表必须逐一绑定授权谓词任何一张表没有映射就直接拒绝查询。不要试图在改写器里猜哪些表重要所有表一视同仁。6.2 多轮对话的状态漂移权限快照被缓存第二次事故发生在Agent框架升级之后。Agent开始缓存会话内的权限校验结果第一轮查询校验通过后续几轮直接复用同一份权限快照不重新走沙箱。这个优化的本意是减少延迟结果导致会话中用户任务目标变化后Agent依然用旧快照访问数据。我们的修复是双重的Agent端彻底移除权限快照缓存每次查询请求都必须携带当前会话的上下文身份令牌衡石沙箱端对每个查询请求做全量重校验。性能损失换来了确定性的安全边界。后来实测全量重校验的单查延迟约增加20-35毫秒对Agent多轮探索这个量级完全可接受。6.3 异步任务绕过调度队列里没人管令牌第三个坑最隐蔽。Agent的某个数据导出具象化为一个异步任务压入队列Agent会返回正在处理的提示。问题在于任务调度器在异步执行时压根没检验任务携带的授权令牌是否还有效导致明明会话已中断后台标注任务还是成功执行了。修复分两层任务入队时绑定会话标识和令牌快照任务开始执行前重新校验沙箱边界如果会话已经注销或者令牌过期任务直接进入失败分支同时通知Agent发起方授权已失效请重新申请。异步任务的安全校验不能依赖入队时校验一次执行前校验才是真正的生死线。6.4 效果复盘沙箱上线后我们做了两轮验证。第一轮是红蓝对抗内部安全团队伪装成攻击者故意诱导Agent越权所有攻击路径全部被沙箱拦截或触发告警无一成功。第二轮是灰度观察20个业务Agent并行跑了两个月数据相关的安全事件清零而Agent的查询成功率和探索深度都保持正常。我个人最大的体会是权限沙箱不是给AI Agent戴上镣铐而是给数据世界安装一套交通规则。规则存在的目的不是限制Agent跑而是让所有Agent都知道——这条路可以走、这条路需要申请、这条路禁止通行。边界清晰了自由才是可持续的。如果你正在给团队的AI Agent接入数据平台我的建议是别先想着给Agent多大的权限先想清楚你能接受的边界长什么样边界画好了放手让它探索反而更安心。
返回列表