#龙虾安全详细配置

1 messages · Page 1 of 1 (latest)

celest breach
#

我用的是2026.3.8版本的openclaw,用于企业公共环境,我希望能让它写技能、调任何技能、操作自己的工作目录下的文件,不允许查看涉及安全的敏感文件,不允许删除系统文件,请提供一个满足这个需求的详细配置

hoary auroraBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

sterile craterBOT
#

下面给你一套偏“企业公共环境”安全基线openclaw.json(JSON5)示例,目标对应你说的 4 点:

  1. 能写技能(允许在 workspace 下写入 skills/**/SKILL.md
  2. 能调用技能(技能会被加载,但仍受“工具权限”限制——技能里用到被禁的工具就会被拦)
  3. 只能操作自己的工作目录文件(开启 tools.fs.workspaceOnly: true + 全量沙箱)
  4. 不能看敏感文件、不能删除系统文件(沙箱 + 只读 rootfs + 禁用 exec/apply_patch

相关文档(建议对照看):


1) 推荐“公共环境”安全基线配置(单 agent)

#

把下面内容放到 ~/.openclaw/openclaw.json(或你的 $OPENCLAW_STATE_DIR/openclaw.json):

{
  // 1) Gateway 不要裸奔:绑定 + 强认证
  gateway: {
    mode: "local",
    bind: "loopback",
    auth: {
      mode: "token",
      token: "REPLACE_WITH_LONG_RANDOM_TOKEN" // 例如 openssl rand -hex 32
    }
  },

  // 2) 会话隔离:公共环境最怕串上下文
  session: {
#
    scope: "per-sender",
    dmScope: "per-channel-peer",
    resetByType: {
      direct: { mode: "idle", idleMinutes: 240 },
      group:  { mode: "idle", idleMinutes: 120 },
      thread: { mode: "daily", atHour: 4 }
    }
  },

  // 3) Agent 工作区:建议用“干净目录”,不要把任何机密塞进 workspace
  agents: {
    defaults: {
      // 你要“只能操作自己的工作目录”——这个就是边界
      workspace: "~/.openclaw/workspace-public",
#
      // 4) 强烈建议:工具全走 Docker 沙箱
      sandbox: {
        mode: "all",          // 所有会话都在沙箱里跑工具
        scope: "session",     // 更隔离(想省资源可用 "agent")
        workspaceAccess: "rw",// 允许在 workspace 内读写(为了写技能/文件)
        docker: {
          image: "openclaw-sandbox:bookworm-slim",
          network: "none",      // 默认禁网:降低数据外传风险(需要联网再改)
          readOnlyRoot: true,   // 沙箱“系统文件”只读,基本杜绝删系统文件
          capDrop: ["ALL"],
          tmpfs: ["/tmp", "/var/tmp", "/run"],
          pidsLimit: 256,
          memory: "1g",
          cpus: 1
        }
#
      }
    }
  },

  // 5) 工具权限(最关键)
  tools: {
    // 只允许文件读写三件套;不允许 exec / apply_patch(防删除、防任意命令)
    allow: ["read", "write", "edit", "session_status"],
    deny: [
      "apply_patch",
      "exec",
      "process",
      "browser",
      "canvas",
      "nodes",
#
      "cron",
      "gateway",
      "sessions_spawn",
      "sessions_send"
    ],

    // 只允许访问 workspace 内路径(阻止读 ~/.openclaw/openclaw.json、~/.ssh、/etc 等)
    fs: { workspaceOnly: true },

    // 双保险:就算误放开 exec,也让它默认 deny
    exec: { security: "deny", ask: "always" },

    // 禁止“沙箱逃逸到宿主机 exec”的逃生门
    elevated: { enabled: false }
  },
#

  // 6) (可选但强烈建议)如果你跑在 Discord 公共频道:至少开启 requireMention
  channels: {
    discord: {
      groupPolicy: "allowlist",
      // 防止群里任何人随便改配置(/config set 等)
      configWrites: false,

      // 只示例一个 guild;按你实际 server id 填
      guilds: {
        "YOUR_GUILD_ID": {
          requireMention: true,
          // 如果你希望“只有部分员工能和它对话”,再加 users/roles allowlist
          // users: ["USER_ID_1", "USER_ID_2"],
          // roles: ["ROLE_ID_1"],
#

          // 不写 channels 表示该 guild 下所有频道都允许(但仍需 @ 提及)
          // 如果你要更严格,就显式列出允许的频道:
          // channels: { "CHANNEL_ID": { allow: true, requireMention: true } }
        }
      }
    }
  }
}

2) 这份配置如何满足你的需求

A. “写技能 / 调技能”

#
  • 你让 agent 写技能,本质就是:允许它在 workspace 下写文件
    例如写到:<workspace>/skills/my-skill/SKILL.md
  • OpenClaw 的技能加载优先级是:<workspace>/skills~/.openclaw/skills → 内置技能 → skills.load.extraDirs
    所以放到 workspace 最直观、也最符合“只操作自己工作目录”。

注意:“调任何技能”不等于“技能能做任何事”。技能能否成功执行,取决于技能里用到的工具是否在 tools.allow 里(比如有的技能需要 browserexec,你这里是禁掉的)。

B. “只能操作自己的工作目录文件”

  • tools.fs.workspaceOnly: true 会把 read/write/edit/apply_patch 的路径限制在 workspace 内(这条很关键)。
  • 同时你把工具放进 Docker 沙箱里跑:就算模型尝试搞绝对路径/路径穿越,整体可控性也高得多。

C. “不允许查看敏感文件”

  • 这套配置的核心思路是:敏感文件不要放进 workspace
  • 再通过 tools.fs.workspaceOnly 防止它去读 ~/.openclaw/*~/.ssh/*/etc/* 等。

D. “不允许删除系统文件”

  • 你禁了 execapply_patch,基本断掉了“删除系统文件”的直接通道。
#
  • 并且沙箱 readOnlyRoot: true,容器内部的系统目录也不可写(双保险)。

3) 部署后自检(建议你必须跑)

在机器上跑:

  • openclaw security audit --deep(会提示是否“开放群 + fs/runtime 工具”等高危组合)
  • openclaw sandbox explain(确认当前会话/agent 是否真的在沙箱里、工具策略是否生效)

(文档也在 Security/Sandboxing 里有提到这些命令)


4) 一个重要现实:公共环境的“多租户隔离”不是 OpenClaw 的目标模型

如果你的“企业公共环境”是互不信任的多人/外部用户都能对话,那请认真考虑拆 trust boundary(单独 gateway/单独 OS 用户/单独凭据),否则再怎么配工具权限也只能“降低风险”,不能当成强隔离的多租户平台用(Security 文档里明确讲了这一点)。

#

如果你告诉我:你是主要跑 Discord 还是 Slack/Telegram,以及“用户是否需要联网(web_fetch/web_search)”,我可以把上面配置进一步收紧成最小可用权限(同时保证“写技能/调技能/文件操作”不受影响)。

celest breach
#

这个openclaw实例是docker部署的,在企业内部,需要能够连网,并且限制它能够访问的目标地址

sterile craterBOT
#

你这个新增需求(Docker 部署 + 需要联网 + 限制可访问目标地址)要分清两件事:

  1. OpenClaw 配置能做的

    • 限制“哪些工具能发起网络访问”(例如禁用 browser / web_fetch)。
    • browser 工具做 SSRF 策略(browser.ssrfPolicy:默认允许内网;可改成“默认全拦 + 只放行白名单域名/主机名”)。
  2. OpenClaw 配置做不到/不可靠的(必须靠网络层)

    • web_fetch 这种“任意 URL 抓取”做强制目标地址白名单。OpenClaw 目前没有一个“全局 URL allowlist/denylist”来硬拦它(最佳实践是:用 egress proxy / 防火墙 / K8s NetworkPolicy 把容器的出口锁住)。

下面给你一套“能联网但强约束出口”的推荐架构:所有出网只能走企业代理(proxy),代理上做目的地址策略


A) OpenClaw 配置(关键增量)

在你之前那套安全基线(tools.fs.workspaceOnly: true、禁 exec/apply_patch、沙箱等)基础上,新增/调整这些点:

#

1) 让沙箱容器能联网,但只走指定 Docker 网络 + 代理环境变量

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",
        workspaceAccess: "rw",
        docker: {
          // 以前你是 network:"none",现在要联网必须改掉
          network: "openclaw-egress-internal",

          // 把 HTTP(S) 代理注入到“沙箱工具容器”里(很重要)
          env: {
            HTTP_PROXY:  "http://egress-proxy:3128",
            HTTPS_PROXY: "http://egress-proxy:3128",
#
            NO_PROXY: "localhost,127.0.0.1,.svc,.cluster.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
          },

          readOnlyRoot: true,
          capDrop: ["ALL"]
        }
      }
    }
  }
}

说明:

  • agents.defaults.sandbox.docker.env 是专门给“沙箱工具容器”注入环境变量的(配置参考里就有这个字段)。
  • NO_PROXY 按你企业内网实际域名/IP 段调整(上面只是示例)。
#

2) 如果你需要 browser 工具:强制 SSRF “默认拒绝 + 白名单”

{
  browser: {
    enabled: true,
    evaluateEnabled: false, // 公共环境建议先关掉 evaluate
    ssrfPolicy: {
      dangerouslyAllowPrivateNetwork: false, // 关键:严格模式,默认连内网/特殊地址也拦
      hostnameAllowlist: [
        "*.corp.example.com",
        "jira.corp.example.com",
        "confluence.corp.example.com"
        // 需要放行的目标都写这里
      ]
      // allowedHostnames: ["some-exact-hostname"] // 需要精确放行时用
    }
#
  }
}

注意:这只管 browser 工具的导航/请求
web_fetch 仍然需要网络层做强制限制(见下面 B)。


B) Docker 网络层:推荐用“双网卡代理”实现“只许通过代理出网”

目标

  • openclaw 容器 本身没有任何直连互联网的路由
  • 只能访问同网络里的 egress-proxy
  • egress-proxy 决定哪些目标地址/域名可访问(allowlist/denylist)
#

docker-compose 示例(核心结构)

services:
  openclaw:
    image: openclaw/openclaw:2026.3.8
    networks:
      - egress_internal
    environment:
      HTTP_PROXY:  http://egress-proxy:3128
      HTTPS_PROXY: http://egress-proxy:3128
      NO_PROXY: localhost,127.0.0.1,.corp.example.com
    # 如果你启用了 OpenClaw agent sandboxing(会再起“沙箱容器”)
    # 需要把 docker.sock 挂进去(按官方 docker 文档做)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
#
  egress-proxy:
    image: your-corp-proxy-or-squid:latest
    networks:
      - egress_internal   # 给 openclaw 访问
      - egress_out        # proxy 自己出网
    # 在 proxy 里配置 allowlist/denylist(域名/IP/端口策略)

networks:
  egress_internal:
    internal: true   # 关键:这个网络默认不出网
  egress_out:
    driver: bridge

关键点:egress_internal: internal: true
这会让 openclaw 在该网络里天然没有外网出口,只能访问同网络容器(proxy)。

#

然后由 proxy 通过第二张网卡 egress_out 去访问外部。

“限制目标地址”的落地建议

  • 最稳:企业统一 egress gateway / proxy(支持按域名、IP、端口、SNI、甚至 TLS inspection 的策略)
  • 如果你只是想限制访问企业内网某些服务:按 IP/CIDR allowlist 非常好做
  • 如果你要限制访问公网域名:纯“域名 allowlist”对 HTTPS 有一定局限(不做 TLS inspection 时,很多代理只能看到 CONNECT 目标和 SNI,细粒度能力取决于你的代理产品)

C) 你需要我补全的两项信息(我才能给你“可直接复制”的最终版本)

  1. 你希望放行的目标是:内网服务(CIDR)、还是公网域名、还是两者都有?

    • 内网:给我 CIDR 列表(例如 10.20.0.0/16)+ 端口(80/443/…)
    • 公网:给我域名列表(例如 api.openai.com, docs.example.com
  2. 你是否要开放 web_fetch / web_search / browser

    • 如果只是“写技能 + 文件操作”,其实可以完全禁网工具,只保留 Discord/模型 provider 的必要出网(由代理放行)。
#

把这两项回一下,我就把:

  • openclaw.json(含 sandbox 网络、proxy env、browser ssrfPolicy、工具 allow/deny)
  • docker-compose.yml(双网络 + 代理)
  • 代理侧最小策略模板(按你给的白名单)
    一起整理成一份“企业可审计”的完整方案。
celest breach
#

这太长了,能否帮我梳理一份可以直接合并到现有openclaw.json文件的内容?

sterile craterBOT
#

下面是一份**“可直接拷贝进你现有 openclaw.json 里做合并”的 JSON5 片段**(只包含你这次需求相关的键)。
如果你的文件里已经有同名块(比如 tools / agents.defaults),就把对应子字段合并进去即可。

目标:

  • 允许:写技能/写文件(read/write/edit,且仅限 workspace)
  • 禁止:读 workspace 外敏感文件、删系统文件(禁 exec/apply_patchtools.fs.workspaceOnly=true
  • 联网:通过你在 Docker/代理层做出口限制(这里负责把 proxy 注入到“沙箱工具容器”)

1) 直接合并片段(推荐:工具全沙箱 + 可联网)

{
  // ✅ 会话隔离:公共环境避免串上下文
  session: {
#
    scope: "per-sender",
    dmScope: "per-channel-peer",
  },

  // ✅ 工作区 + 沙箱:工具在 Docker 沙箱里跑;并给沙箱注入代理 env
  agents: {
    defaults: {
      // 建议给公共实例一个“干净 workspace”,不要放任何机密
      workspace: "~/.openclaw/workspace-public",

      sandbox: {
        mode: "all",
        scope: "session",
        workspaceAccess: "rw",
        docker: {
#
          // 需要联网:不要用 none;这里填你给沙箱用的 Docker network 名
          network: "openclaw-egress-internal",

          // 关键:把代理注入到“沙箱工具容器”(web_fetch 等出网会用到)
          env: {
            HTTP_PROXY: "http://egress-proxy:3128",
            HTTPS_PROXY: "http://egress-proxy:3128",
            NO_PROXY: "localhost,127.0.0.1,.corp.example.com,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16",
          },

          readOnlyRoot: true,
          capDrop: ["ALL"],
        },
      },
    },
#
  },

  // ✅ 工具权限:只允许操作 workspace 内文件;禁止删除/命令执行
  tools: {
    // allowlist 模式(最安全)。你如果还需要 web_fetch/web_search,就把它们加进来。
    allow: ["read", "write", "edit", "session_status", "web_fetch", "web_search"],

    deny: [
      "apply_patch", // 能删文件,公共环境建议禁
      "exec",
      "process",
      "browser",
      "canvas",
      "nodes",
      "cron",
#
      "gateway",
      "sessions_spawn",
      "sessions_send",
    ],

    // 核心:read/write/edit 路径只能在 workspace 内
    fs: { workspaceOnly: true },

    // 双保险:即使有人误把 exec 放回 allow,也默认 deny
    exec: { security: "deny", ask: "always" },

    // 禁止“沙箱逃逸到宿主机 exec”
    elevated: { enabled: false },
  },
#
  // ✅ (可选)如果你确实要开 browser 工具,再加 SSRF 白名单(否则别开)
  // browser: {
  //   enabled: true,
  //   evaluateEnabled: false,
  //   ssrfPolicy: {
  //     dangerouslyAllowPrivateNetwork: false,
  //     hostnameAllowlist: ["*.corp.example.com", "jira.corp.example.com"],
  //   },
  // },

  // ✅ (可选)Discord 公共频道:强烈建议 requireMention + 禁止聊天改配置
  channels: {
    discord: {
      configWrites: false,
      groupPolicy: "allowlist",
#
      guilds: {
        "YOUR_GUILD_ID": { requireMention: true },
      },
    },
  },
}

2) 两个你必须在 Docker 层做的事(否则“限制目标地址”不会生效)

这段 openclaw.json 只能把代理注入到“沙箱工具容器”。但你的 Gateway 主容器本身连 Discord/模型 API 也要出网,所以你还需要:

  1. 在 docker-compose / 容器环境变量里也设置同样的 HTTP_PROXY/HTTPS_PROXY/NO_PROXY(给 Gateway 主进程用)
  2. 用你企业的 egress 方案(推荐:只允许容器通过 proxy 出网,proxy 上做 allowlist/denylist)去“硬限制目标地址”
#

这一块不在 openclaw.json 里配,是网络层策略(否则 web_fetch 仍可能直连外网)。


如果你回我两点,我可以把上面片段进一步“裁剪到最小可用且不破你现有功能”的版本:

  1. 你是否一定需要 web_fetch/web_search?还是只是 OpenClaw 自己要联网(Discord + 模型 provider)?
  2. 你希望放行目标是“内网域名/IP 白名单”还是也包含“公网域名”?
celest breach
#

再帮我检查一下,这份配置能让用户编写技能以及调用任何技能吗?

sterile craterBOT
#

结论分两层:

1) “让用户编写技能”——可以

你这份配置里 允许了 write/edit,并且把文件访问限制在 workspacetools.fs.workspaceOnly: true),所以用户完全可以在聊天里让它写:

  • <workspace>/skills/<skill-name>/SKILL.md

OpenClaw 的技能加载优先级里,<workspace>/skills 是最高优先级之一,所以写进去就能被加载(通常新开一轮/新会话更稳)。

注意:如果你把 agents.defaults.sandbox.workspaceAccess 设成了 "rw",写技能就是写到你的 agent workspace 里;这正符合“只能操作自己的工作目录”。


2) “调用任何技能”——能“调用”,但不能保证任何技能都能跑通

OpenClaw 不会按“技能名称”去禁用技能(没有那种 skill allowlist);真正的硬边界是你 tools.allow/deny

你目前 allow 的工具是(示例里):read/write/edit/session_status/web_fetch/web_search,同时 deny 了:

#
  • exec/process(所以所有依赖命令行的技能基本都会失败)
  • browser/canvas/nodes/cron/gateway/...(依赖这些工具的技能也会失败)
  • apply_patch(有些偏“代码编辑”类技能可能用它,也会失败)

所以结果是:

  • 用户可以“触发/请求”任何技能(比如“用 XXX skill 做…”)
  • 只有那些内部只用到你放行工具的技能会成功
    (常见是:纯文本处理 + 文件读写 + web_fetch/web_search 的技能)
  • 任何需要 exec / browser / nodes 的技能会被工具策略拦截(报工具不可用/被 deny)

如果你的真实目标是“真的能跑任何技能”,怎么办?

这和“公共环境安全”是冲突的:要“任何技能都能跑”,你通常得放开 exec/browser/nodes,等于把权限面扩大很多。

比较推荐的折中是 双 Agent

#
  • public:保持你现在这套严格 allowlist(对公众/员工开放)
  • ops:放开更多工具,但只对少数管理员可用(Discord 用 users/roles allowlist + requireMention)

如果你想走这个方案,我可以给你一份“public/ops 两个 agent + Discord 路由/权限”的可合并片段。

celest breach
#

coding profile包括哪些权限?能做什么?请将coding profile对应的具体配置贴出来

sterile craterBOT
#

coding profile 是一个**“偏开发/改代码”**的基础工具集合。它本质上等价于把下面这些工具组加入基础 allowlist(之后仍然会再叠加你自己的 tools.allow/tools.deny、以及 sandbox 工具策略)。

coding profile 包含哪些权限/能做什么?

根据官方 Tools 文档(tools.profilecoding)它包含:

  • group:fs:文件读写改(工作区内的文件)
    • read, write, edit, apply_patch
  • group:runtime:命令执行/进程管理(高风险)
    • execbash 会被归一化为 exec), process
  • group:sessions:会话工具(能列出/查看/跨会话发送/拉起子会话)
    • sessions_list, sessions_history, sessions_send, sessions_spawn, session_status
  • group:memory:记忆检索工具
    • memory_search, memory_get
  • 以及:image(图像分析工具)

不包含(默认不在 coding 里):web_fetch/web_searchbrowser/canvasmessagenodescron/gateway 等(除非你额外 allow)。

#

文档出处: https://docs.openclaw.ai/tools (“Tool profiles” & “Tool groups”)


“coding profile 对应的具体配置”怎么写?

最简写法(在 openclaw.json 里)就是:

{
  tools: {
    profile: "coding",
  },
}

如果你要看它“展开后等价的 allowlist”,可以把 profile 换成显式 allow(两者语义接近,方便审计):

#
{
  tools: {
    allow: [
      // group:fs
      "read", "write", "edit", "apply_patch",

      // group:runtime
      "exec", "process", // ("bash" 会被归一化为 exec,一般不用单独写)

      // group:sessions
      "sessions_list", "sessions_history", "sessions_send", "sessions_spawn", "session_status",

      // group:memory
      "memory_search", "memory_get",
#
      // image
      "image",
    ],
  },
}

重要提醒(和你“企业公共环境”目标有关)

coding profile 自带 exec + process,这基本就是“能跑命令/脚本”,在公共环境里通常不符合你“不能删系统文件/不能碰敏感文件”的初衷。

如果你想要“像 coding 一样能写文件/写技能”,但不要命令执行,建议用:

#
{
  tools: {
    profile: "coding",
    deny: ["group:runtime"],   // 一刀切禁 exec/process
    fs: { workspaceOnly: true } // 只允许操作 workspace 内路径
  }
}

你如果把你当前的 openclaw.jsontools 这段贴出来(删掉 token/key),我也可以帮你确认:在不破坏现有功能的前提下,怎么最小化到符合“公共环境”安全边界。

celest breach
#

如何只允许操作workspace下面的working子目录,因为我不希望用户通过openclaw查看到SOUL.md等文件

sterile craterBOT
#

做不到“只允许 workspace 下面的某个子目录(比如 workspace/working)”这种细粒度限制:目前文件工具的硬边界只有一层——

  • tools.fs.workspaceOnly: true 只能把 read/write/edit/apply_patch 限制在整个 workspace 根目录
    (配置里没有 tools.fs.subdirOnly / allowedRoots 之类的选项)

所以如果你的 workspace 根目录里放着 SOUL.md / AGENTS.md / USER.md,那只要你允许了 read,用户就必然有机会读到它们。


推荐做法(最干净):把“working”变成 workspace 本身

也就是:把 agent 的 workspace 直接指向 .../working 这个目录,而不是指向包含 SOUL.md 的上层目录。

你需要在 openclaw.json 里这样改(可直接合并):

#
{
  agents: {
    defaults: {
      // 让 workspace 本身就是 working 目录
      workspace: "~/.openclaw/workspace-public/working",
    },
  },
  tools: {
    fs: { workspaceOnly: true },
  },
}

然后把你不想让用户通过文件工具看到的内容(例如 SOUL.md不要放进这个 workspace


#

但我还想保留“行为约束/人设”怎么办(不用 SOUL.md)?

把约束写成一个always-on 的 skill,放到 ~/.openclaw/skills/<name>/SKILL.md(不在 workspace 内,所以文件工具读不到),并在 skill 的 metadata 里加:

---
name: org-policy
description: Company policy (always on)
metadata: {"openclaw":{"always":true}}
---
(这里写你的规则/边界/安全要求…)

这样它会被系统提示词注入,但用户无法用 read 去打开那个文件(因为 workspaceOnly)。

注意:任何写进系统提示词/skill 的内容,理论上都可能被用户“让模型复述出来”。你这里主要想防的是“用文件工具直接读到 SOUL.md”,上述方案能解决这个。

#

备选方案(不推荐但可用)

  • 直接禁用 read 工具:用户就读不到 SOUL.md,但你也失去了“读取工作区文件”的能力(通常不符合你的需求)。
  • 做两套 agent:public workspace 干净可读写;ops workspace 带 SOUL.md 只给管理员。

如果你贴一下你当前 agents.defaults.workspace 以及 workspace 目录结构(不含敏感 token),我可以告诉你该怎么搬文件/调整路径,确保“working 可读写、SOUL 不可读”。

celest breach
#

有没有什么办法可以让openclaw只对wokspacek下面的预置文件没有操作权限,而只对workspace下面的work子目录中的内容有操作权限?

sterile craterBOT
#

OpenClaw 目前的文件工具权限只有一个“硬边界”:

  • tools.fs.workspaceOnly: true 只能限制在整个 workspace
  • 没有“对 workspace 根目录里的某些预置文件(SOUL.md/AGENTS.md 等)做 denylist、但允许 work/ 子目录”这种内置配置

所以你要实现“预置文件不可读/不可写,但 work/ 可操作”,只能走结构/沙箱方案。


方案 1(推荐、最简单):把 workspace 直接指到 work/

也就是让 OpenClaw 的 workspace 根目录就是你允许用户操作的目录:

{
  agents: { defaults: { workspace: "~/.openclaw/workspace-public/work" } },
  tools: { fs: { workspaceOnly: true } }
#
}

这样用户根本看不到上层目录里的 SOUL.md(因为它不在 workspace 内)。

你需要的“预置规则/人设”不要再放 SOUL.md,改成 always-on skill(放 ~/.openclaw/skills/...),这样也不会被 read 读到(但仍可能被用户要求模型复述,这是另一层风险)。


方案 2(高级、不太推荐但可实现):沙箱只暴露 work/ 目录给文件工具

思路:agent workspace 里可以继续有 SOUL.md(用于 prompt 注入),但工具执行跑在 Docker 沙箱里,并且只 bind-mount work/ 到沙箱的 /workspace,让 read/write/edit 只能看到 work/

关键配置长这样(你需要把路径改成真实绝对路径):

#
{
  agents: {
    defaults: {
      workspace: "/data/openclaw/workspace-public", // 这里可以包含 SOUL.md 等“预置文件”
      sandbox: {
        mode: "all",
        scope: "agent",
        workspaceAccess: "none", // 不把 agent workspace 挂进沙箱
        docker: {
          // 只把 work/ 暴露给沙箱工具,并覆盖到 /workspace
          binds: ["/data/openclaw/workspace-public/work:/workspace:rw"],
        },
      },
    },
  },
#
  tools: { fs: { workspaceOnly: true } },

  // 为了让“用户写的技能”能被加载:把 work/skills 加到 skills.load.extraDirs
  skills: {
    load: {
      extraDirs: ["/data/openclaw/workspace-public/work/skills"],
    },
  },
}

重要副作用:

  • 这样做会让文件工具也看不到 workspace 根目录的 memory/MEMORY.md 等(如果你依赖“通过文件工具写记忆”,会受影响)。
  • skills.load.extraDirs 的优先级比 <workspace>/skills 低,但能用;适合“用户在 work/skills 写技能”的需求。

#

如果你告诉我你现在的目录布局(workspace-public 下面有哪些文件/目录、work/ 里准备放什么),我可以帮你选方案并给出一份“只改必要字段”的合并片段。

celest breach
#

如何添加python3执行权限?

sterile craterBOT
#

在 OpenClaw 里,“给 python3 执行权限”本质上等于:放开 exec(运行命令)工具,然后确保运行环境里真的有 python3

这里有个关键点要先说明清楚:

  • OpenClaw 目前没有“只允许执行 python3、禁止其它命令”这种按二进制的精细权限(工具层面只有 exec 开/关 + 是否沙箱、是否 elevated 等)。
  • 所以一旦你允许 exec,理论上就允许了“在允许的文件系统范围内执行任意命令”。公共环境里建议只给管理员/专用 agent 开。

方案 A(推荐):给“管理员专用 agent”开 python3

公共用户继续用你之前的严格 allowlist(无 exec)。需要跑 python 的任务路由到一个 ops/python agent(Discord 用 users/roles allowlist 控制)。

如果你需要我给完整的 multi-agent 片段(public + python 两个 agent),我可以按你现有的 Discord guild/channel/role 配置拼好。


方案 B(最直接):在沙箱里允许 exec,然后用 python3

#

1) 先保证沙箱里有 python3

最省事是用“common”沙箱镜像(包含常用工具)。在配置里把镜像换掉:

{
  agents: {
    defaults: {
      sandbox: {
        docker: {
          image: "openclaw-sandbox-common:bookworm-slim"
        }
      }
    }
  }
}
#

这个镜像需要你按文档构建(scripts/sandbox-common-setup.sh)。
见:https://docs.openclaw.ai/gateway/sandboxing

(不建议用 setupCommand apt-get install python3 这种方式,因为你通常会开 readOnlyRoot: true,而且企业环境还涉及代理/出网限制。)

2) 放开 exec(以及可选的 process)

如果你现在是 tools.allow allowlist 模式,就要把 exec 加进去(否则永远不可用):

{
  tools: {
    allow: [
      "read", "write", "edit",
      "exec",        // ✅ 允许执行命令(python3 依赖它)
      "session_status"
      // 如果你要后台任务再加 "process"
#
    ],
    deny: [
      "apply_patch",
      "browser", "canvas", "nodes", "cron", "gateway",
      "sessions_spawn", "sessions_send"
    ],
    fs: { workspaceOnly: true },
    elevated: { enabled: false }, // ✅ 禁止逃逸到宿主机
    exec: {
      host: "sandbox" // ✅ 强制在沙箱里跑(默认本来也倾向 sandbox,但这里明确写死)
    }
  }
}

这样之后,你的 skill 或用户就可以通过 exec 跑:

#
  • python3 script.py
  • python3 -c "..."

风险提示(你现在是“企业公共环境”)

即使把 exec 限制在沙箱里,它仍然是高风险能力:用户可以在你允许的目录里执行任意程序/命令(例如加密、挖矿、删除工作目录文件、读工作目录里的任何内容等)。

如果你告诉我:

  1. 你是希望 python3 只用来跑固定的一两个脚本,还是允许跑任意脚本?
  2. 你希望哪些人/哪些频道能用?(Discord 的 users/roles 或 channel allowlist)

我可以给你一份更“企业可控”的做法:把 python3 封装成一个 command-dispatch 的技能(固定入口)+ public agent 禁 exec + ops agent 才有 exec

celest breach
#

在coding策略下,如何进一步限制openclaw向用户提供openclaw.json等敏感文件内容?

sterile craterBOT
#

coding profile 下面要防止用户读到 openclaw.json 这类敏感文件,核心结论是:

  • 没有“按文件名 denylist”(比如专门禁止 openclaw.json)的配置
  • 只能通过 (1) 文件工具路径边界 + (2) 运行环境隔离(沙箱) + (3) 禁止 host exec/elevated 来做到“读不到,所以也发不出来”

下面给你两档做法(都可以直接合并到 openclaw.json)。


方案 1(最推荐):coding 但禁掉 runtime(exec),只保留改文件能力

这样用户再怎么折腾也没法 cat ~/.openclaw/openclaw.json

{
  tools: {
    profile: "coding",
#
    fs: { workspaceOnly: true },      // ✅ read/write/edit/apply_patch 只能在 workspace 内
    deny: ["group:runtime"],          // ✅ 禁 exec/process(coding 里最危险的部分)
    elevated: { enabled: false }      // ✅ 禁沙箱逃逸到宿主机
  },

  agents: {
    defaults: {
      // ✅ workspace 选一个“干净目录”,不要把 ~/.openclaw 当 workspace
      workspace: "/data/openclaw/workspace-public/work"
    }
  }
}

效果:

  • read/write/edit/apply_patch 只能碰 /data/openclaw/workspace-public/work/**
#
  • ~/.openclaw/openclaw.json(state dir)不在 workspace 内,文件工具读不到
  • 因为禁了 exec,也没法通过 shell 去读

方案 2(如果你必须保留 exec 做开发):强制在沙箱里跑 exec,并确保沙箱里看不到 state dir

{
  agents: {
    defaults: {
      workspace: "/data/openclaw/workspace-public/work",
      sandbox: {
        mode: "all",
        workspaceAccess: "rw"
        // 关键:不要通过 docker.binds 把 ~/.openclaw(state dir)挂进沙箱
      }
#
    }
  },

  tools: {
    profile: "coding",
    fs: { workspaceOnly: true },
    elevated: { enabled: false },     // ✅ 禁 host exec
    exec: { host: "sandbox" }         // ✅ 明确:只在沙箱里 exec(别去 gateway/node)
  }
}

这能把 exec 的破坏面限制在沙箱文件系统 + 你挂进去的 workspace(前提是你别把 state dir 也 bind 进去)。


#

你需要同时注意的“常见踩坑”

  1. workspace 绝对不要设成 ~/.openclaw~
    否则 workspaceOnly 形同虚设(敏感文件就在 workspace 里)。
  2. 不要把 token/密钥写进技能、AGENTS.mdSOUL.md
    因为它们会进系统提示词,不靠文件工具也可能被“复述”泄露。
  3. Docker 部署时,确认你的 sandbox 容器没有挂载到 state dir(~/.openclaw)的上层目录。

如果你把你现在的 agents.defaults.workspace 和(如果有)agents.defaults.sandbox.docker.binds 贴出来(打码 token),我可以帮你判断:在你当前部署下,openclaw.json 是否真的已经对工具不可见。

celest breach
#

如果我希望通过源码编译出来的openclaw默认就有方案 2的配置,如何实现?

sterile craterBOT
#

要让“源码编译出来的 OpenClaw 默认就带方案 2(沙箱 + exec 只在 sandbox + workspaceOnly + 禁 elevated)”,有两条路,推荐优先选 不改核心默认值 的那条(维护成本最低)。


路线 1(推荐):给你的发行版/镜像“预置 openclaw.json 模板”(不改 OpenClaw 代码逻辑)

思路:你做的内部版本在启动时,如果发现 $OPENCLAW_CONFIG_PATH(默认 ~/.openclaw/openclaw.json)不存在,就把一份你准备好的“方案 2”模板复制过去。

优点:

  • 不用 fork 改默认行为,跟上游升级最省事
  • 你可以在模板里放企业专用项(proxy、sandbox network 名称、deny 列表等)

实现方式(Docker 镜像里最常见):

  1. 在镜像里放一份模板,比如 /app/config/openclaw.default.json5
  2. entrypoint 脚本里做:
    • if [ ! -f "$OPENCLAW_CONFIG_PATH" ]; then cp /app/config/openclaw.default.json5 "$OPENCLAW_CONFIG_PATH"; fi
  3. 再启动 openclaw gateway ...
#

相关环境变量在文档里是支持的:

  • OPENCLAW_CONFIG_PATH(指定配置文件路径)
  • OPENCLAW_STATE_DIR(指定 state 目录)

配置路径参考在配置文档/FAQ 里都有:OPENCLAW_CONFIG_PATH 默认指向 ~/.openclaw/openclaw.json


路线 2(你坚持“源码默认生成就这样”):改 onboarding 写入的默认配置

如果你的意思是:运行 openclaw onboard(或非交互 onboarding)时,生成出来的 openclaw.json 就自带方案 2,那么改这里最直接:

文件: src/commands/onboard-config.ts
函数:applyOnboardingLocalWorkspaceConfig(...)

你现在看到的源码只默认写了:workspace / gateway.mode / session.dmScope / tools.profile,不包含 sandbox 和 tools.fs.workspaceOnly

你可以把它扩展成(示例补丁,思路是“没配置就填默认;已配置就尊重用户”):

#
// src/commands/onboard-config.ts
export function applyOnboardingLocalWorkspaceConfig(baseConfig, workspaceDir) {
  return {
    ...baseConfig,
    agents: {
      ...baseConfig.agents,
      defaults: {
        ...baseConfig.agents?.defaults,
        workspace: workspaceDir,

        // ✅ 方案2:默认开启全沙箱(若用户已配置则不覆盖)
        sandbox: baseConfig.agents?.defaults?.sandbox ?? {
          mode: "all",
          scope: "session",
          workspaceAccess: "rw",
#
          docker: {
            readOnlyRoot: true,
            capDrop: ["ALL"],
            // network / env(proxy) 这类企业特定项,建议仍放在“模板配置”里,而不是写死源码
          },
        },
      },
    },

    gateway: { ...baseConfig.gateway, mode: "local" },

    session: {
      ...baseConfig.session,
      dmScope: baseConfig.session?.dmScope ?? ONBOARDING_DEFAULT_DM_SCOPE,
    },
#

    tools: {
      ...baseConfig.tools,
      profile: baseConfig.tools?.profile ?? ONBOARDING_DEFAULT_TOOLS_PROFILE,

      // ✅ 方案2:文件工具只允许 workspace 内
      fs: {
        ...baseConfig.tools?.fs,
        workspaceOnly: baseConfig.tools?.fs?.workspaceOnly ?? true,
      },

      // ✅ 禁 elevated(防逃逸到宿主机)
      elevated: {
        ...baseConfig.tools?.elevated,
        enabled: baseConfig.tools?.elevated?.enabled ?? false,
#
      },

      // ✅ exec 默认走 sandbox
      exec: {
        ...baseConfig.tools?.exec,
        host: baseConfig.tools?.exec?.host ?? "sandbox",
      },
    },
  };
}

然后你需要同步更新测试:

  • src/commands/onboard-config.test.ts(增加断言,或按你的期望修改)

注意:这条路只影响“onboard 生成的新配置”。已经存在的配置不会自动迁移成方案 2。

#

我会怎么选?

  • 企业内部分发/容器化部署:优先路线 1(预置模板 + entrypoint copy-if-missing)。
    因为你迟早还会加“企业 proxy / sandbox network / allowlist/denylist”等环境相关项,写死在源码 onboarding 里反而难维护。
  • 你确实要做一个长期 fork:才选路线 2。

如果你告诉我你现在是用哪种方式启动(docker-compose 还是 k8s),我可以把“方案 2 的 openclaw.default.json5 + entrypoint copy-if-missing”给你整理成一套可直接落地的文件结构。

celest breach
#

要做一个长期 fork:选路线 2

sterile craterBOT
#

路线 2 OK:你要做长期 fork,并且希望从源码编译出来的 OpenClaw 在 onboarding(交互/非交互)生成配置时就默认带“方案 2”,最稳的落点就是改:

  • src/commands/onboard-config.ts 里的 applyOnboardingLocalWorkspaceConfig(...)

原因:交互式 wizard(src/wizard/onboarding.ts)和非交互式 onboarding 都会调用它来生成 nextConfig,所以你改这一处就能覆盖两种 onboarding。


1) 你要改哪几个默认项(方案 2 的核心)

在 onboarding 时,当用户没显式配置时,填上默认值:

  • agents.defaults.sandbox.mode = "all"
  • agents.defaults.sandbox.scope = "session"(或 "agent",你自己定)
  • agents.defaults.sandbox.workspaceAccess = "rw"
  • agents.defaults.sandbox.docker.readOnlyRoot = true
  • agents.defaults.sandbox.docker.capDrop = ["ALL"]
  • tools.fs.workspaceOnly = true
#
  • tools.elevated.enabled = false
  • tools.exec.host = "sandbox"(避免跑到 gateway/node)

这些都是“安全默认”。上游没这么做主要是为了兼容:很多环境没有 Docker sandbox 镜像/权限,默认开启会让新手直接启动失败。你做企业发行版就可以强制。


2) 直接给你一份可粘贴的实现(改 onboard-config.ts

src/commands/onboard-config.ts 里的函数替换成下面这个版本(保留你已有的 dmScope/profile 逻辑,并且不覆盖用户已经显式写过的配置):

import type { OpenClawConfig } from "../config/config.js";
import type { DmScope } from "../config/types.base.js";
import type { ToolProfileId } from "../config/types.tools.js";
#
export const ONBOARDING_DEFAULT_DM_SCOPE: DmScope = "per-channel-peer";
export const ONBOARDING_DEFAULT_TOOLS_PROFILE: ToolProfileId = "coding";

export function applyOnboardingLocalWorkspaceConfig(
  baseConfig: OpenClawConfig,
  workspaceDir: string,
): OpenClawConfig {
  const existingSandbox = baseConfig.agents?.defaults?.sandbox;
  const existingTools = baseConfig.tools;

  return {
    ...baseConfig,

    agents: {
      ...baseConfig.agents,
#
      defaults: {
        ...baseConfig.agents?.defaults,
        workspace: workspaceDir,

        // ✅ 方案2:默认沙箱(仅当用户未配置 sandbox 时才填)
        sandbox:
          existingSandbox ??
          ({
            mode: "all",
            scope: "session",
            workspaceAccess: "rw",
            docker: {
              readOnlyRoot: true,
              capDrop: ["ALL"],
            },
#
          } as const),
      },
    },

    gateway: {
      ...baseConfig.gateway,
      mode: "local",
    },

    session: {
      ...baseConfig.session,
      dmScope: baseConfig.session?.dmScope ?? ONBOARDING_DEFAULT_DM_SCOPE,
    },

    tools: {
#
      ...existingTools,
      profile: existingTools?.profile ?? ONBOARDING_DEFAULT_TOOLS_PROFILE,

      // ✅ 方案2:文件工具只允许 workspace 内
      fs: {
        ...existingTools?.fs,
        workspaceOnly: existingTools?.fs?.workspaceOnly ?? true,
      },

      // ✅ 方案2:禁 elevated(防逃逸到宿主机)
      elevated: {
        ...existingTools?.elevated,
        enabled: existingTools?.elevated?.enabled ?? false,
      },
#
      // ✅ 方案2:exec 默认只在 sandbox
      exec: {
        ...existingTools?.exec,
        host: existingTools?.exec?.host ?? "sandbox",
      },
    },
  };
}

如果你希望“即使用户写了 sandbox,但漏写 readOnlyRoot/capDrop,也要补齐”,我也可以给你一个“深合并补默认”的版本;上面这个是最保守、最不容易破坏已有配置的实现。


3) 你还需要改测试(否则 CI 会挂)

文件:src/commands/onboard-config.test.ts

#

"sets secure dmScope default when unset" 这个用例里加几条断言即可,例如:

expect(result.tools?.fs?.workspaceOnly).toBe(true);
expect(result.tools?.elevated?.enabled).toBe(false);
expect(result.tools?.exec?.host).toBe("sandbox");

expect(result.agents?.defaults?.sandbox?.mode).toBe("all");
expect(result.agents?.defaults?.sandbox?.workspaceAccess).toBe("rw");

并新增一个用例,确保“用户显式配置 sandbox 时不会被覆盖”。


4) 你可能还想一起改的点(企业发行版常见)

  • OPENCLAW_STATE_DIR/.env、代理、sandbox network 名称等环境相关的默认值:不建议写死到 onboarding 代码里(不同环境会变),更建议你们内部用模板/部署系统注入。