- 修复窄屏 git clone 块横向溢出撑破整页(hero-clone max-width + code 块内横滚) - 顶栏:移动端保留 GitHub 入口;Astrion 标题改为星空开关按钮(停 rAF + 隐藏画布,卡顿排查用) - 演示区:废弃 IntersectionObserver 懒加载,改为「点击预览」手动触发(移动端卡顿定位) - 文档:沙箱平台口径——macOS/Windows 已实测,Linux 未测试未适配暂不可用(02/05 章中英四份) Co-authored-by: Astrion powered by Kimi-K3 <astrion-agent@users.noreply.github.com>
87 lines
6.3 KiB
Markdown
87 lines
6.3 KiB
Markdown
# 执行与安全
|
||
|
||
本章讲 Astrion 如何安全地执行 AI 发起的操作:沙箱执行的实际行为、路径授权、审批机制。概念层面的四组开关(部署/权限/执行环境/运行模式)请先看《核心概念》,本章聚焦具体行为与日常管理。
|
||
|
||
> 范围说明:「实时终端」只是观察面板,与安全机制无关,见《对话》一章。
|
||
|
||
---
|
||
|
||
## 1. 命令是怎么被执行的
|
||
|
||
### run_command:两段式执行
|
||
|
||
以默认推荐的 `approval` 模式为例,一条 AI 发起的 shell 命令的实际旅程是:
|
||
|
||
1. **先在只读身份下执行**——能读不能写(host 模式靠 OS 沙箱,docker 模式靠容器内的非特权用户);
|
||
2. 如果命令没碰写操作,直接返回结果,全程无感;
|
||
3. 如果触发权限拒绝(要写文件、要改系统),**自动转为向你发起审批**;
|
||
4. 你批准后,**仅这一条命令**以可写身份重试;你拒绝或超时未处理,则本次不执行;
|
||
5. AI 拿到的是最终结果,中间过程不干扰它的思路。
|
||
|
||
`auto_approval` 模式把第 3 步的审批者换成自动审批智能体;`unrestricted` 模式跳过审批直接执行;`readonly` 模式下写入类请求直接拒绝。注意审批**只放大这一次写入、不放大读取范围**——想读工作区之外的文件,唯一途径是路径授权(见第 2 节)。
|
||
|
||
### 终端会话:身份钉死,切换即关闭
|
||
|
||
持久终端会话(terminal 系列工具)的读写身份在启动时按当时的权限档、执行环境与沙箱策略**钉死**:受限档(readonly/approval/auto_approval)下终端以只读身份运行,终端里的写入由系统直接拒绝(EPERM);`unrestricted` 下才是可写身份。当你**切换执行环境(sandbox ⇄ direct)、权限档在受限档与无限制之间互切、切换工作区或容器**时,现有终端会话会被**直接关闭**——不会带着旧身份继续运行,后续操作在重新拉起的会话中按新策略执行。这也意味着:跑长任务时不要切换这些开关,任务会随会话一起终止。
|
||
|
||
### 子智能体与后台命令
|
||
|
||
子智能体的终端进程同样经过执行环境策略:sandbox 下经宿主机沙箱启动,direct 下直接宿主机启动;docker 模式则在容器内执行。后台命令(`run_in_background`)与前台命令走同一套只读/可写沙箱判定,**不会因为放后台就绕过权限**。
|
||
|
||
## 2. 路径授权的日常管理
|
||
|
||
入口:输入栏 `+` 菜单 →「路径授权」。
|
||
|
||
- **可读可写路径**:AI 的完整工作范围,通常就是你的项目目录;
|
||
- **仅可读路径**:允许 AI 参考但禁止修改,比如参考文档、线上配置样例、别的项目源码。
|
||
|
||
建议实践:
|
||
|
||
1. 保持最小授权——只加当前任务需要的目录;
|
||
2. 敏感目录(`~/.ssh`、密钥库、系统目录)永远不要加入任何一类;
|
||
3. 任务性质变化时及时调整,授权是即时生效的(新终端会话除外,见上)。
|
||
|
||
## 3. 网络权限
|
||
|
||
输入栏权限菜单中独立的一组:
|
||
|
||
- **受限**(默认):仅本地回环,AI 无法访问外部网络——适合纯本地任务,也杜绝了数据外发;
|
||
- **完全开放**:允许出站/入站连接——需要 AI 联网搜索、调外部 API、装依赖时开启。
|
||
|
||
网络权限与文件沙箱相互独立,且在 plan 模式下也可调整。
|
||
|
||
## 4. 审批面板
|
||
|
||
入口:`+` 菜单 →「审批面板」。这里能看到审批记录:哪些命令/写入被提请审批、谁批的(人工或自动审批智能体)、结果如何。`auto_approval` 模式下如果不想让面板自动弹出打扰,个人空间有开关(默认不自动打开)。
|
||
|
||
## 5. 禁止命令清单
|
||
|
||
部署级配置 `forbidden_commands.json`(放 `<数据根>/config/`)可以配置**绝对禁止执行的命令特征**,命中即拒,与权限模式无关。这是兜底防线,适合在服务器部署时封死 `rm -rf /`、`shutdown` 这类命令。
|
||
|
||
## 6. 关于 direct 模式的忠告
|
||
|
||
`direct` = 命令直接在宿主机执行,**没有任何沙箱**。它与受限档权限(readonly/approval/auto_approval)硬互斥——只有 `unrestricted` 才能选 direct,从 direct 切入受限档时会被自动压回 sandbox。合理使用场景只有一个:某条命令在沙箱里确实跑不了(需要系统级权限),且没有替代方案。此时:
|
||
|
||
1. 先把权限档切到 `unrestricted`,再临时切到 direct;
|
||
2. 跑完立即切回 sandbox(和原来的权限档);
|
||
3. 注意 direct 切换后**永久生效、不会自动回退**——忘记切回等于长期裸奔。
|
||
|
||
## 7. docker 模式的安全现状
|
||
|
||
docker 模式下,用户之间的隔离边界是容器本身:每个用户的终端在独立容器中,互相不可见。容器**内部**的权限约束同样是真强制:
|
||
|
||
- 受限档(readonly/approval/auto_approval)下,run_command、后台命令与持久终端都以**非特权用户(uid 10001)**在容器内执行——工作区属主是 root,写入由内核文件权限直接拒绝,不依赖对命令文本的识别;审批通过后,仅该条命令以 root 身份重试;
|
||
- 生效前提:工作区属主为 root、没有全局可写的文件、容器未挂载 docker.sock(按官方部署文档操作即满足);
|
||
- 该强制仅在 **Linux 宿主机**上成立——macOS 本机的 Docker Desktop 不执行 uid 文件权限,本机开发时不要把容器内部权限当安全边界;
|
||
- 多用户部署时应配合容器资源限制、镜像最小化等常规容器安全实践。
|
||
|
||
## 8. 各平台安全水位
|
||
|
||
再次强调《核心概念》中的结论,因为它直接影响你该信任沙箱到什么程度:
|
||
|
||
- **Windows(WSL2)**:已实测,可做到完全数据隔离,需先安装 WSL2;
|
||
- **macOS(sandbox-exec)**:已实测,白名单读模型,写入和读取都可限制——进程默认只能读系统目录、工作区与已授权路径;代价是授权路径的祖先目录顶层文件名可被列出(文件内容仍不可读);
|
||
- **Linux(bwrap+seccomp)**:**未测试、未适配、当前不可用**——Linux 服务器上部署多用户服务请使用 Docker 模式(容器隔离已实测生效),不要依赖宿主机沙箱。
|
||
|
||
无论哪个平台,沙箱的首要价值是**防误操作**;涉及真正的敏感数据,请叠加路径授权最小化、网络受限、readonly 权限等手段综合防护。
|