模型 / 数据集
eugene1g/agent-safehouse avatar
eugene1g/agent-safehouse

Agent Safehouse:用 sandbox-exec 给 macOS 上的编码智能体做减权

Sandbox your local AI agents so they can read/write only what they need

2,061 个 Star94 个 ForkShellApache-2.0

秒懂

它是什么?
它把 macOS 自带的 sandbox-exec 包装成一套可组合的策略配置,默认拒绝一切,再按需放行。适合在 Mac 上跑 Claude Code、Codex 这类能改文件的智能体,但要清楚它是加固层,不是对抗定向攻击的完整边界。
适合谁用?
如果你的智能体在 macOS 上运行,并且你愿意接受「默认拒绝、按需放行」这套心智模型,Agent Safehouse 值得装一次试用;先用 brew install eugene1g/safehouse/agent-safehouse 安装,再在真实项目里跑一遍你常用的命令,观察哪些路径被拦。不要把它当成能挡住定向攻击的隔离边界,README 自己就写明它只是加固层。
能商用吗?
可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 2 天前。
用什么语言写的?
主要是 Shell(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

它解决的是权限过宽,而不是提示注入

编码智能体在本地跑起来之后,通常拿到的是当前用户的完整文件权限。它要读项目源码,于是顺手也能读 ~/.ssh 和 ~/.aws;它要写构建产物,于是也能写你的 shell 配置。Agent Safehouse 针对的正是这个落差:把智能体的可访问范围收敛到它完成工作真正需要的那部分。

目标用户很明确,在 macOS 上使用 Claude Code、Codex、Amp 这类可执行命令、可写文件的智能体,并且不想为每个项目手工搭一套容器或虚拟机的人。仓库的 topics 里同时出现 claude-code 和 macos,语言是 Shell,说明它的实现方式是围绕系统已有能力做编排,而不是自己实现一套隔离内核。

README 里有一句话需要认真读:它是 hardening layer,不是针对determined attacker 的完美安全边界。这句话决定了它的定位。它降低的是智能体误操作和越权访问的常规风险,不是把恶意代码关进笼子。如果你的威胁模型里包含攻击者主动寻找沙箱逃逸路径,这个工具不该是唯一一层。

策略如何从模板渲染成最终规则

核心机制是 macOS 的 sandbox-exec,配合一套可组合的策略 profile。模型是 deny-first:先拒绝,再逐条放行。内置的 profiles 目录按模块划分,覆盖主流编码智能体和由应用托管的智能体工作流。

渲染阶段有两个细节值得注意。第一,HOME_DIR 和 WORK_DIR 是模板变量,用来生成与家目录、工作目录相对的具体规则。README 明确说明 HOME_DIR 本身不会授予对家目录的递归读权限,它只是让策略能写出精确的 home-relative 规则。WORK_DIR 同理,通过 workdir-literal、workdir-subpath、workdir-prefix 三个前缀暴露给内置和追加的策略规则。相对辅助参数以 / 开头,这样一条可复用的策略就能指向 <workdir>/.env 这类文件,而不必把项目的绝对路径写死。

第二,内置模块里出现的 macOS 兼容路径,例如 /etc、/private/etc/resolv.conf、/private/etc/localtime,会在渲染时被解析。如果作者写的路径本身是符号链接,Safehouse 会为真实目标路径补上对应的授权,让主机特有的系统文件继续可用,同时不必把源策略放宽到递归读取整个 /private/etc。这个机制的适用范围被刻意收窄了:只覆盖内置的绝对 literal 和 subpath 读授权,用户自己提供的路径授权走另一套归一化流程,可写规则和仅元数据规则目前都不参与自动展开。

安装与日常调用

Homebrew 路线最省事:

brew install eugene1g/safehouse/agent-safehouse

不想引入 tap 的话,README 也给了独立脚本的装法:

mkdir -p ~/.local/bin curl -fsSL https://github.com/eugene1g/agent-safehouse/releases/latest/download/safehouse.sh -o ~/.local/bin/safehouse chmod +x ~/.local/bin/safehouse

日常使用的关键参数有三个。--add-dirs-ro 追加只读目录,--add-dirs 追加可读写目录,--append-profile 追加一个策略文件。追加的策略最后加载,因此它的 deny 规则可以收窄之前的默认放行。

README 推荐的模式是把机器相关的设置放进 shell wrapper,而不是写进项目配置。示例里定义了 SAFEHOUSE_APPEND_PROFILE 环境变量指向 ~/.config/agent-safehouse/local-overrides.sb,再封装一个 safe 函数同时传入 --add-dirs-ro 和 --append-profile。zsh、bash、fish 三种写法都给了。这个分层是有道理的:共享仓库的配置对所有人生效,而 ~/server 或 /Volumes/Shared 这类挂载点每台机器都不一样,混在一起会让配置到处冲突。

机器本地策略文件用的是 Scheme 风格的 S-expressions。示例里既展示了放行,也展示了收尾的拒绝:

(deny file-read* file-write* (workdir-literal "/.env"))

这条规则的意思是,即使工作目录整体可写,根目录下的 .env 依然不可读写。

HOME 并没有被整体放行,但默认例外是真实存在的

这是最容易误解的一点。默认行为比直觉要窄:对 /、通往 $HOME 的路径以及 $HOME 本身,只授予元数据级别的遍历权限,让运行时能探测那些已被显式允许的家目录路径;对 ~/.config 和 ~/.cache 授予目录根读取,让工具能发现 XDG 位置;再加上始终启用的 profile 里少量明确的家目录范围文件和目录,例如 git 与 ssh 的元数据、共享的智能体指令文件夹。

结果是 stat "$HOME" 可以成功,而 ls "$HOME" 和 cat ~/secret.txt 依然失败,除非有更具体的规则放行。这个设计是有意为之:让工具链能正常探测路径存在性,同时不暴露内容。

但默认例外确实存在,而且不是零。如果你希望连这些也去掉,README 给出的办法是使用 --append-profile,因为追加的 profile 最后加载,它的 deny 规则可以覆盖前面的默认放行。这里需要自己动手,工具没有提供一个开关来一键关闭全部家目录例外。

Git worktree 的自动检测只覆盖启动那一刻

启动时,如果所选工作目录本身就是某个 Git worktree 的根,Safehouse 会自动识别。它会为该 worktree 补上共享 Git 元数据的访问权限(当 common dir 位于所选工作目录之外时),并默认让该仓库下其他已存在的 linked worktree 变为可读,方便跨树检查。

限制在于快照不会更新。已经运行中的进程不会感知到之后新建的 worktree。README 直接给了应对方式:如果你习惯把 worktree 建在 ~/worktrees 这样的固定父目录下,最好用 --add-dirs-ro 把这个根目录显式加进去,而不是依赖自动检测。

这个取舍是合理的,静态策略无法随文件系统变化而重写,但使用者必须知道边界在哪里。对经常并行开多个 worktree 的工作流,自动检测可能只帮你解决一半问题。

Linux 上没有对应的实现路径

Safehouse 是专为 macOS 写的,依赖 sandbox-exec,这个接口在 Linux 上不存在。README 没有试图用跨平台抽象来掩盖这一点,而是直接列了 Linux 原生的替代方案。

vetto 走的是零守护进程的内核沙箱路线,Linux 上用 Landlock LSM 和 seccomp-bpf,macOS 上落到 Seatbelt,并提供自动的 PATH shim,用 vetto enable <agent> 启用。bubblewrap 是非特权 user namespace 沙箱工具,在容器工具链里被广泛使用。firejail 是成熟的 SUID 沙箱,自带常见应用的现成 profile。nono.sh 用 Landlock 加 seccomp-notify,特点是不重启就能提升权限。sandlock 是纯 Python 实现,组合 Landlock、seccomp-bpf 和 seccomp user notification,不需要 root、容器或 C 编译器。

这些方案与 Safehouse 的差别不只是平台。Safehouse 复用系统自带的 sandbox-exec,好处是没有额外运行时依赖,坏处是策略表达力受限于 Apple 那套 profile 语法,而且这个接口本身在 macOS 上并非面向第三方安全产品的稳定 API。Linux 上的 Landlock 和 seccomp 是内核主线机制,语义更明确。选哪个,先看你的开发机是什么系统,这一步没有折中余地。

版本节奏、许可证与需要自己确认的事

仓库最近三个版本是 v0.11.0(2026-07-08)、v0.11.1(2026-07-17)和 v0.12.0(2026-09-07),最后一次推送在 2026-09-09,仓库未归档。从时间间隔看,维护是持续的,但版本号还在 0.x,策略语法和参数在次版本之间发生变化的可能性不能排除。升级前值得看一眼 release notes 里有没有涉及 profile 结构或渲染行为的改动,尤其是你已经写了本地追加策略的情况。

许可证是 Apache-2.0。这个许可证包含专利授权条款,通常对商业使用友好,但具体到你的分发方式、是否修改后再分发、是否需要保留 NOTICE 文件,应当由法务判断,这里不做法律意见。

还有几件事这份材料没有回答,需要你自己确认。仓库只有一个 Shell 语言的主实现,README 提到全部详细文档、架构说明和测试说明都在 VitePress 站点上,也就是说仅读 README 不足以掌握完整的策略语义。CI 里有两个 macOS 工作流,分别覆盖测试和智能体 TUI 的端到端测试,但材料没有给出测试覆盖的具体范围。策略渲染涉及符号链接解析和路径归一化,这类逻辑的边界情况最好在你自己的机器上用真实项目验证一遍,而不是假设默认配置已经覆盖了你的目录结构。

编辑结论

如果你的智能体在 macOS 上运行,并且你愿意接受「默认拒绝、按需放行」这套心智模型,Agent Safehouse 值得装一次试用;先用 brew install eugene1g/safehouse/agent-safehouse 安装,再在真实项目里跑一遍你常用的命令,观察哪些路径被拦。不要把它当成能挡住定向攻击的隔离边界,README 自己就写明它只是加固层。Linux 用户不必勉强,sandbox-exec 是 macOS 专有接口,README 直接推荐了 bubblewrap、firejail、vetto 等替代品。上手前必须验证三件事:你的智能体实际需要哪些写路径,HOME 目录下哪些文件被默认放行,以及已有的 Git worktree 是否落在所选工作目录之外。

官方来源

  1. eugene1g/agent-safehouse on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
社区笔记

社区笔记