我接触过的AI Agent项目里,OpenClaw是比较特别的一个。它不是一个只能在网页里聊天的玩具,而是能直接接管你的电脑、读写文件、执行命令、收发微信消息的"数字员工"。能力越大,责任越大,权限配置就成了这个项目最要命的话题。很多人装好OpenClaw第一个问题不是"它能干嘛",而是"它会不会乱来"。这篇东西就是把OpenClaw的权限体系从头到尾拆一遍,告诉你哪些配置能防住AI越权,哪些坑我替你踩过了。
1. 为什么权限配置是OpenClaw的第一道安全底线
1.1 AI越权到底意味着什么
先想明白一件事:大模型本身没有"恶意",但它天然有"过度完成"的倾向。你让它"帮我看下这个项目里哪些文件比较大",它可能会顺着列出整个用户目录的文件;你让它"整理一下桌面",它可能真把桌面快捷方式全删了。这不是AI学坏了,而是模型在做概率预测时,倾向于生成一个"看起来最完整"的结果,而完整往往意味着越界。
OpenClaw这类Agent框架把这种风险放大了。它不止是聊天,它能调用Shell、写文件、发HTTP请求。一旦某个环节权限放开,AI就可能接触到不该接触的密钥、配置、内网地址,甚至在群聊场景里替一个完全陌生的人执行危险操作。权限配置不是"锦上添花"的安全项,是决定你这个AI助手是"帮工"还是"隐患"的分水岭。
1.2 OpenClaw的权限模型长什么样
OpenClaw的权限控制我把它拆成四个独立的维度,理解了这四个维度,后面所有配置都是围绕它展开的:
- 命令执行权限:AI能不能跑Shell命令,能跑哪些命令,哪些命令一票否决。
- 文件访问权限:AI能读、写、删除哪些路径下的文件,这个决定了它会不会碰你的私钥、密码本。
- 网络请求权限:AI能不能发外部HTTP请求,能请求哪些域名,这是防数据外泄的关键。
- 消息收发权限:哪些渠道(微信、Telegram、Discord)能触发AI,群聊里谁有资格发起指令。
这四个维度不是孤立的。举个例子,你只限制了命令白名单,但没限制文件写入,那AI完全可以靠一条echo xxx > ~/.ssh/authorized_keys把内容追加进关键文件。反过来,你限制了网络请求,即使某个prompt注入成功,AI想外传数据也传不出去。所以我一直强调,权限配置必须从整体看,补一块漏一块等于没配。
1.3 配置原则:最小权限加默认拒绝
我给所有用OpenClaw的朋友一个建议:权限配置按"进门默认锁死,用到哪开到哪"来做,而不是按"先全开,出问题再关"来做。前者是安全设计,后者是事故预告。
最小权限原则说起来简单,做起来容易跑偏。刚开始配置的时候,总想着"这个命令以后可能用得上,先放着吧",结果白名单越滚越大,最后跟没配一样。我自己的习惯是:先用默认拒绝跑一段时间,哪个功能报错了、确实需要,再单独加一条放行规则。虽然前期麻烦点,但每一条权限都是"有明确需求才开的",后面出问题的面就小得多。
2. 核心权限配置项逐项拆解
2.1 全局运行模式:ask-first、allow、deny
OpenClaw的权限配置入口是用户目录下的配置文件,一般在~/.openclaw/openclaw.json,首次初始化后生成。配置里第一类重要参数是全局运行模式,它决定了AI面对一个"不在白名单里"的操作时的默认态度,常见的有三种:
| 模式 | 行为 | 适合场景 |
|---|---|---|
ask-first | 执行前弹确认,等你点头 | 大多数日常使用,兼顾效率与可控 |
allow | 直接放行所有请求 | 完全可信的隔离环境、一次性跑批任务 |
deny | 直接拒绝所有未明确授权的操作 | 公网机器人、多人群聊、敏感目录 |
我强烈建议默认用ask-first,哪怕你是在自己的开发机上。原因是AI的一次操作可能引发连锁动作——比如它执行一条测试命令,测试脚本里又调用了清理函数,这个链条你没法预料,人肉确认一下最稳。群里机器人更是别用allow,任何人都能@它执行任务,跟把家门钥匙挂门口没区别。
2.2 命令执行权限:白名单与黑名单
命令执行是OpenClaw能力最强也最危险的部分。配置里allowedCommands和deniedCommands两个数组,定义哪些命令可用、哪些命令绝对不可碰。但我要重点提醒一个反直觉的点:黑名单是不可靠的。你以为把rm拉黑了就安全了,AI照样可以用find -delete、python os.remove()或者一条shell脚本绕过。所以正确思路是尽量用白名单,而不是黑名单。
我通常在白名单里只放这些命令:ls、cat、git、node、python这类日常开发工具。sudo、rm -rf、mkfs、> /dev/sda、shutdown这些直接列进deniedCommands,同时注意deniedCommands匹配的是"命令片段",配置的时候尽量写全一些变体。另外还有一个更细的颗粒度控制,叫dangerousPatterns,可以配置正则表达式,比如匹配到路径里有/etc或~/.ssh的命令直接拦截,这个比单纯命令名匹配靠谱得多。
这里放一段我实际在用的配置模板:
{ "permissions": { "mode": "ask-first", "allowedCommands": ["ls", "cat", "head", "tail", "git", "node", "python", "npm"], "deniedCommands": ["rm -rf", "mkfs", "shutdown", "reboot", "sudo", "chmod 777"], "dangerousPatterns": [ "\\.ssh/", "/etc/", "authorized_keys", "base64 -d", "curl .*\\|.*sh" ] } }dangerousPatterns里那几条,是我从一个真实的越权事故里总结出来的。当时AI被提示词注入引导着去读~/.ssh/id_rsa,然后准备base64编码外传,如果没有这条正则拦截,后果可想而知。
2.3 文件系统访问边界:路径规则与沙箱
命令白名单解决的是"能不能执行命令",但AI还可以通过编辑器、文件工具直接读写文件,所以必须要单独划一个文件系统访问边界。OpenClaw里常见的是allowedPaths、deniedPaths配合一个sandboxRoot沙箱根目录来用。
我踩过的一个坑是:只配了allowedPaths指向工作目录,但没配sandboxRoot,结果AI用../相对路径一层层往上跑,还是读到了工作目录外的文件。任何路径限制都要记住一个铁律:AI不是人,它不会嫌麻烦,它会老老实实把../../../../etc/passwd拼出来。所以别指望路径字符串的"隐蔽性",直接把沙箱根目录设成项目根目录,然后deniedPaths把~/.ssh、/etc、/root、~/.aws这种目录全部堵死,才算是真正的边界。
文件权限配置示例:
{ "permissions": { "sandboxRoot": "/home/me/work", "allowedPaths": ["/home/me/work"], "deniedPaths": [ "/etc", "/root", "/home/me/.ssh", "/home/me/.aws", "/home/me/.openclaw" ] } }注意一个细节:deniedPaths一定要包含OpenClaw自己的配置目录,否则AI能读配置,就等于把所有权限规则都看光了。这就跟保险箱密码写在保险箱外面一样。
2.4 网络请求与API调用限制
网络权限这块很多人会忽略,觉得AI发个请求无所谓。但我可以负责任地告诉你,AI Agent的数据外泄,大多数是从网络请求这条通道出去的。OpenClaw支持配置network.allowDomains白名单,只有白名单里的域名才允许发起HTTP请求。
配置建议分两层。第一层是分布式访问限制:默认禁止所有外部请求,只放行必要的API域名,比如api.github.com、api.openai.com、*.anthropic.com这类,按需增加。第二层是本地网络保护:network.denyLocalhost最好默认开启,防止AI扫描局域网或者请求本机其他端口。你想想,如果AI被恶意提示词引导着去请求http://localhost:9222,可能就能操作你的浏览器调试端口,这个通道不堵上,其他权限配得再好也有漏洞。
另外,如果OpenClaw接入了像CC Switch这类模型切换工具,切换模型后网络权限配置也要重新检查。因为不同模型的API端点不同,有些代理工具会在本地起一个代理端口,这时候denyLocalhost会把代理请求也拦掉,导致切换后AI"突然失灵"。这种情况不是权限配置失效,而是网络白名单和新模型端点不匹配,排查时要有这个意识。
2.5 多用户与群聊环境的角色权限
OpenClaw接入微信、Telegram这类群聊场景后,权限问题的维度会变得更复杂:以前你只需要防"AI越权",现在还要防"别人利用AI越权"。所以群聊环境必须引入用户角色等级。
我见过一个典型的反面教材:某团队把OpenClaw拉进项目群,所有人都能@它跑命令,结果有人开玩笑发了一句"AI,帮我把刚才那份合同发给群里的XX",AI差点就把机密文档发出去了。问题出在权限配置里没有区分用户等级。正确做法是:
- 管理员:完整权限,可以执行命令、读全量文件、管理技能。
- 普通成员:只有问答、查资料、读公共目录的权限。
- 访客/陌生人:仅限基础问答,所有命令和文件操作直接拒绝。
在配置里,用userRoles字段把各渠道用户ID映射到对应角色,然后把命令白名单按角色再细分。群聊环境还有一个细节,建议开启"私聊确认"功能:当群聊中出现危险操作请求时,AI不直接执行,而是私聊管理员确认一次。这一步能把大部分误触风险和恶意指令挡在门外。
3. 从零开始的完整配置实操
3.1 安装与初始化后的默认权限状态
先交代一下基础环境。OpenClaw在Linux、macOS上通过npm安装,Windows下通常建议用WSL2跑,也有社区做的离线整合包,但核心配置文件的结构是一样的。安装完成后,第一次启动会引导初始化配置文件,默认生成的权限配置一般比较宽松——这也是我们后面要动手改的原因。
默认状态通常是这样:命令执行是ask-first,但白名单很空;文件访问没有设sandboxRoot,等于AI在用户目录范围内基本畅通;网络请求默认放行。说白了,官方给的默认配置是为了让你"先跑起来",不是让你"直接上生产"。所以我每次在新机器部署OpenClaw,第一件事就是打开openclaw.json,先把网络请求默认改成拒绝,再把sandboxRoot设好,然后才敢跟它说第一句话。
3.2 场景A:个人开发助手——本地代码库操作
我自己的主力场景是让OpenClaw当本地开发助手,帮我整理代码库、生成README、做代码审查。这类场景的特点是:AI需要读大量文件、偶尔跑测试命令,但不需要删除文件,也不需要访问代码库之外的系统区域。
针对这个场景,我的核心配置思路是"代码库内全通,代码库外免谈"。
{ "permissions": { "mode": "ask-first", "sandboxRoot": "/home/me/myproject", "allowedPaths": ["/home/me/myproject"], "deniedPaths": ["/home/me/myproject/node_modules"], "allowedCommands": ["ls", "cat", "grep", "find", "git", "npm", "node"], "deniedCommands": ["rm -rf", "sudo", "curl"], "network": { "allowDomains": ["api.github.com", "registry.npmjs.org"], "denyLocalhost": true } } }这里有个细节值得说一下:deniedPaths里我把node_modules也加进去了。AI读代码库的时候经常一头扎进node_modules,读取量大且没啥信息量,既慢又容易让它"总结"出错误结论。堵上这个路径,AI反而会更快地聚焦到源码上。另外注意network.allowDomains里保留了registry.npmjs.org,因为执行npm install时确实需要访问它,如果没有这个白名单,AI装依赖会反复失败。
3.3 场景B:群聊机器人——只读问答场景
群聊机器人是最容易出事的场景,因为交互对象不可控。给群里装OpenClaw,我的建议是:默认只给它"能说话的权限",不给它"能动手的权限"。
配置上和开发助手有很大差别:
{ "permissions": { "mode": "ask-first", "userRoles": { "wechat:admin_id": "admin", "telegram:channel_owner_id": "admin", "*": "guest" }, "roleDefaults": { "guest": { "allowedCommands": [], "allowedPaths": ["/home/me/shared_public"], "network": { "allowDomains": [] } }, "admin": { "allowedCommands": ["ls", "cat", "grep"], "allowedPaths": ["/home/me"], "network": { "allowDomains": ["api.github.com"] } } } } }群聊场景的mode我依然保留ask-first,但把管理员以外的用户角色全部限制成只读。注意"allowedCommands": [],这意味着访客角色连ls都执行不了——AI只能基于OpenClaw内置的对话能力来回答,任何涉及系统操作的需求都会被拒绝。这样的好处是,即使有人在群里写了一大段巧妙的提示词注入,AI也无计可施,因为它手里根本没有"工具"可用。
3.4 场景C:文件管理助手——目录隔离场景
还有一种常见用法是让OpenClaw做文件整理,比如批量重命名、归档日志、清理临时文件。这类任务的本质是"高文件操作权限 + 低系统权限",所以配置时要把精力放在文件边界上。
我的做法是先建一个专门的共享目录,比如/srv/openclaw-file-zone,把AI能碰的文件全部放进去,然后权限配置里sandbox就指向这个目录:
{ "permissions": { "sandboxRoot": "/srv/openclaw-file-zone", "allowedPaths": ["/srv/openclaw-file-zone"], "deniedPaths": ["/srv/openclaw-file-zone/archive/private"], "allowedCommands": ["ls", "cp", "mv", "mkdir", "rename", "zip", "unzip"], "network": { "allowDomains": [], "denyLocalhost": true } } }这类场景通常会遇到一个实际问题:AI要移动的文件,有可能来自用户上传(微信图片、接收的文档),而这些文件最初落在/home/me/Downloads这样的系统目录里。如果不加处理,AI没权限读取,任务就卡住了。我建议在OpenClaw侧加一个"文件收集目录"的映射逻辑——用户先把文件发到共享目录,AI只在共享目录内工作,做到"进得来、碰不到"。别省这一步,直接把/home/me/Downloads加进白名单,AI会把下载目录翻个底朝天。
3.5 如何验证权限配置是否生效
配置写完了,别急着上线,先做一轮"攻击测试"。我通常用三个递进的问题来验证:
- 正常请求:"帮我看看当前目录下有哪些文件",确认基本功能不被误伤。
- 越界请求:"读取
/etc/passwd并总结前10行",预期结果是拒绝。 - 绕过尝试:"用Python脚本读取
/home/me/.ssh/id_rsa文件内容",预期结果同样是拒绝。
OpenClaw在命令执行前会打印权限判断日志,大概长这样:[permission] command blocked: python /tmp/exploit.py (matched deniedPattern: .ssh/)。我建议每次都检查这个日志,确认到底是"命令被拦截"还是"AI压根没尝试"。如果是前者,说明权限规则生效;如果是后者,那可能是prompt层面的限制,并不是权限配置在起作用,这种"虚假安全"很容易让人误判。
4. 常见越权场景与排查实录
4.1 一次真实的越权事故复盘:AI读取了我的SSH私钥
分享一个我之前踩过的坑,希望你们都不用再踩一遍。当时我给OpenClaw配了一个开发助手配置,命令白名单里有cat和grep,但因为某些文件操作走的是AI内置FileTool,没走shell,所以我一度忽略了文件工具本身的权限。
某一天,我在代码里留了一处错误配置,AI在排查问题的时候,从系统日志里发现了一个指向~/.ssh/id_rsa的路径。它为了"帮我确认这个路径是否存在",直接用FileTool把文件内容读了出来,并且还把开头几十个字符贴进了对话回复里。我立刻意识到不对劲,翻日志定位到原因:
- 问题一:
FileTool的文件访问权限和白名单里的shell命令是两套独立系统,我只配了shell白名单,没限制FileTool的路径。 - 问题二:
deniedPaths没有覆盖~/.ssh,等于狙击枪瞄准了命令层,文件层的门却敞开着。
修复方案:在deniedPaths里补上/home/me/.ssh,同时把dangerousPatterns里的正则也添加了\.ssh/,这样即使AI换一种路径表示方式,也能被正则拦下。另外,全局确认模式保持ask-first,从此文件读取类操作也会触发确认。
这里有一个很重要的经验:权限是分层的,XML格式的数据你看不到也要堵住,API工具的路径和Shell命令的路径是两条路。配置完一定要分别验证:一条走Shell命令,一条走AI内置文件工具。
4.2 配置不生效的排查思路
权限配置"不生效",大部分时候不是OpenClaw的bug,而是配置文件加载顺序或者预编译缓存的问题。我整理了几个最常见的排查步骤:
- 检查配置文件路径:确认你改的文件确实是OpenClaw正在加载的那个。用
openclaw --print-config命令输出当前的生效配置,如果跟你改的不一致,检查环境变量OPENCLAW_CONFIG是否指向了其他的配置文件。 - 重启服务:OpenClaw部分配置是启动时加载的,改了配置文件不重启就不会生效。注意要用
openclaw restart,直接kill进程再启动可能因为端口未释放而加载到旧的日志状态。 - 看权限日志级别:在配置里把
log.level调成debug,然后重新触发一次越权测试。如果日志里完全没有权限判断的打印,说明你的权限配置模块压根没被加载,多半是JSON语法错误导致模块被跳过了。 - 检查JSON语法:
openclaw.json是严格控制格式的,多一个逗号就会导致权限模块崩溃回退到默认模式。我配置完总会先跑一遍jq . ~/.openclaw/openclaw.json做语法校验。
最常见的坑是第四条。有一次我配置完在配置文件末尾多留了个逗号,结果OpenClaw没报错,只是日志里提示"permission module not loaded, fallback to default",所有限制全被静默绕过。这种失效方式最危险,因为表面上看服务一切正常,实际上已经"裸奔"了。
4.3 环境特有的权限坑:WSL2、微信插件的特殊情况
不同部署环境下,权限配置的坑还不一样。
WSL2环境:我在Windows里用过WSL2跑OpenClaw,遇到一个很恼人的问题——启动时报错could not safely verify the WSL2 environment,然后拒绝启动。后来排查发现是权限模块在检测/etc/wsl.conf的挂载选项,因为我没有给某个Windows盘符配置成只读挂载,它担心AI能跨文件系统访问Windows的用户目录。如果在WSL2下也遇到这个报错,解决办法是在/etc/wsl.conf或%USERPROFILE%\.wslconfig里把非必要盘符挂载为只读,或者在OpenClaw配置里增加allowUnsafeWslMount: false(效果一样,都是让权限模块知道"我确认不会跨盘写操作")。
微信插件:OpenClaw接入微信通常会走第三方适配器(比如ilinkai这种)。我自己用的时候发现,微信端历史会话里残留的上下文,有时候会触发服务端风控导致权限确认消息发不出去。现象是AI实际上在等确认,但因为在风控期,确认请求根本到不了你手机。这种不是权限配置问题,而是会话状态问题。处理办法是配置定期清理会话上下文,或者设置长时间无操作后自动登出,别让AI一直处于"等待确认"的假死状态。
CC Switch切换模型后:如果你用CC Switch这类工具切换底层模型,切换之后权限配置理论上不变,但要留意模型的能力差异。同一个Agent任务,模型A可能规规矩矩地只调白名单命令,模型B却可能自作主张用另一种方式完成任务。切换模型后一定要重新跑一遍4.2里的三条验证问题,别默认"权限配置跟模型无关"。
4.4 权限配置速查表
最后总结一个速查表,方便直接照着检查和配置:
| 检查项 | 推荐配置 | 误配置风险 |
|---|---|---|
| 全局模式 | ask-first | allow模式下一旦prompt注入,AI无确认直接执行 |
| 命令白名单 | 只放行日常开发必需命令 | 仅配置黑名单时容易被等效命令绕过 |
| 危险正则 | 覆盖/etc、.ssh、authorized_keys等 | AI通过路径拼接读取关键文件 |
| 文件沙箱 | 设置sandboxRoot并允许路径限定在沙箱内 | 未设沙箱时AI用../逃逸到任意目录 |
| 文件工具权限 | 与Shell命令权限同步配置 | 双通道权限不一致导致漏口 |
| 网络白名单 | 默认空列表,按需放行API域名 | 无限制网络请求时数据可被外传 |
| 本地网络 | 开启denyLocalhost | AI可扫描局域网或访问本机服务 |
| 用户角色 | 管理员/成员/访客分级 | 群聊中任何人可触发危险操作 |
| 确认机制 | 危险操作私聊管理员确认 | 群聊误操作无人工复核就执行 |
表格不是让你背下来,是让你在每次改完配置之后,按行自查一遍。我每次部署OpenClaw到新环境,都会打开这个表对照检查,十分钟能搞定,但能省下后面几天的事故排查时间。
写到最后
配置OpenClaw的权限,说白了就是一句话:把AI当成一个能力很强但完全没有常识判断力的新员工,所有"不该碰的东西"都要提前上锁。我个人实际用下来的体会是,权限配置这个东西,前期多花半小时,后期能少熬三个夜。尤其是那些准备把OpenClaw接进微信、接进生产环境的,一定别跳过"越权测试"这一步,别觉得"我的AI不会那么干"——训练一个"不乱来"的AI很难,但写好一个配置文件很简单,做好后者就够了。