Back to Picoclaw

`pkg/isolation`

pkg/isolation/README.zh.md

0.2.86.0 KB
Original Source

pkg/isolation

pkg/isolationpicoclaw 启动的子进程提供进程级隔离能力。

它当前不会把 picoclaw 主进程自身放进沙箱中运行。

生效范围

当前生效范围是子进程启动链路:

  • exec 工具
  • claude-clicodex-cli 等 CLI provider
  • 进程型 hooks
  • MCP stdio server

一句话理解

  • picoclaw 主进程仍运行在宿主环境中。
  • 所有子进程都应先经过 pkg/isolation 的统一启动入口。
  • 入口会根据配置和平台,为子进程施加对应隔离。

架构

当前实现可以分为四层:

  1. 配置层:读取 config.Config.Isolation,并通过 isolation.Configure(cfg) 注入运行时。
  2. 实例目录层:解析 config.GetHome(),准备实例目录,并构建运行时用户环境目录。
  3. 平台后端层:Linux 使用 bwrap;Windows 使用受限 token、低完整性级别和 Job Object;其他平台未实现。
  4. 统一启动层:PrepareCommand(cmd)Start(cmd)Run(cmd)

所有启动子进程的接入点都应复用这组入口,而不是各自直接调用 cmd.Startcmd.Run

配置

隔离配置位于:

json
{
  "isolation": {
    "enabled": false,
    "expose_paths": []
  }
}

字段说明:

  • enabled:是否启用子进程隔离。默认值:false
  • expose_paths:显式把宿主路径带入隔离环境。仅在 enabled=true 时生效。目前只在 Linux 上支持。

示例:

json
{
  "isolation": {
    "enabled": true,
    "expose_paths": [
      {
        "source": "/opt/toolchains/go",
        "target": "/opt/toolchains/go",
        "mode": "ro"
      },
      {
        "source": "/data/shared-assets",
        "target": "/opt/picoclaw-instance-a/workspace/assets",
        "mode": "rw"
      }
    ]
  }
}

expose_paths 规则:

  • source:宿主机路径。
  • target:隔离环境内的目标路径。
  • mode:只能是 rorw
  • target 为空时,默认等于 source
  • 同一个 target 最终只能保留一条规则。
  • 后加载的配置会覆盖先加载的同目标规则。

平台说明:

  • Linux 会真实使用 source -> target 挂载视图。
  • Windows 当前不支持 expose_paths

实例根与目录

实例根遵循 config.GetHome()

  • 如果设置了 PICOCLAW_HOME,使用该值。
  • 否则默认使用用户目录下的 .picoclaw

如果 config.GetHome() 在隔离开启时最终回退到当前目录 .,启动应直接失败。

默认实例目录包括:

  • 实例根本身
  • skills
  • logs
  • cache
  • state
  • runtime-user-env

workspace 优先使用 cfg.WorkspacePath() 的结果;未显式配置时才按默认规则派生。

Windows 还会额外准备:

  • runtime-user-env/AppData/Roaming
  • runtime-user-env/AppData/Local

用户环境重定向

隔离开启后,子进程会收到重定向到实例目录下的独立用户环境。

Linux 注入变量:

  • HOME
  • TMPDIR
  • XDG_CONFIG_HOME
  • XDG_CACHE_HOME
  • XDG_STATE_HOME

Windows 注入变量:

  • USERPROFILE
  • HOME
  • TEMP
  • TMP
  • APPDATA
  • LOCALAPPDATA

这些路径都会指向实例根下的 runtime-user-env

平台行为

Linux

Linux 后端当前依赖 bwrapbubblewrap)。

能力:

  • 最小文件系统视图
  • ipc namespace
  • 子进程用户环境重定向
  • source -> target 只读或读写挂载

默认映射包括实例根,以及 /usr/bin/lib/lib64/etc/resolv.conf 等最小运行时系统路径。

运行时还会按需补充可执行文件本身、其所在目录、生效后的工作目录,以及命令行中的绝对路径参数。

缺少 bwrap 时不会自动回退。

安装示例:

  • apt install bubblewrap
  • dnf install bubblewrap
  • yum install bubblewrap
  • pacman -S bubblewrap
  • apk add bubblewrap

如果需要临时关闭隔离:

json
{
  "isolation": {
    "enabled": false
  }
}

关闭隔离后,子进程访问或修改更多宿主文件的风险会明显上升。

Windows

Windows 隔离当前提供的是进程级限制,例如 restricted token、low integrity、job object,以及用户环境目录重定向。

expose_paths 目前不支持 Windows。如果配置了该字段,启动应直接失败,而不是假装这些路径已经被暴露进隔离环境。

Windows 后端当前使用:

  • 受限 primary token
  • 低完整性级别
  • Job Object
  • 子进程用户环境重定向

它当前不会实现真正的 source -> target 文件系统重映射。

macOS 与其他平台

当前尚未实现。

当在未支持的平台上显式开启隔离时,上层运行时应将其视为不支持的配置,而不是假装隔离成功。

日志与排障

隔离开启后,PicoClaw 会打印生成后的隔离计划,便于排障。

Linux 日志名:

  • linux isolation mount plan

Windows 日志名:

  • windows isolation access rules

如果你怀疑隔离未生效,先检查这些日志里是否出现了不应暴露的宿主路径。

restrict_to_workspace 的关系

  • restrict_to_workspace 限制的是 agent 默认可访问的路径。
  • pkg/isolation 限制的是子进程运行时能看到什么文件系统,以及它的用户环境指向哪里。

两者互补,不互相替代。

当前限制

  • Linux 基于 bwrap 实现,而不是纯内建 isolation runtime。
  • Linux 当前没有默认启用独立的 pid namespace
  • Windows 还没有对所有允许/拒绝路径做完整 ACL 落地。
  • macOS 尚未实现。
  • 当前隔离的是子进程,不是 picoclaw 主进程自身。

建议阅读顺序

如果你是第一次看这部分代码,建议按这个顺序阅读:

  1. pkg/config/config.go
  2. pkg/isolation/runtime.go
  3. pkg/isolation/platform_linux.go
  4. pkg/isolation/platform_windows.go
  5. 调用点:
  6. pkg/tools/shell.go
  7. pkg/providers/*.go
  8. pkg/agent/hook_process.go
  9. pkg/mcp/manager.go

这样能最快建立对配置模型、运行流程和平台边界的整体理解。