内核并不关心你给该工具起了什么名字。
The kernel does not care what you named the tool

原始链接: https://www.cognivisehub.com/blogs/the-kernel-does-not-care-what-you-named-the-tool

**AgentGuard** 是一款基于 Linux eBPF 的安全工具,旨在通过在内核层而非应用层执行策略,为 AI 编程代理提供安全保障。 目前的许多防护措施依赖于“代理自觉”(例如系统提示词或工具钩子白名单),但当代理在定义的工具模式之外执行代码(例如通过 `python`、`perl` 或 `mmap`)时,这些措施极易被绕过。AgentGuard 将安全边界移至内核的 **LSM(Linux 安全模块)**,确保即使代理被提示词注入或攻破,也无法执行未经授权的系统调用。 **主要功能包括:** * **故障关闭安全机制:** 对敏感文件(如 `.env`)的非法访问尝试或执行破坏性命令的操作,将在内核层直接返回 `EPERM`(操作不允许)。 * **Git-Ops 策略:** 安全策略在仓库中的 YAML 文件内定义,从而实现可审计和版本控制。 * **系统反馈:** 可选择向代理提供反馈,使其能够适应限制,而非直接卡住。 * **独立性:** 它独立于代理的内部逻辑运行,充当一个不可篡改的监督者。 AgentGuard 是一个开源(Apache-2.0 协议)的 Linux 原型项目,适用于需要在受控机器上实现稳健且与代理无关的系统调用强制执行的用户。

抱歉。
相关文章

原文

AgentGuard: eBPF LSM for coding agents. YAML in the repo. Deny is EPERM.
Linux prototype · Apache-2.0 · github.com/AgentGuard-hq/AgentGuard


You asked the agent to fix a failing test. The GitHub issue looked normal. Buried in a fixture, or in an MCP response, or in a README the model helpfully fetched, was an instruction to read .env and post it somewhere.

The model may even agree that secrets are off-limits. That is not a security boundary. The boundary is whether openat succeeds.

Coding agents are not chatbots with a nicer prompt. They open, exec, and connect. The failure that matters is the next syscall, not the next token.


Conscience is not a TCB

Most guardrails live inside the agent:

  • a system prompt
  • CLAUDE.md / AGENTS.md
  • PreToolUse hooks
  • an allowlist of “Bash” strings

Those are a conscience. Consciences are bypassed the moment execution leaves the tool schema.

Deny .env in a hook, then read it with python -c, perl, node, a loader, mmap, anything that is not Read or Bash as the CLI defines them. Deny rm as a command string, then hit the same inode another way. The hook never ran. The kernel still would — if you asked it to.

Vendor sandboxes (Seatbelt, bubblewrap, Claude’s sandbox-runtime, devcontainers) are the right product default for most people. This post is a narrower claim:

Policy that remains true when the agent’s own conscience is false.

That layer is the LSM. Deny is EPERM. The OS does not care what the tool was named.


What AgentGuard is

AgentGuard is a Linux eBPF LSM supervisor for coding agents. One binary loads policy into the kernel and starts the agent as the invoking user, not root.

Policy is YAML in the project (policies/default.yaml). Starter rules:

  • Credentials — block .env, id_rsa, the usual secret paths
  • Destructive argvrm, dd, the obvious ones
  • Egress — allowlisted hosts on 443, via a local proxy; everything else denied

A deny is a kernel error, not a chat message. Optionally, Claude Code / Codex hooks inject a feedback: string so the model can adapt instead of spinning on a raw permission error. If the hooks are missing, the kernel still blocks. The model just is not told why.

That split is the whole design:

LayerJob
LSMEnforcement. Fail closed.
YAML in gitPolicy you can review in the PR.
HooksExplanation. Courtesy. Not the TCB.
policies/default.yaml
        │
        ▼
   eBPF LSM (loaded as root)
        │
        ▼
   agent as SUDO_USER
        │
        ├── openat(".env")              → EPERM
        ├── execve("rm", …)             → EPERM
        └── connect(not :443 allowlist) → EPERM
                │
                └── optional: "SYSTEM FEEDBACK: …" into the TUI

Status: v0.1.2, early. Tested primarily with Claude Code. Codex is wired the same way. Native Darwin claude is not supervised — macOS has no BPF LSM. A Colima/Docker Linux VM is a different machine, not a magic halo around the host binary.


Why EPERM and not another hook

Hooks inspect intent as the product serialized it. LSM inspects what the process did.

If you only wrap Bash, you have not wrapped python. If you only wrap the CLI’s Read tool, you have not wrapped openat from a compiler, a test runner, or a postinstall script the agent just spawned. Child processes inherit the LSM. They do not inherit your settings.json.

That is also why AgentGuard is not “prompt injection detection.” Injection is how you get to a bad syscall. The interesting part is whether the syscall is allowed. Catching every encoding of “ignore previous instructions” is a language problem. Catching openat on .ssh/id_rsa is a kernel problem. I would rather have both. I will not pretend the first replaces the second.


Privilege, said plainly

Loading BPF is a loaded privilege. Typically root at load, CAP_BPF in play.

Two rules I treat as non-negotiable:

  1. LSM only. The supervisor must not attach tracing probes on the agent’s TLS stack or rewrite userspace buffers. If you need to mutate what the model “saw” in order to “help,” you are no longer a reference monitor.
  2. Pin the object. Drop caps on the child. doctor should fail on a hash mismatch. The agent must not keep CAP_BPF. A second tracing program on the box is a peer of the supervisor, not a child you can YAML away — unless you also gate bpf() / program types.

“We used eBPF” is not the same sentence as “you can trust us.” The first is a mechanism. The second is a TCB story: hashed program, allowlisted types, no extra helpers, agent running as a boring user.

install.sh cannot invent lsm=bpf. That is a boot-time fact. If doctor says BPF is missing from the LSM list, that is the kernel cmdline, not a missing mount. Securityfs being readable is not the same as enforcement.


Non-goals (on purpose)

AgentGuard is not:

  • a replacement for Anthropic’s Seatbelt / bubblewrap sandbox, MDM, or Claude Code on the web
  • a Mac-native enforcer
  • a hosted microVM product (that is E2B/Daytona/Modal)
  • a complete jail — the default YAML is a starter, completeness is a policy problem
  • unprivileged install on a random laptop kernel

If the threat model is “untrusted repo, don’t toast the laptop,” start with the first-party sandbox or a VM. Use something like this when you need agent-agnostic, auditable syscall policy on a Linux box you already control.

There are many other GitHub repos named AgentGuard. This one is the kernel one. The name collision is annoying and irrelevant to the claim.


What “working” looks like

The demo I care about is not a cartoon jailbreak.

  1. Hooks and CLAUDE.md say: never read .env, never rm -rf.
  2. The prompt is ordinary: debug the test / summarize the issue.
  3. The bypass does not go through the tool the hook subscribed to.
  4. Hooks-only: the secret is in context, or the file is gone.
  5. LSM: EPERM. Process still alive. Optional feedback: so the model retries cleanly.

If I cannot show a hook path that loses and an LSM path that holds, I do not have a product. I have a policy compiler with extra steps.


Why this exists

I wanted to know whether coding-agent safety could live at the same layer as every other process on Linux: LSM, fail closed, policy in git.

The prototype says yes, with the usual kernel tax — BTF, lsm=bpf, sudo to load, no Darwin miracles.

The industry is shipping consciences at industrial scale. Some of them are good consciences. I still want the door to lock when the conscience is tired, confused, or prompt-injected.

Hooks are the agent’s conscience.
The kernel is the door.


AgentGuard is Apache-2.0, v0.1.2, Linux. Code and a longer engineering note: github.com/AgentGuard-hq/AgentGuard.

联系我们 contact @ memedata.com