夜雨聆风学习资料网

ARTICLE · 1062702

OpenClaw 2.0把安全做成了只读

OpenClaw 2.0把安全做成了只读
Skill Workshop 用来源记录保护用户手写 Skill,却没有同时提供旧 Skill 的显式接管功能。本文直接对照官方代码、PR 和 Issue,看看限制怎样上线、误伤怎样发生、官方修到了哪一步。全文约 1600 字,预计阅读 4 分钟。

OpenClaw 给 Skill Workshop 加所有权保护,本来是件好事。自动整理不能因为一个目录位于 workspace/skills/,就擅自改写或删除用户手写的 Skill。

但 OpenClaw 2.0 系列先发布了所有权限制,显式接管功能至今仍停在 Issue 里。

结果是,许多在 Skill Workshop 出现之前创建的老 Skill,即使操作者明确授权修改、提案通过扫描,仍可能因为没有 Workshop 的 create 来源记录而被拒绝更新。

这不是猜测。限制写在代码里。

先看原始代码,未知来源一律只读

2026 年 8 月 18 日合并的 PR #125666[1],标题是“preserve externally owned workspace skills”。它新增了 src/skills/workshop/ownership.ts,用已应用的 create 提案判断一个 Skill 是否属于 Workshop。

原始代码中的关键部分如下。

/** Paths claimed by a successfully applied Workshop create proposal. */export function listWorkshopOwnedSkillDirs(  workspaceDir: string,  options: SkillWorkshopStoreOptions = {},): Set<string> {  const { database, kysely } = openSkillWorkshopStore(options);  const rows = executeSqliteQuerySync(    database.db,    kysely      .selectFrom("skill_workshop_proposals")      .selectAll()      .where("workspace_dir", "=", path.resolve(workspaceDir))      .where("kind", "=", "create")      .where("status", "=", "applied")      .where("claim_released_time", "is", null),  ).rows;  // Unknown provenance fails closed to user-owned; only an applied create proves ownership.  return new Set(    rows.flatMap((row) => {      const record = parseSkillProposalRow(row);      return record ? [path.resolve(record.target.skillDir)] : [];    }),  );}

代码注释直接说明了判断原则。没有来源记录,就按“用户所有、Workshop 无权修改”处理;只有成功应用过 Workshop create 提案,才算 Workshop-owned。

这个默认值是对的。问题出在下一段。

更新老 Skill 时,代码直接拒绝

同一个 PR 修改了 src/skills/workshop/apply-transition.ts。在应用更新提案之前,它新增了下面的判断。

+import { isWorkshopOwnedSkillDir } from "./ownership.js"; if (   record.kind === "update" &&   !isWorkshopOwnedSkillDir(     input.workspaceDir,     record.target.skillDir,     storeOptions(input.env),   ) ) {   throw new Error(     `Skill Workshop does not own this skill path: ${record.target.skillKey}`,   ); }

集合整理也受同一规则约束。collection-plan.ts 规定,只要当前 Skill 不是 Workshop-owned,任何 write 或 drop 都会报错。

+if (+  entry.action !== "keep" &&+  currentByName.has(entry.name) &&+  !currentByName.get(entry.name)!.workshopOwned+) {+  throw new Error(`Skill Workshop does not own this skill path: ${entry.name}`);+}

产品已经把限制写死。老 Skill 没有 create 来源记录,只能 keep

这套限制进入了稳定版 OpenClaw 2026.8.2[2]。它防住了自动清理误删手写资产,也顺手把大量历史 Skill 变成了永久只读候选。

只读规则已经上线,adopt / disown 仍未上线

Issue #125711[3] 在 PR 合并当天就提出补齐 adopt / disown。操作者可以显式把某个旧 Skill 交给 Workshop 管理,留下审计记录,以后也能撤回授权。

Issue 对问题的描述很准确。

Since #125666, the workshop only mutates skills it created ...That is the right default, but it has no opt-out.

截至 2026 年 9 月 23 日,这个 Issue 仍然是 Open。

也就是说,OpenClaw 已经实现了“我不认识,所以不碰”,却没有实现“主人确认这是自己的,现在可以接管”。

安全边界因此从防止 Agent 越权,变成了阻止所有者授权。

绕路也可能绕出一个新 Skill

如果更新走不通,直觉上可能会改用 create。但 Issue #94947[4] 记录了另一个坑。本来要修现有 Skill A,create 会在旁边生成一个新的 sibling Skill。

旧 Skill 没改,新的规则和脚本被装进了另一个目录。提案看起来应用成功,真正运行的还是旧版本。

这个 Issue 截至 9 月 23 日也仍为 Open。

错误落点后看起来成功,比明确失败更麻烦。它会制造两个来源、两个名字和两套维护历史,直到下一次线上问题才暴露。

2026.9.2 还把普通仓库源码一起锁了

OpenClaw 2026.9.2 的系统提示词曾包含下面这条绝对指令。

Durable reusable skill/playbook/workflow work: `skill_workshop`;never write proposal/skill files directly.

它没有区分下面两类文件。

  • • Workshop 管理的运行中 Skill
  • • 普通 Git 仓库里的 SKILL.md 源码

Issue #140246[5] 记录了实际后果。用户已经明确说明目标是普通仓库源码,不是 OpenClaw 管理的 Skill,Agent 仍然因为开发者级指令拒绝修改。

文件名只要叫 SKILL.md,正常开发就可能被当成越权操作。

官方修了一半,原始修改如下

PR #142844[6] 在 2026 年 9 月 10 日合并,commit 为 57dc817e9634。它把原来的绝对禁令改成了有边界的规则。

-"Durable reusable skill/playbook/workflow work: `skill_workshop`; never write proposal/skill files directly.",+"Durable reusable skill/playbook/workflow work: `skill_workshop`; never write Workshop proposal or Workshop-owned skill files directly.",+"Exception: user-requested edits to repository-owned skill source in an ordinary repository checkout are normal repository work—apply them with normal repository file tools, do not route them through Workshop, and never infer Workshop ownership from a `SKILL.md` filename, skill-like directory, or name collision with an installed skill.",

这次修改是对的。普通仓库中的 Skill 源码就是普通仓库文件,用户明确要求后,Agent 应该正常修改,不需要先把源码“收编”进 Workshop。

修复进入了稳定版 OpenClaw 2026.9.4[7]

但它只修复了“仓库源码误伤”,没有给历史 Skill 增加 adopt / disown。截至本文核验时,本机仍是 2026.9.2,npm 最新版为 2026.9.5。升级能解决普通仓库源码被拦截的问题,不能解决老 Skill 无法纳管的问题。

真正合理的安全模型并不复杂

未知来源 Skill 默认只读,继续保留。

所有者显式执行 adopt 后,系统记录操作者、目标路径、当前树哈希和时间;扫描通过后,Workshop 才获得更新权。

每次更新仍要做哈希绑定、安全扫描、测试和审批。所有者执行 disown 后,Workshop 立即失去写权限。

完整的所有权模型应当默认保护,允许明确授权,全程留痕,也能随时撤销。

OpenClaw 现在只交付了前半套。PR #125666 已经把默认只读做进稳定版,Issue #125711 仍在等待实现。

创作说明|本文由 phx 确定选题、观点和最终版本,龙虾(AI Agent)参与资料整理与文字协作。欢迎留言挑错,也欢迎给龙虾提写作建议。

引用链接

[1] PR #125666: https://github.com/openclaw/openclaw/pull/125666[2] OpenClaw 2026.8.2: https://github.com/openclaw/openclaw/releases/tag/v2026.8.2[3] Issue #125711: https://github.com/openclaw/openclaw/issues/125711[4] Issue #94947: https://github.com/openclaw/openclaw/issues/94947[5] Issue #140246: https://github.com/openclaw/openclaw/issues/140246[6] PR #142844: https://github.com/openclaw/openclaw/pull/142844[7] OpenClaw 2026.9.4: https://github.com/openclaw/openclaw/releases/tag/v2026.9.4

相关学习资料