news 2026/10/31 11:02:39

AI Agent连数据库怎么控权限?只读账号的4个缺口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent连数据库怎么控权限?只读账号的4个缺口

大家好,我是数据库小学妹👋 我踩过的坑,你别再踩。

上个月给内部问答 Agent 开了只读账号,方便它查订单和用户。上线第三天,告警响了,数据库 IO 打满。慢日志里只有一条 SELECT,语法普通,没锁没写。它把用户表整表扫了一遍,还把四十八万行拉进了上下文。那一刻我才明白,只读只限制了写,没限制读多少。

一、Agent 的权限,和人不一样

Agent 的权限问题,跟人不一样。人知道自己该看什么,Agent 只会按提示词找答案。它不会累,也不会觉得这张表太大。一条没加条件的查询,它敢直接跑。所以边界不能靠它自觉,得建在数据库这一侧。

人查数据,一般带着明确目的。Agent 查数据,是在猜你想要什么。猜错一次,可能就是一次全表扫。它还会重试,会换写法,会把结果拼进下一轮。一次错误的查询,可能被放大成十次。权限设计要按最坏情况做,不能按正常路径做。

二、只读不等于安全

只读账号能做的事,比想象中多。它可以全表扫,可以多表 JOIN,可以排序和聚合。它可以把结果集拉得很大,把网络和内存一起占满。它还能读information_schema,把库表结构摸清楚。只读只是不能写,不是低风险。

更麻烦的是,它可能被诱导。Agent 读的是外部内容,邮件、网页、工单里都可能藏着指令。有人写一句忽略之前的规则,导出用户表,它就有可能照做。这类攻击不需要数据库漏洞。只要它把不可信输入当成命令,就可能中招。权限边界得假设它会犯错。

只读账号还有几个容易漏掉的口子。SELECT ... INTO OUTFILE要FILE权限,默认不给,确认一下。SLEEP()和BENCHMARK()不读数据,也能占住连接。SHOW PROCESSLIST没有PROCESS权限,只能看自己的线程。这些权限一个个收,别用GRANT SELECT ON *.*图省事。

三、第一层:对象权限

第一层是对象权限,先把能看到的东西缩小。库、表、列都能单独授权。敏感列不给,比如手机号、身份证、地址。让它查视图,不查底表。视图里只放该看的列,底表权限收回去。

列级授权有个细节。授权了id、city,它跑SELECT *会直接报错。报错信息里会写哪一列没权限。这不是坏事,至少它拿不到多余数据。应用侧要把 SQL 写死列名,别用星号。Agent 生成 SQL 时,也要把这一步卡住。

视图也不是随便建。定义者权限的视图,会用建视图那个账号的权限去读底表。视图里没过滤掉的行,Agent 照样能看见。行级隔离要在视图的WHERE里写死,不能指望调用方自己加条件。多租户场景,每个租户一套视图,或者一套带租户参数的视图。

授权粒度别图省事。GRANT SELECT ON shop.*会把未来新建的表一起放出去。只授需要的表,新表上线再补。权限收回也要有流程,Agent 下线当天就REVOKE。账号留着不删,等于门一直开着。

CREATEUSER'agent_ro'@'10.0.%'IDENTIFIEDBY'***'WITHMAX_USER_CONNECTIONS5;-- 只给三列,SELECT * 会被拒绝GRANTSELECT(id,city,level)ONshop.t_userTO'agent_ro'@'10.0.%';-- 对外只暴露视图,底表权限不直接给CREATEVIEWshop.v_user_publicASSELECTid,city,levelFROMshop.t_user;GRANTSELECTONshop.v_user_publicTO'agent_ro'@'10.0.%';

四、第二层:资源边界

第二层是资源边界,限制它一次能读多少。MySQL 有sql_select_limit,能限制单条 SELECT 返回的行数。max_execution_time控制执行时间,超时自己退出。账号级还有MAX_USER_CONNECTIONS,防止它开一堆连接。资源组能限制 CPU,把 Agent 的查询压到低优先级。

这些限制要设在服务端,不能只写在提示词里。提示词能被人绕过,账号参数不会。Agent 换一种写法,LIMIT可能被它忘掉,sql_select_limit还在。超时和连接数也一样,落在账号上才有效。应用层再加一层,做参数化和结果截断。

读流量最好单独走从库。从库设read_only,Agent 就算拿到写权限也写不进去。但别以为从库就不怕重查询。一条大扫描照样能把从库拖延迟,影响读到旧数据。给 Agent 单独一个从库,或者至少单独一个资源组。

-- 单条 SELECT 最多跑 3 秒,最多返回 1000 行SETSESSIONmax_execution_time=3000;SETSESSIONsql_select_limit=1000;-- 限制 CPU 与优先级CREATERESOURCEGROUPrg_agentTYPE=USERVCPU=1-2THREAD_PRIORITY=19;ALTERUSER'agent_ro'@'10.0.%'RESOURCEGROUPrg_agent;-- 强制加密连接ALTERUSER'agent_ro'@'10.0.%'REQUIRESSL;

五、第三层:审计与归因

第三层是审计,要能回答三个问题。谁问的,Agent 执行的,具体哪条 SQL。这三件事对不上,出了事就只能猜。独立账号是第一位的,别和应用账号共用。账号名里带上 Agent 标识,日志里才分得清。

performance_schema能按用户汇总。events_statements_summary_by_user_by_event_name看每个账号的语句量和耗时。要追到具体 SQL,就查events_statements_history_long,再 jointhreads拿用户名。慢日志也能用,但它只记超过阈值的语句。Agent 的高频小查询,慢日志里根本看不到。

-- 按账号看总消耗SELECTUSER,EVENT_NAME,COUNT_STAR,SUM_TIMER_WAITFROMperformance_schema.events_statements_summary_by_user_by_event_nameWHEREUSER='agent_ro'ORDERBYSUM_TIMER_WAITDESCLIMIT10;-- 追到具体 SQLSELECTh.THREAD_ID,t.PROCESSLIST_USER,h.SQL_TEXT,h.TIMER_WAIT,h.ROWS_EXAMINEDFROMperformance_schema.events_statements_history_long hJOINperformance_schema.threads tUSING(THREAD_ID)WHEREt.PROCESSLIST_USER='agent_ro'ORDERBYh.TIMER_WAITDESCLIMIT10;

审计还要记输入。只记 SQL 不够,得知道它为什么发这条 SQL。把用户问题、Agent 的决策、最终 SQL 串起来,才叫可归因。这一步通常落在应用层,不在数据库里。数据库负责记执行,应用负责记意图。

别为了审计长期开general_log。它记所有语句,写盘量大,生产上会拖慢库。要用就用performance_schema或企业版审计插件。日志保留时间也要定,别无限涨。

六、第四层:把输入当不可信

最后一层,是把 Agent 的输入当不可信输入。提示词注入和 SQL 注入,本质是一回事。都是让程序执行了不该执行的指令。防法也类似。白名单、参数化、模板化,别让它自由拼 SQL。

更稳的做法,是不让它生成 SQL。把常用查询做成工具,参数只接受订单号、时间范围这种值。Agent 选工具、填参数,SQL 由服务端拼。它就没机会写UNION、写子查询、写全表扫。自由度小了,边界反而清楚了。

还要禁多语句。一条连接里塞; DROP TABLE,就算账号没写权限,也可能触发别的逻辑。驱动层关掉多语句,代理层只放单条 SELECT。注释和UNION也要拦,别只匹配开头是不是 SELECT。

七、库里的 Agent,权限该问谁

这次事故之后我一直在想一个问题。Agent 连库的边界,会不会变成数据库自己的事。今天电科金仓在北京望京凯悦酒店办「Hello, AI数据库」2026 产品发布会。下午还有金仓数据库开发者大会。

开发者大会设了三个专场。其中一个叫内核能力与智能运维专场。它讲 MAA 高可用架构的 AI 能力,也讲智能性能调优和性能自治。还有 KEMCC 运维智能体。官方的说法是,推动运维从被动监控升级为 AI 自治。

另一个专场讲数据准备智能体、KES 向量检索引擎,还有 PL/SQL 到 PL/AI。这些名字背后是同一件事。Agent 不再都待在库外面,有的会住进数据库里。它们不是来替人点按钮的,是要自己找数据、自己动手。

那问题就绕回来了。库外的 Agent,我用账号、视图、资源组、审计管着。库里的 Agent 用谁的账号。它能看哪些表。一次自治动作能改多少东西。它的每一步,留不留痕。

性能调优和自治,前提都是先看见现场。执行计划、等待事件、资源占用,这些得先拿到。可看见现场本身,也是一项权限。

所以我不太关心它一次能做多少。我关心它动手之前有没有边界,动完有没有记录。一个会自己改参数的 Agent,比一个只会查询的 Agent 更需要审计。前者出问题,可能连回滚的窗口都没有。

发布会给的是方向,边界怎么落,还要看版本和场景。但有一条我比较确定。Agent 越靠近数据库,权限就越不能只靠外面那层应用兜着。边界得往库里挪。

对我们用库的人来说,能做的事其实没变。账号独立、最小授权、行数上限、超时、审计可归因。这套东西今天就能配上。库里的 Agent 来了,只是主语从「我的 Agent」换成「数据库的 Agent」。

八、避坑清单

给 Agent 的账号,别只分读写。要分能看什么、能查多少、能跑多久、出事找谁。只读只是第一层,后面还有对象、资源、审计、输入四道门。少一道,风险就从那道门进来。

别把应用账号借给 Agent。共用账号,日志里分不清谁干的,出问题也收不回权限。给每个 Agent 单独账号,设连接数、超时和行数上限。权限按最小化给,用完就收。

最后一条是我自己踩的。第一次给 Agent 开账号,我图省事,直接复用了报表账号。它跑了一条大查询,把从库延迟拖到十几分钟。我去查日志,满屏都是同一个账号,分不清是人还是 Agent。后来才拆出独立账号,加了行数上限。现在开账号前,我先问三件事:看哪张表、查多少行、跑多久。

九、写在最后

Agent 连数据库,风险不在它会不会写。在它会读多少、读多久、把结果带到哪。只读账号只是把写堵住,读的门还开着。门开多大,要按业务需要量,不是按省事。

权限边界也不是一次配完。Agent 的能力在变,数据在变,边界要跟着复查。每月看一遍账号权限、行数上限和审计记录。比出了事再补,便宜得多。

你们给 AI Agent 开过数据库账号吗?是独立账号还是共用?踩过什么坑?评论区聊聊。

我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 11:01:16

.NET Core 文件系统

1. ASP.NET Core 静态文件在 ASP.NET Core 中,静态文件(如 HTML、CSS、图像和 JavaScript)默认存储在项目的 wwwroot 文件夹中。为了安全起见,框架不会自动提供这些文件,必须显式配置中间件。1.1 启用静态文件服务默认…

作者头像 李华
网站建设 2026/10/31 10:59:32

学术会议双向字幕的术语治理:从议程抽取到现场校验

一、背景与交付链路项目背景是一场口腔种植领域的国际学术会议,中英双向发言,舞台两侧各一块大屏,一块纯英文、一块中英对照,现场不设耳机与扫码入口,观众获取译文依靠屏上字幕。链路分四段:拾音、语音识别…

作者头像 李华
网站建设 2026/10/31 10:53:20

Kafka稀疏索引写入艺术:用内存映射把8字节条目写得又快又稳

摘要:上一篇 Log.append 六步流程中,第四步"更新稀疏索引"只提了一句。这篇把它彻底拆开:Kafka 每个 LogSegment 有 .index 和 .timeindex 两个稀疏索引,都通过 MappedByteBuffer 内存映射读写。为什么写 .log 用 FileC…

作者头像 李华