沙箱权限网关
这套机制运行在哪里
权限网关是 sandrpod-agent(员工 PC 上)内置的,不在 Sira 后端里。本文描述的是员工 PC 上 AI 行为受到的限制,以及员工和管理员看到 / 控制它的方式。
每次 AI 在沙箱里访问文件、执行命令、打开 PTY,sandrpod-agent 都会先经过 权限网关 裁决。三种模式由启动参数 --permission-mode 控制:
| 模式 | 行为 |
|---|---|
off | 完全跳过网关,仅保留旧版"系统路径黑名单"(默认) |
prompt | work_dir 内静默放行;硬锁路径静默拒绝;其他路径走原生弹框询问员工 |
strict | work_dir 内静默放行;其他全部静默拒绝(适合无人值守服务器) |
决策优先级(prompt 模式下)
work_dir 命中 → 放行(静默)
↓
hardlock 命中 → 拒绝(静默,且不可被规则覆盖)
↓
permanent rule 命中 → 用规则结果
↓
session grant 命中 → 用本会话临时授权
↓
弹框询问 → 用户选择 (允许一次 / 永久允许 / 拒绝 / 永久拒绝)
↓
30 秒超时 → 拒绝(fail-close)默认硬锁路径
硬锁是一组 永远拒绝 的目录——AI 永远读不到员工的密钥、邮件、聊天记录等。即便员工自己设了"永久允许",硬锁也优先生效。
跨平台共同硬锁:
~/.ssh~/.aws~/.gnupg~/.kube~/.config/gh~/.docker
macOS 额外硬锁:
~/Library/Keychains~/Library/Application Support/Google/Chrome~/Library/Application Support/Firefox~/Library/Application Support/com.apple.sharedfilelist~/Library/Mail~/Library/Messages~/Library/Cookies
Linux 额外硬锁:
~/.mozilla~/.config/google-chrome~/.config/chromium~/.local/share/keyrings~/.thunderbird
Windows 额外硬锁:
~/AppData/Roaming/Microsoft/Crypto~/AppData/Local/Google/Chrome~/AppData/Local/Microsoft/Edge
解锁需要明确知情
如确实必须让 AI 访问硬锁路径,员工可以在自己的 PC 上跑:
bash
sandrpod-tray unlock <path> --i-understand-the-risk只有命令行能解锁,UI 不提供按钮——这是故意的。
弹框机制
prompt 模式下,未命中硬锁/规则的访问会触发原生弹框(不是浏览器、不是 web 弹框,是 OS 级的):
| OS | 实现 |
|---|---|
| macOS | osascript display dialog(最多 3 个按钮) |
| Linux | zenity --question --extra-button,回退 kdialog |
| Windows | PowerShell WinForms.MessageBox Yes/No/Cancel |
弹框文字会显示:
- AI 想做什么(读 / 写 / 执行 / 打开终端)
- 目标路径或命令
- 调用方(哪个智能体)
员工选项:
- 允许这一次:仅当前请求放行
- 永久允许这条路径 / 命令:写入
~/.sandrpod/permissions.json - 拒绝这一次:仅当前请求阻止
- 永久拒绝:写规则
30 秒不操作视为拒绝(fail-close)。
配置文件
员工 PC 上:
| 路径 | 用途 | 权限 |
|---|---|---|
~/.sandrpod/permissions.json | 永久规则 + 会话授权 + 命令策略 | 600 |
~/.sandrpod/authz.sock | tray ↔ agent IPC | 600 |
~/.sandrpod/audit/active.log | 决策审计本地缓冲(NDJSON) | 600 |
~/.sandrpod/audit/audit.cursor | 已上传位点 | 600 |
permissions.json 结构:
json
{
"rules": [
{ "path": "/Users/me/work", "decision": "allow", "mode": "rw" }
],
"session_grants": [
{ "path": "/tmp/foo", "decision": "allow", "expires_at": "2026-05-01T12:00:00Z" }
],
"command_policy": {
"deny": ["rm -rf /", "shutdown"],
"warn": ["sudo *"]
}
}命令策略
除了路径访问,命令执行也走网关:
- deny 列表:直接拒绝
- warn 列表:弹框警示,员工选 allow / deny
- 默认 work_dir 内的命令也会走 prompt(除非员工设永久规则)
撤销 / 重置
bash
# 列出所有永久规则
sandrpod-tray rules list
# 撤掉某条规则
sandrpod-tray rules revoke <id>
# 清空所有会话临时授权
sandrpod-tray rules clear-session
# 完全重置(保留硬锁,清空其他所有规则)
sandrpod-tray rules reset与平台决策审计的关系
每次裁决(允许 / 拒绝 / 警告)都会写一条本地 NDJSON 日志,每 30 秒批量上传到 Sira 后端的 sandbox_decision_events 表。管理员可以在 AI 决策审计 看到完整记录。
推荐部署策略
| 场景 | 模式 |
|---|---|
| 个人电脑、有人值守 | prompt(默认) |
| CI / 服务器、无人值守 | strict(避免弹框卡住) |
| 调试 / 演示 | off(偷懒,但不要用于生产) |
prompt 模式不能完全防御失控
即使在 prompt 模式下,AI 仍可能在 work_dir 内做出意外操作(比如删除项目文件)。建议:
- 把 work_dir 指向干净目录而不是用户主目录
- 重要操作前 git 提交一次,便于回滚
- 配合 AI 决策审计 事后追溯
