1. 从一次“查目录被拒”说起:OpenClaw exec tools 文件权限配置到底卡在哪
个人游戏笔记本上跑 OpenClaw,最让人心里发毛的不是模型答得慢,而是它到底能碰你硬盘上的哪些东西。我在 Win10 + WSL2 + Ubuntu 这套环境里装完 OpenClaw 2026.3.13 之后,第一件想验证的事就是:让它看一眼/mnt/e/WSL目录,会不会顺手把我 Windows 盘里的文件给动了。结果很有意思——没开 exec 工具时,它绕了一圈,最后只返回自己工作区/home/hello/.openclaw/workspace的文件列表;一旦我在控制台把 exec 工具授权打开,再问同样的问题,它直接回我“无法查看 /mnt/e/WSL 目录的文件”,理由是 SOUL.md 里的边界规则和权限限制。
这个反差恰好说明 OpenClaw 的 exec tools 文件权限配置是两层东西在同时起作用:一层是 Ubuntu 系统本身的用户/用户组权限,另一层是 OpenClaw 自己的 exec 安全策略(host、审批、allowlist)。很多人只调了其中一层,就会出现“明明授权了却跑不动”或者“以为很安全其实能乱跑”的情况。这篇就按我自己的机器,把 settings 改到 TaoToken 统一 Key/API 通道,再把 exec tools 的权限白名单和验证动作一步步走完,目标是在不暴露敏感路径的前提下,跑通一次受控执行。
先说清楚这套东西适合谁:如果你也是个人游戏本,用 WSL2 装 Ubuntu 跑 OpenClaw,想让 AI 帮你执行一些 shell 命令(比如查日志、跑脚本、看目录),但又不想让它碰/mnt/c、/mnt/d这些 Windows 盘,那这篇的配置路径就是给你准备的。核心检索词就三个:OpenClaw、exec tools、文件权限配置。下面所有命令和 JSON 片段都可以直接复制,路径按你自己的用户名替换即可。
我先把结论摆前面,省得你踩我踩过的坑:exec 能不能执行、能执行什么,取决于exec.security(deny / allowlist / full)、exec.ask(off / on-miss / always)、askFallback三者叠加,再加上按智能体配置的 allowlist。而“能不能访问某个目录”则取决于运行 exec 的那个系统用户有没有该目录的权限。这两件事必须分开配,混在一起调只会越调越乱。
2. 前置:把 settings 统一改到 TaoToken 的 Key/API 通道
在动 exec 权限之前,我建议先把模型调用这条链路收口。原因很实际:exec 工具一旦放开,OpenClaw 会频繁发起模型请求来决定“这条命令要不要跑、怎么跑”,如果 Key 散落在多个配置文件里,排查问题时你根本分不清是权限拦住了还是凭证失效了。把 settings 统一改到 TaoToken 的 API 通道,好处是只有一个 Base URL、一个 Key、一个 Model ID 需要维护。
TaoToken 的 API 地址是https://taotoken.net/api,官网入口在https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。注意 API 地址后面不加任何 UTM 参数,直接就是/api,这点在填 Base URL 时别画蛇添足。
OpenClaw 的模型配置我放在~/.openclaw/openclaw.json里,用 JSON 结构管理。下面是我实际在用的片段,你可以直接抄,把sk-开头的 Key 换成你自己的:
{ "models": { "providers": { "taotoken": { "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoToken密钥", "api": "openai-completions", "models": [ { "id": "claude-sonnet-4-5", "name": "Claude Sonnet 4.5", "contextWindow": 200000, "maxTokens": 8192 } ] } }, "default": "taotoken/claude-sonnet-4-5" } }这里三个字段必须成对出现,缺一个都会报错:Base URL 是https://taotoken.net/api,Key 是你在控制台生成的sk-开头字符串,Model ID 是taotoken/claude-sonnet-4-5这种“provider/model”格式。我试过只填 baseUrl 不填 api 字段,OpenClaw 会默认按 OpenAI 兼容协议走,大部分情况没问题,但显式写上openai-completions更稳。
如果你用的是 Claude Code 那套配置习惯,对应的 settings 片段是这样,路径在~/.claude/settings.json:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的TaoToken密钥", "ANTHROPIC_MODEL": "claude-sonnet-4-5" } }Codex 用户则在~/.codex/auth.json里配:
{ "OPENAI_BASE_URL": "https://taotoken.net/api", "OPENAI_API_KEY": "sk-你的TaoToken密钥" }三件套永远是 Base URL + Key + Model ID,不管哪个客户端都一样。把这条链路收口之后,后面 exec 出问题,你就能确定不是凭证在捣乱。生成 Key 的入口在控制台的 API Keys 页面,接入细节可以对照接入文档,模型能力验证用模型对话页面,长期跑编码和 Agent 任务则看 Coding Plan。
注意:
~/.openclaw/目录存的是配置、凭证和会话,官方明确说它和~/.openclaw/workspace是分开的。前者别随便暴露,后者才是工具的工作目录。
3. 可复制配置:exec tools 权限白名单与 settings 片段
现在进入正题。OpenClaw 的 exec 工具配置在控制台的“AI与代理” → “Tools” → “Exec Tool”里,但真正落地的是~/.openclaw/exec-approvals.json这个文件。审批信息存储在执行主机上的本地 JSON 文件里,路径就是~/.openclaw/exec-approvals.json。我先把 host 选型说清楚,因为它决定了后面审批怎么走。
host有三个值:sandbox、gateway、node。sandbox 需要装 Docker,隔离性最好;我没装 Docker,所以选的是gateway,也就是在主机上直接跑。gateway 方式的安全主要靠 Ubuntu 的用户权限管理,或者 AppArmor 做资源隔离。这里有个坑要提醒:如果沙箱隔离默认关闭,host=sandbox会直接在 Gateway 网关主机上运行(无容器)且不需要审批。也就是说你以为选了沙箱很安全,实际上没装 Docker 时它退化成主机执行还不问你。要审批,就得用host=gateway并配置 exec 审批。
我的exec-approvals.json实际内容长这样,你可以按需改:
{ "version": 1, "defaults": { "security": "allowlist", "ask": "on-miss", "askFallback": "deny" }, "agents": { "main": { "security": "allowlist", "ask": "on-miss", "askFallback": "deny", "allowlist": [ "/usr/bin/uptime", "/usr/bin/df", "/usr/bin/free", "/bin/ls", "/usr/bin/du", "~/Projects/**/bin/rg" ] } } }三个策略字段的含义必须记牢。security里deny阻止所有主机执行请求,allowlist仅允许列表中的命令,full允许所有命令(等同提权模式)。ask里off从不提示,on-miss仅在允许列表未匹配时提示,always每次命令都提示。askFallback是“需要提示但无法访问 UI”时的兜底:deny阻止,allowlist仅在匹配时允许,full允许。
我选allowlist + on-miss + deny这套组合的逻辑是:白名单里的命令直接跑,不在白名单的弹审批,如果审批界面连不上就默认拒绝。这样既不会每次查个磁盘都弹窗,又不会在 UI 掉线时被偷偷执行命令。
allowlist 是按智能体配置的,模式匹配不区分大小写,而且模式应解析为二进制路径——只写基本名称的条目会被忽略。也就是说你写ls没用,得写/bin/ls。配置命令有三条:
# 获取当前 allowlist openclaw approvals get --gateway # 用文件整体替换 allowlist openclaw approvals set --file ./exec-approvals.json # 新增单条 openclaw approvals allowlist add --agent main --gateway "/usr/bin/uptime" # 删除单条 openclaw approvals allowlist remove "~/Projects/**/bin/rg"我实测下来,openclaw approvals allowlist add --agent main --gateway "/usr/bin/uptime"这条命令会在 JSON 里给 main 智能体单独建一个节点。如果你有多个智能体,切换编辑对象时要留意,别把 A 的白名单配到 B 头上。
提示:
~/.openclaw/workspace是默认的当前工作目录,但不是严格沙箱。工具会相对于工作区解析相对路径,但如果没启用沙箱,绝对路径仍可能访问主机上的其他位置。需要隔离就用agents.defaults.sandbox。
4. 验证请求:跑通一次受控执行并确认结果
配置写完不验证等于没配。我按“先看权限、再跑命令、最后试越界”三步来验。
第一步,确认系统用户和组的关系。执行cat /etc/passwd能看到两个关键用户:hello:x:1000:1000:,,,:/home/hello:/bin/bash和ollama:x:999:989::/usr/share/ollama:/bin/false。ollama 是官方安装程序自动创建的系统服务用户,UID 999、GID 989,主目录/usr/share/ollama,登录 Shell 是/bin/false,禁止交互式登录。这是最小权限原则的体现:Ollama 服务只能访问它需要的资源,即使被攻击,攻击者也只能以低权限运行。
再用id命令看组归属:
$ id ollama uid=999(ollama) gid=989(ollama) groups=989(ollama),44(video),992(render) $ id hello uid=1000(hello) gid=1000(hello) groups=1000(hello),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),989(ollama)关键点在这:hello用户同时在sudo、users和ollama组里,所以它能访问 Ubuntu 系统文件,也能访问 ollama 相关文件。而 ollama 用户没有/mnt/c、/mnt/d这些 Windows 盘的权限。这意味着即使 exec 以 ollama 身份跑,也动不了你的 Windows 文件;但 hello 用户是有这个权限的,所以 exec 的 host 和审批策略才是真正的闸门。
第二步,在对话框里运行/exec查看当前参数,确认 security、ask、askFallback 和你写进 JSON 的一致。然后跑一条白名单内的命令,比如/usr/bin/uptime,应该直接返回结果不弹审批。
第三步,故意试一条越界命令,比如让它读/mnt/e/WSL目录。我实测返回的是:
我无法查看 /mnt/e/WSL 目录的文件。原因: 安全限制 边界规则:根据 SOUL.md 的边界规则,私人文件和共享的敏感信息必须保持隐私 权限限制:我无法访问外部系统或共享路径这说明 exec 工具没有权限访问/mnt/c、/mnt/d等 Windows 系统文件夹。到这里,一次受控执行就算跑通了:白名单命令能跑,越界路径被拦,审批兜底是 deny。
如果你要验证模型通道是否也通了,可以在模型对话页面发一条简单请求,确认返回正常,排除是 Key 或 Base URL 的问题。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
配这套东西最容易撞的几个报错,我按真实遇到的整理一下。
401 Unauthorized:九成是 Key 或 Base URL 的问题。先确认~/.openclaw/openclaw.json里的baseUrl是https://taotoken.net/api,注意结尾没有多余斜杠,也没带 UTM 参数。再确认apiKey是sk-开头且没被截断。如果用的是 Claude Code 的 settings,检查ANTHROPIC_AUTH_TOKEN和ANTHROPIC_BASE_URL是否成对。三件套里任何一个写错都会 401。
local proxy failed:这个通常出现在你本地有代理类工具残留配置时。检查环境变量里有没有HTTP_PROXY、HTTPS_PROXY指向本地端口,有的话清掉再试。OpenClaw 走的是直连 API,不需要中间层。
reading choices 报错:一般是模型返回结构不符合预期,常见于 Model ID 填错或 provider 的api字段没写。确认api是openai-completions,Model ID 是taotoken/claude-sonnet-4-5这种带 provider 前缀的格式。如果只写claude-sonnet-4-5,OpenClaw 找不到对应 provider 就会在解析 choices 时炸掉。
OAuth 相关报错:如果你之前用 OAuth 方式登录过某个客户端,残留的 token 可能和现在的 Key 冲突。清掉旧的凭证缓存,统一走 API Key 通道。Codex 用户检查~/.codex/auth.json里是不是还留着旧的 OAuth 字段。
exec 授权了却跑不动:先openclaw approvals get --gateway看 allowlist 里到底有没有那条命令,注意必须是完整二进制路径,ls这种基本名会被忽略。再看exec.security是不是deny,deny会阻止所有主机执行请求,白名单再全也没用。
审批一直超时:ask设成always时每条命令都弹窗,如果 Control UI 没开着就会走到askFallback。我把 fallback 设成deny,所以超时即拒绝。想省事就把ask改成on-miss。
排障时优先看 API Keys 和接入文档,确认凭证和地址无误;模型行为异常去模型对话页面单独验证;如果是长期跑编码或 Agent 任务出的问题,对照 Coding Plan 的配置说明检查。
6. 把 Key 和权限收口到一处,后续才好维护
走到这里,你应该已经能在个人游戏本上跑通一次受控执行了:settings 统一指向 TaoToken 的https://taotoken.net/api,exec tools 的 host 选 gateway,security 用 allowlist,ask 用 on-miss,askFallback 用 deny,白名单里只放完整二进制路径。这套组合的好处是权限边界清晰——ollama 用户碰不到 Windows 盘,hello 用户的越界访问被 SOUL.md 边界规则和 allowlist 双重拦住。
最后留一个我还没完全解决的问题,也给后续文章埋个引子:目前 OpenClaw 还不能调用任何 skills,虽然内置了 skills。运行openclaw skills list能看到 weather 技能显示 ready,但问它武汉天气却查不出来。我怀疑两个原因,一是 workspace 里 SOUL.md、IDENTITY.md、USER.md、TOOLS.md 还是初始配置,人格和权限没打通;二是文件访问权限问题,ollama 用户只能访问~/.openclaw/workspace/,访问不到~/.openclaw/workspace/skills。这个坑等我理清了再写。你要是也卡在这,可以先检查这两个方向。