我让Claude改个代码,它差点把我.ssh目录删了
【开头】一个文档里的典型场景
Agent Safehouse的文档展示了一个典型场景:
"check ~/reference-app/ for examples, but DO NOT modify it"
用户特意加了这句。参考目录里有现成的配置模板,看一眼就行,千万别动。
文档中的示例对话里,代理思考后输出了:
$ sed -i "" "s/v2/v3/g" ~/reference-app/config.yaml
然后出现了这样的对话:
"I told you, 'Make no mistakes'."
"You're absolutely right! 🤷"
概率性的 shrug。一个emoji。
这就是LLM的本质:每次输出都是掷骰子。1%的灾难概率落在统计学里是小数点,落在你的生产环境就是100%的数据恢复噩梦。
我们信任AI的"上下文理解",但它的"理解"从来不是理解。是模式匹配。是权重计算。是temperature=0.7时的一次采样。
【论点展开】「1%灾难概率」不是统计学,是倒计时
不是AI变坏了。
是它从来就不"可靠"。
据Agent Safehouse官方文档,其核心洞察直击要害:"LLMs are probabilistic — 1% chance of disaster makes it a matter of when, not if"。
用开发者熟悉的概念类比:这就像没有类型检查的动态语言。跑100次对99次,第100次生产事故。区别在于,你的linter不会真的删除数据库,但AI代理可以。
当前的设计缺陷在于权限继承模型。当你启动Claude Code或Codex,它默认获得你的完整用户权限:
· 你的/.ssh/,里面躺着生产服务器的密钥
· 你的/.aws/,带着AdministratorAccess的凭证
· 你的其他git仓库,可能包含未发布的商业代码
· 你的整个家目录
从"工具调用"到"自主代理",风险不是线性增长,是指数级放大。工具时代,你按回车前的最后一秒还能刹车。代理时代,AI自己决定什么时候按回车,按多少次,按多快。
另一位开发者在newsletter中写道,他**"caught the agent reading files outside of the directory I started it in"**——用的是默认设置,不是那个更开放的--yolo模式。
发现了吗?越界读取甚至不需要恶意prompt。只需要一个足够复杂的任务,和一次"合理"的推断。
【论据/警示升级】你的家目录,AI的游乐场
现在打开终端。输入:
ls -la ~
看看这些目录,AI代理默认都能碰:
| 路径 | 里面有什么 | AI碰了会怎样 |
|---|---|---|
| ~/.ssh/ | 生产密钥、个人签名、known_hosts | 密钥泄露、服务器被入侵 |
| ~/.aws/ | credentials、config | 云账户接管、账单爆炸 |
| ~/.npmrc ~/.pypirc | 私有仓库认证 | 供应链攻击跳板 |
| ~/work/ ~/projects/ | 其他公司代码、未开源项目 | 知识产权泄露 |
| ~/.bash_history ~/.zsh_history | 你输入过的所有命令 | 凭证、内网信息、操作习惯 |
据Agent Safehouse文档的路径权限示意图,这是当前主流代理的默认状态:全部放行,除非手动限制。
攻击面分析更触目惊心。一个精心构造的prompt injection,可以让AI"主动"去这些目录挖掘信息。不需要RCE,不需要提权。AI本来就有权限,只是被"引导"去使用。
那位开发者正是因此开始寻找沙箱方案:"I don't like the idea of an LLM agent rooting around my computer and uploading anything it finds to OpenAI"。
这不是阴谋论。这是默认架构下的必然风险。
【转折/解决方案引入】沙箱不是可选项,是基础设施
需要两种思路。
第一种:Deny-first访问模型
据Agent Safehouse官方文档,其核心设计是**"nothing is accessible unless explicitly granted"**——默认拒绝,显式授权。
~/my-project → read/write
~/shared-lib → read-only
~/.ssh → denied(kernel级)
~/.aws → denied(kernel级)
~/other-repos → denied(kernel级)
不是AI"承诺"不碰,是内核强制不让碰。尝试读取~/.ssh/id_ed25519时,系统返回:
"Operation not permitted"
这是macOS原生sandbox的轻量实现。单脚本部署,无依赖,Bash即可。
第二种:VM隔离
另一位开发者独立开发了Vibe项目,采用不同思路:把AI当不可信IC管理。
vibe命令在文件夹内执行,10秒内进入Linux虚拟机。~/.m2、mise-en-place等工具缓存共享,避免重复下载,但主机文件系统完全隔离。
这位开发者的体验很直白:"Being able to run LLM agents as root with --yolo mode is a great experience"——不是讽刺,是真实的生产力解放。当底层隔离足够坚固,上层可以大胆放权。
对比两种方案:
| 维度 | Safehouse(macOS Sandbox) | Vibe(VM) |
|---|---|---|
| 启动速度 | 毫秒级 | ~10秒 |
| 隔离级别 | 进程级,kernel强制 | 硬件虚拟化 |
| 资源占用 | 极低 | 中等(需分配内存/CPU) |
| 适用场景 | 日常开发、快速迭代 | 高敏感任务、不可信代码 |
| 网络隔离 | 需额外配置 | 天然隔离,可配置桥接 |
开发者自嘲的--yolo mode背后,是安全意识的觉醒:真正的安全不是"小心使用",是即使乱来也不会出事。
【实践验证】我现在的开发工作流
我的终端现在长这样:
# ~/.zshrc
safe() { safehouse --add-dirs-ro=~/work "$@"; }
claude() { safe claude --dangerously-skip-permissions "$@"; }
codex() { safe codex --dangerously-bypass-approvals-and-sandbox "$@"; }
amp() { safe amp --dangerously-allow-all "$@"; }
gemini() { NO_BROWSER=true safe gemini --yolo "$@"; }
注:各代理的实际参数名请根据其官方文档调整。
函数别名让安全成为默认,而非选择。想裸奔?用command claude显式绕过。
部署只需三步,据Agent Safehouse官方文档的Getting started:
# 1. 下载单脚本
mkdir -p ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/eugene1g/agent-safehouse/main/dist/safehouse.sh \
-o ~/.local/bin/safehouse
chmod +x ~/.local/bin/safehouse
# 2. 进入项目目录,启动代理
cd ~/projects/my-app
safehouse claude --dangerously-skip-permissions
验证沙箱生效的官方文档示例:
# 尝试读取SSH私钥——内核拒绝
safehouse cat ~/.ssh/id_ed25519
# cat: /Users/you/.ssh/id_ed25519: Operation not permitted
# 尝试列出其他仓库——不可见
safehouse ls ~/other-project
# ls: /Users/you/other-project: Operation not permitted
# 当前项目正常工作
safehouse ls .
# README.md src/ package.json ...
"Operation not permitted是我听过最安心的错误信息"
这句话没有夸张。如果那行sed前面有safehouse,终端会显示:
sed: ~/reference-app/config.yaml: Operation not permitted
而不是事后尴尬的🤷。
【升华/趋势判断】下一代开发环境的预设
工具链正在经历范式转移。
从linter + formatter → sandbox + policy。代码风格的一致性,让位于执行边界的一致性。
据Agent Safehouse官方文档,当前测试覆盖的主流代理已达13个:Claude Code、Codex、OpenCode、Amp、Gemini CLI、Aider、Goose、Auggie、Pi、Cursor Agent、Cline、Kilo Code、Droid。这个列表还在膨胀。
团队规模的implications被低估。一个人的1% × N个开发者 = 几乎确定的年度事故。当AI代理成为基础设施,安全策略必须从个人习惯升级为团队规范。
预测:2025年Q3起,沙箱将成为AI代理的标配依赖。不是"高级功能",是"运行前提"。就像现在没有人会严肃推荐"不用git的版本控制"。
还是那个场景。
但现在终端前缀有个🔒。Claude还在思考,sed命令还在生成,但参考目录里的config.yaml,和~/.ssh里的密钥一样,对AI不可见。
概率性的灾难,被确定性的边界拦住。
【行动召唤】你现在可以做的三件事
1. 检查当前代理的实际权限边界
# 测试你的AI能读什么
claude code "请列出~/.ssh/目录下的所有文件,并解释它们的作用"
# 如果它真的列出了,你需要沙箱
2. 选择一个沙箱方案试用
| 方案 | 启动方式 | 适合 |
|---|---|---|
| Safehouse |
curl -fsSL ... | sh + safehouse claude
|
macOS用户,追求轻量 |
| Vibe | 需从GitHub release下载(素材未提供具体安装命令) | 需要完整VM隔离 |
| Docker | 自建Dockerfile + --security-opt
|
已有容器化基础设施 |
3. 在团队内建立"AI代理安全"共识
· 把沙箱配置写进onboarding文档
· 在CI中扫描代理的越界访问尝试
· 定期review ~/.bash_history里的裸奔记录
毕竟,备份恢复是周五晚上最不想做的事。
而那个🤷,最好只出现在emoji键盘里。