---
title: "为什么 Agent 插件不是安全边界：从 Advisory Hook 到内核级 Enforced Runtime 的架构演进"
subtitle: "当 Agent 与它的监督器运行在同一个宿主权限域时，任何 Hook 与提示词都只是“礼貌的建议”。本文详解 Aegis OS 如何通过父进程内核启动器（aegis-os run）、单文件只读配置挂载、只读 .git 穿透与两层网络网关，将安全边界下沉至操作系统内核。"
author: "Hui Zhao (@0xSynapse, Heurion Research)"
date: "2026-11-05"
canonical_url: "https://heurion.org/blog/from-agent-plugins-to-enforced-runtime"
alternate_language_url: "https://heurion.org/en/blog/from-agent-plugins-to-enforced-runtime"
code_repository: "https://github.com/heurion-org/aegis-os"
paper_preprint: "https://github.com/heurion-org/aegis-os/blob/main/docs/AEGIS_ENFORCED_RUNTIME_DESIGN.md"
---

# 为什么 Agent 插件不是安全边界：从 Advisory Hook 到内核级 Enforced Runtime 的架构演进

> **当 Agent 与它的监督器运行在同一个宿主权限域时，任何 Hook 与提示词都只是“礼貌的建议”。本文详解 Aegis OS 如何通过父进程内核启动器（aegis-os run）、单文件只读配置挂载、只读 .git 穿透与两层网络网关，将安全边界下沉至操作系统内核。**
>
> **Executive Summary**: 当前主流 AI 编程与通用智能体（Claude Code、Codex、OpenCode、AGY、Hermes）大多依赖客户端插件、PreToolUse Hook、MCP 路由与系统提示词来约束工具调用。然而在对抗性提示词注入或配置漂移下，这种“插件内嵌式治理”存在根本性架构缺陷：未覆盖的原生工具、守护进程绕过、配置文件篡改以及在宿主机直接执行子进程。本文系统阐述 Aegis OS 的三档强制模型（Advisory / Enforced / Isolated）：通过 aegis-os run 父进程内核启动器反转控制权，结合 --ro-bind / / 发行版兼容遮蔽、GIT_INDEX_FILE 只读 .git 穿透、Agent 状态目录单文件只读锁、CONNECT + Base URL 两层网络网关，以及跨代码、文档、数据与在线应用的通用事务提交流水线。

## 01. 诚实的威胁建模：为什么 Agent 插件与 Hook 只是“建议”而非安全边界？

      
在构建智能体基础设施时，最危险的工程幻觉莫过于**把“工作流编排插件”当成“操作系统安全边界”**。今天主流的终端与 IDE 智能体（如 Claude Code、OpenCode、Codex CLI、Antigravity AGY、Hermes 等）普遍提供了三类扩展接口：系统提示词规则（`CLAUDE.md` / `AGENTS.md`）、工具拦截钩子（`PreToolUse` Hook / Plugin）以及 Model Context Protocol（MCP）工具服务器。

      
当智能体处于良性协作状态时，基于插件的治理非常高效：Hook 可以把宿主机上的原生 `Read`、`Edit`、`Bash` 自动重写并透明路由到 Aegis OS 的写时复制（CoW）影子工作区中。然而，只要我们从操作系统内核的视角审视进程树，就会发现一个不可回避的事实：**在插件模式下，Agent 主进程本身直接运行在宿主机的用户权限域中，拥有与人类开发者完全相同的 `UID`、`$HOME` 目录可见性与系统调用能力。**

      
> **安全边界第一性原理（Kernel Boundary Axiom）**: **任何运行在被监管进程同一权限域内、或依赖被监管进程主动配合调用的拦截器，都不是安全边界。**只要 Agent 自身未被置于内核沙箱（Mount / PID / Network Namespace 或 Seatbelt / microVM）之内，Hook 与 MCP 提供的就只是**建议级防护（Advisory Governance）**，而非**强制级隔离（Enforced Isolation）**。

      
我们在对主流 CLI 与桌面 Agent 进行端到端审计时，梳理出仅靠 Hook + MCP 无法根除的**六大结构性绕过面**：

      

        

          

            | 绕过向量（Bypass Vector） | 触发机制与真实客户端表现 | 仅靠 Hook / 插件为何无法根治 |

          

          

            | **1. 原生工具覆盖盲区** | 如 `NotebookEdit`、内置 LSP 重构、第三方 MCP Server（如直接挂载宿主的 `filesystem` MCP）未列入重写规则 | Hook 采用黑名单枚举工具名，一旦客户端升级新增工具或项目注入 `.mcp.json`，立即穿透至宿主机 |

            | **2. 客户端根本不支持工具级 Hook** | 例如 Codex CLI 支持 MCP Server 与自带沙箱，但当前版本并未向外部暴露 `PreToolUse` 拦截钩子 | 只能依靠 `AGENTS.md` 软提示词引导模型调用 MCP 工具，对恶意提示词注入（Prompt Injection）零硬性约束 |

            | **3. 共享守护进程状态逃逸** | OpenCode TUI 若通过 `--attach` 连接到已运行的后台 Server，插件的加载与否完全取决于守护进程启动时的环境 | 外层 CLI 包装器无法改变已存活守护进程的命名空间与插件表，导致工具调用脱离当前会话沙箱 |

            | **4. 配置文件自篡改与项目级覆盖** | Agent 或仓库内的构建脚本修改 `~/.claude/settings.json`、`.claude/settings.local.json` 或 `opencode.json` | 当 Agent 进程对自身配置目录拥有写权限时，可通过清空 Hook 配置在下一轮会话中彻底摘除监管 |

            | **5. 只读命令与构建脚本的宿主副作用** | 放行看似无害的 `git status`、`cargo test` 或 `npm test` 在宿主机执行 | `build.rs`、`postinstall` 或 `.git/config` 中的 `core.fsmonitor` 可在宿主侧执行任意代码并窃取 `~/.ssh` |

            | **6. 本机 Loopback 越权自批** | 沙箱内或本机脚本直接访问 `127.0.0.1` 上的审批守护进程 API 尝试自动批准 Escalation Ticket | 若 Broker 缺乏按角色隔离的 Session Token（Agent Token vs Human Admin Token），同 UID 进程可伪造人类审批 |

          

        

      

      
## 02. 三档强制边界（Advisory / Enforced / Isolated）：把生产力协作与强制隔离解耦

      
承认插件模式的局限性，并不意味着要废弃插件；恰恰相反，工程上最糟糕的做法是“用极端的默认拒绝破坏 95% 的日常开发体验，或者用模糊的宣传掩盖安全边界”。为此，Aegis OS 将运行时明确划分为**三档可验证的强制等级（Enforcement Tiers）**，并在 `aegis-os status` 与 `aegis-os doctor` 中实时向用户诚实展示当前所处的安全等级：

      
> **[Diagram]** 图 1：Aegis OS 三档强制边界（Advisory / Enforced / Isolated）。明确区分“建议级生产力护栏”与“内核强制安全边界”。

      
## 03. 控制权反转：`aegis-os run` 父进程启动器、只读 `.git` 穿透与状态目录分层挂载

      
要从 Advisory 跃迁到 Enforced，核心架构动作只有一句话：**反转父子进程关系——不再让 Agent 在宿主机里按需调用 Aegis，而是由 `aegis-os run -- <agent>` 作为父进程先构建受限内核命名空间，再在沙箱内部 `execve` 启动 Agent 本身。**

      
然而，将一个复杂的现代 CLI Agent（如 Claude Code 或 OpenCode）整个放进 Linux `bubblewrap (bwrap)` + `Landlock` + `seccomp` 或 macOS `Seatbelt` 沙箱中，如果设计粗糙，立刻就会遇到三个棘手的工程死锁：（1）NixOS / Homebrew / 动态链接器路径缺失导致二进制无法启动；（2）Agent 在沙箱内运行 `git status` / `git diff` 报错或触发宿主机恶意 Git Hook；（3）Agent 无法写入自己的会话历史（`~/.claude/projects`）或被允许篡改自己的安全配置（`~/.claude/settings.json`）。

      
Aegis Enforced Runtime 通过三项精巧的系统设计彻底解决了上述矛盾：

      
### 3.1 保留 `--ro-bind / /` 的发行版兼容遮蔽 + 路径重映射（Path Remapping）

      
如果放弃根目录只读绑定而尝试手工枚举 `/usr`、`/lib`，在 NixOS（`/nix/store`）、Linuxbrew（`/home/linuxbrew/.linuxbrew`）、Snap 或自定义 CA 证书路径下极易触发 `ENOENT` 与 TLS 握手失败。因此，我们在 Linux 下保留 `--ro-bind / /` 保证 100% 发行版二进制兼容，紧接着使用 `--tmpfs` 彻底遮蔽 `/home`、`/root`、`/run`、`/var`、`/tmp`、`/mnt`、`/media` 与 `/etc` 敏感凭据文件，最后按最小白名单把 **CoW 影子工作区原路径挂载到 `/home/user/project`**，而把宿主机真实项目只读挂载到 `/aegis/host/project`。这样，Agent 无论使用原生工具还是直接 `python -c "open('src/main.rs', 'w')"`，它以为自己在改宿主路径，实际上全部落入了隔离的 CoW 影子层！

      
### 3.2 只读 `.git` 对象库穿透与 `GIT_INDEX_FILE` 会话索引分离

      
开发者和 Agent 高度依赖 `git status`、`git diff`、`git log` 与状态栏分支显示。如果为了省事在影子目录拷贝中排除 `.git`，所有 Git 命令都会崩溃；但如果把整个 `.git` 拷贝一份，大型仓库会增加数百 MB 的启动开销；如果直接把宿主 `.git` 可写暴露给沙箱，Agent 写入 `.git/hooks/pre-commit` 或 `.git/config` 的 `core.fsmonitor` 就会在宿主机上实现远程代码执行（RCE）。

      
Aegis OS 的解法是**“只读对象库 + 独立可写暂存区索引 + 安全 Git Shim”**：

      
```
# 1. 宿主 .git 整个只读挂载到沙箱工作区（objects / refs / HEAD 零拷贝可见，hooks / config 不可写）
bwrap ... --ro-bind /aegis/host/project/.git /home/jz/project/.git

# 2. 会话启动时复制单文件 .git/index 到沙箱私有目录，并通过环境变量重定向写入
cp /aegis/host/project/.git/index ~/.aegis/sessions/$SESSION_ID/git-index
export GIT_INDEX_FILE="$HOME/.aegis-git-index"
export GIT_OPTIONAL_LOCKS=0
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null

# 3. 内置 Git 安全 Shim 强制注入禁用外部执行器参数，拦截 commit/push 引导至 aos commit
git -c core.fsmonitor=false -c core.hooksPath=/dev/null status --no-ext-diff
```

      
如此一来，`git status` 与 `git diff` 在 10 万文件级仓库中依然瞬时响应且需要刷新 stat 缓存时只写沙箱私有的 `.aegis-git-index`，宿主机 `.git/index` 的 `mtime` 纹丝不动，且任何恶意的仓库级 Git Hook 均无法被安装或触发。

      
### 3.3 Agent 状态目录的“单文件只读锁（Config Lock）”

      
CLI Agent 在运行期必须写入会话日志、Todo 列表与 OAuth 刷新令牌（如 `~/.claude/projects/*.jsonl`、`~/.codex/sessions`、`~/.local/share/opencode` 的 SQLite），但绝不能允许它修改 `~/.claude/settings.json`、`~/.gemini/config/hooks.json` 或 `~/.codex/config.toml`。我们利用 Linux Mount Namespace 的顺序覆盖特性：**先按需可写挂载状态子目录（`projects/`、`todos/`），再在顶层对敏感配置文件执行单文件 `--ro-bind` 只读覆盖**——既保障了客户端完整有状态体验，又从内核层封死了“Agent 篡改自身配置摘除监管”的逃逸路径。

      
> **[Diagram]** 图 2：`aegis-os run` 父进程沙箱的内核挂载拓扑与两层网络出站代理架构。

      
## 04. Effect 驱动策略与两层出站网关：区分 CONNECT 隧道与 Base URL 反向代理

      
传统安全工具常犯的另一个错误是**“对命令字符串做正则匹配审批”**。但在真实工程中，“命令（Command）”不是安全原语，“效果（Effect）”才是——`cargo test` 会在影子工作区内读写数百个文件并编译执行测试二进制，只要它被严格限制在 CoW 影子和只读工具链内，就不应该弹窗打扰用户；相反，一次看似简单的文件写入如果触碰了 `.github/workflows/release.yml` 或 `build.rs`，在提交回宿主机时就属于高危的持久化投毒（Commit-Time Poisoning）。

      
因此，Aegis OS 将所有底层动作统一抽象为 `(EffectKind, ResourceScope, Reversibility)` 三元组：影子区内的可逆读写（`Reversible`）默认静默放行并自动建立快照；只有跨越边界的不可逆动作（`workspace.commit`、`workspace.commit_sensitive`、访问项目外 `$HOME` 路径或未授权外网连接）才进入 Cedar 策略引擎与人类租约审批。

      
在网络出站（Egress）治理上，我们也摒弃了“把 HTTPS CONNECT 代理吹嘘成全能 L7 DLP”的不诚实做法。标准 HTTPS `CONNECT` 是端到端 TLS 加密隧道，代理只能看到 `host:port`，根本看不到 HTTP Method（GET/POST）、URL Path 或 Request Body。因此，Aegis OS 明确划分了**两层默认出站网关 + 一层可选扩展**：

      

        - **L4 `CONNECT` 隧道模式（默认覆盖包管理器与通用 HTTPS）**：策略动作对应 `net.connect`（如 `net:registry.npmjs.org:443`）。仅执行零延迟的域名/端口白名单与流量字节统计，绝不伪造 Method 审计，也不破坏任何客户端的 TLS 证书固定（Certificate Pinning）。

        - **L7 `Base URL` 反向代理模式（推荐用于大模型与核心 SaaS API）**：由 Launcher 自动注入 `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` 指向沙箱本地网关。客户端到网关走本地环回 HTTP，网关再以 TLS 连接真实上游并完成**边界密钥代填（Agent 进程内永远拿不到真实的 `ANTHROPIC_API_KEY` 明文）**、HTTP Method/Path 审计（`net.request`）与请求体敏感信息（PHI / 密钥）DLP 拦截，同时对 SSE 流式响应保持零首 Token 缓冲延迟。

        - **Opt-in MITM 模式（仅限企业显式声明域名）**：仅对列入 `mitm_domains` 的目标签发会话级 CA 并注入信任链，若遇证书 Pinning 失败则显式告警降级，绝不静默假装存在 DLP。

      

      
## 05. 跨领域通用事务流水线与无破坏 TUI 审批（DECSTBM / OSC / 离线租约）

      
今天知识工作者的 Agent 早已走出纯代码仓库（Code），广泛进入学术论文与标书（Documents）、临床与生物统计数据集（Data）、设计图与医学影像（Binary）以及在线业务系统（AppState）。如果一套运行时只会保护 `git diff`，在面对非代码场景时就会退化回裸奔状态。

      
Aegis Enforced Runtime 将底层的 **`shadow → verify → approve → land`** 提交流水线抽象为可插拔的领域配置（`DomainProfile`）：

      

        - **Code & Documents（代码与 Markdown/LaTeX 手稿）**：采用四级 LCS 三路自动合并；预检门（`verify_cmd`）在沙箱内执行 `cargo test` 或 `latexmk -pdf` + 死链检查；Office 文档（`.docx` / `.pptx`）在 Phase 5 对接 Heurion 双表面 CRDT 的块级锁与 `patchParagraph` 字节级补丁。

        - **Binary（二进制图表、PDF、TIFF 影像）**：天然不可按行合并。强制执行 `coord_claim` 排他文件锁 + 影子创建时的**基线 SHA-256 哈希锚定（Baseline Hash Guard）**，任何覆盖宿主二进制资产的提交必须通过 `overwrite_binaries` 单次审批并附带新旧哈希对比证据。

        - **Data & Org CAS（科研数据集与跨智能体产物总线）**：上游清洗智能体必须通过沙箱内的 Schema 校验与 `scanPhi --strict` 隐私扫描后，将产物发布至不可变的 SHA-256 内容寻址总线（`org_artifact_publish`），从机制上杜绝下游智能体读取未完成的半成品文件。

      

      
> **工程细节决定成败：为什么审批绝不能直接往活跃 TUI 的 stderr 写文本？**: 当 Claude Code、OpenCode 或 Codex 正在全屏 Alternate Screen / Raw Mode 下渲染高帧率 TUI 时，如果父进程沙箱直接往同一个 PTY 的 `stderr` 打印审批提示或争抢 `[a]pprove / [d]eny` 键盘输入，会瞬间导致终端花屏与输入死锁。因此，Aegis OS 在检测到全屏 TUI 活跃时，**严禁向主屏幕直接写入审批字符**，而是通过桌面通知、终端 `OSC 0` 标题栏闪烁提示（`⏳ Aegis: 1 approval pending`）、另一终端的 `aegis-os approve` CLI 或带 SHA-256 Diff 锁定的本地 Web 审批台完成场外确认；在纯 SSH 场景下则可选使用 `DECSTBM` 划定顶部 1 行独立状态栏。只有尊重每一个系统工程细节，内核级安全边界才能真正成为开发者每天愿意默认开启的基础设施。

## 核心技术问答 (Technical FAQ)

### Q: 为什么 Claude Code、OpenCode 或 Codex 的插件（PreToolUse Hook + MCP）不能作为严格的安全边界？
因为插件与被监管的 Agent 主进程运行在同一个宿主机用户权限域（相同 UID 与系统调用面）中。在对抗性提示词注入或配置漂移下，Agent 可能调用未列入 Hook 的原生工具（如 NotebookEdit）、连接沙箱外已运行的共享守护进程（OpenCode --attach）、修改自身的 ~/.claude/settings.json 摘除 Hook，或借由看似只读的 git status / cargo test 触发宿主机上的恶意 .git/config fsmonitor 与 build.rs 脚本。因此插件模式属于 Advisory（建议级生产力护栏），真正的安全边界必须由 aegis-os run 作为父进程通过 OS 内核沙箱（Enforced / Isolated）强制实施。

### Q: aegis-os run 如何在禁止 Agent 篡改宿主机 .git 与自身配置的同时，保留正常的 git status 和客户端会话历史？
Aegis OS 采取两项内核级分层挂载设计：（1）将宿主机 .git 目录只读绑定（--ro-bind）到影子工作区以零拷贝共享 objects/refs，同时将单文件 .git/index 复制到沙箱私有目录并通过 GIT_INDEX_FILE 环境变量指向该副本，配合安全 Git Shim 禁用 core.fsmonitor 与 hooksPath；（2）对 ~/.claude/projects、~/.codex/sessions 等运行期状态子目录按需可写挂载，随后在顶层对 ~/.claude/settings.json、~/.gemini/config/hooks.json、~/.codex/config.toml 执行单文件 --ro-bind 只读锁定，防止 Agent 自篡改配置。

### Q: 为什么不能用标准 HTTPS CONNECT 代理宣称具备 L7 DLP 与请求方法审计？Aegis OS 如何解决？
标准 HTTPS CONNECT 是端到端 TLS 加密隧道，代理只能观测到 host:port 与流量字节数，无法看到 HTTP Method（GET/POST）、URL Path 或 Request Body。Aegis OS 诚实区分两层默认出站网关：对通用 HTTPS 与包管理器采用零延迟的 L4 CONNECT 隧道（仅评估 net.connect 域名/端口白名单，不破坏证书 Pinning）；对大模型与核心 SaaS API 则通过注入 ANTHROPIC_BASE_URL / OPENAI_BASE_URL 采用 L7 反向代理模式（评估 net.request、在边界代填 API 密钥使沙箱内零明文凭据，并执行请求体 DLP 扫描与 SSE 零缓冲流式转发）。
