カーネルはツールの名前など気にしない
The kernel does not care what you named the tool (cognivisehub.com)
要約
コーディングエージェントにおける「良心」に基づいたガードレールは、エージェントの実行がツールのスキーマを離れると容易に回避される。真のセキュリティ境界はカーネルレベルのシステムコールにあり、AgentGuardはeBPF LSM(Linux Security Module)を使用して、エージェントの意図ではなく実際のシステムコールを監視し、拒否をEPERMエラーとしてカーネルレベルで強制する。
全文翻訳
カーネルはツールの名前に無関心
AgentGuard: コーディングエージェント向けのeBPF LSM。リポジトリにYAMLポリシーを格納。拒否はEPERM。
Linuxプロトタイプ · Apache-2.0 · github.com/AgentGuard-hq/AgentGuard
エージェントに失敗したテストの修正を依頼したとします。GitHubのイシューは普通に見えました。しかし、フィクスチャ、MCPの応答、あるいはモデルが親切に取得してきたREADMEの中に、.envを読み込んでどこかに投稿せよという指示が隠されていました。
モデルは、機密情報は範囲外であることに同意するかもしれません。しかし、それはセキュリティ境界ではありません。境界とは、openatが成功するかどうかです。
コーディングエージェントは、より洗練されたプロンプトを持つチャットボットではありません。それらはopen、exec、connectを実行します。重要なのは次のトークンではなく、次のシステムコールの失敗です。
良心はTCB(Trusted Computing Base)ではない
ほとんどのガードレールはエージェントの内部に存在します:
- システムプロンプト
CLAUDE.md/AGENTS.mdPreToolUseフック- 「Bash」文字列の許可リスト
これらは「良心」です。良心は、実行がツールのスキーマを離れた瞬間に迂回されます。
フックで.envを拒否しても、python -c、perl、node、ローダー、mmapなど、カーネルが定義するReadやBash以外の方法で読み取ることができます。コマンド文字列としてrmを拒否しても、別の方法で同じinodeにアクセスできます。フックは実行されませんでした。しかし、もしカーネルにそれを要求されていれば、カーネルは依然としてそれを実行したでしょう。
ベンダーのサンドボックス(Seatbelt、bubblewrap、Claudeのsandbox-runtime、devcontainers)は、ほとんどの人にとって適切な製品デフォルトです。この投稿は、より狭い主張をします:
エージェント自身の良心が偽りの場合でも真実であり続けるポリシー。
そのレイヤーがLSMです。拒否はEPERMです。OSは、ツールの名前が何であれ気にしません。
AgentGuardとは
AgentGuardは、コーディングエージェント向けのLinux eBPF LSMスーパーバイザーです。1つのバイナリがポリシーをカーネルにロードし、エージェントをrootではなく呼び出し元ユーザーとして開始します。
ポリシーはプロジェクト内のYAMLファイル(policies/default.yaml)で定義されます。開始ルール:
- 認証情報 —
.env、id_rsaなど、通常の機密パスをブロックします。 - 破壊的なargv —
rm、ddなど、明白なものをブロックします。 - Egress — 443ポートへの許可リストに登録されたホスト、またはローカルプロキシ経由のみを許可します。それ以外はすべて拒否します。
拒否は、チャットメッセージではなくカーネルエラーです。オプションで、Claude Code / Codexフックはfeedback:文字列を注入するため、モデルは生のパーミッションエラーでスピンする代わりに適応できます。フックが欠落している場合でも、カーネルはブロックし続けます。モデルは理由を知らないだけです。
この分離が設計全体です:
| レイヤー | ジョブ |
|---|---|
| LSM | 強制。デフォルトで失敗(Fail closed)。 |
| git上のYAML | PRでレビューできるポリシー。 |
| フック | 説明。丁寧さ。TCBではない。 |
policies/default.yaml
│
▼
eBPF LSM (rootとしてロード)
│
▼
エージェント (SUDO_USERとして実行)
│
├── openat(".env") → EPERM
├── execve("rm", …) → EPERM
└── connect(許可リストにない:443) → EPERM
│
└── オプション: TUIへの "SYSTEM FEEDBACK: …"
ステータス:v0.1.2、初期段階。主にClaude Codeでテスト済み。Codexも同様に接続されています。ネイティブDarwinのclaudeは監視されていません — macOSにはBPF LSMがありません。Colima/Docker Linux VMは、ホストバイナリの周りの魔法の光輪ではなく、別のマシンです。
なぜ他のフックではなくEPERMなのか
フックは製品がシリアライズした意図を検査します。LSMはプロセスが何をしたかを検査します。
Bashのみをラップしても、pythonはラップしていません。CLIのReadツールのみをラップしても、エージェントが起動したコンパイラ、テストランナー、またはpostinstallスクリプトからのopenatをラップしていません。子プロセスはLSMを継承します。それらはあなたのsettings.jsonを継承しません。
これも、AgentGuardが「プロンプトインジェクション検出」ではない理由です。インジェクションは、悪いシステムコールに到達する方法です。興味深いのは、システムコールが許可されているかどうかです。「以前の指示を無視せよ」というあらゆるエンコーディングをキャッチするのは言語の問題です。.ssh/id_rsaに対するopenatをキャッチするのはカーネルの問題です。両方欲しいです。最初のものが2番目のものを置き換えると偽るつもりはありません。
特権について、率直に
BPFのロードは、重い特権です。通常はロード時にroot権限、CAP_BPFが関与します。
私が譲れないと考える2つのルールがあります:
- LSMのみ。 スーパーバイザーは、エージェントのTLSスタックにトレーシングプローブをアタッチしたり、ユーザー空間バッファを書き換えたりしてはなりません。モデルが「見た」ものを「助ける」ために変更する必要がある場合、あなたはもはや参照モニターではありません。
- オブジェクトをピン留めし、子からキャップをドロップする。 ハッシュ不一致の場合は
doctorが失敗するべきです。エージェントはCAP_BPFを保持してはなりません。ボックス上の2番目のトレーシングプログラムは、スーパーバイザーのピアであり、YAMLで削除できる子ではありません —bpf()/ プログラムタイプもゲートしない限り。
「eBPFを使用した」と「私たちを信頼できる」は同じ文ではありません。前者はメカニズムです。後者はTCBの物語です:ハッシュ化されたプログラム、許可リストに登録されたタイプ、追加ヘルパーなし、通常のユーザーとして実行されるエージェント。
install.shはlsm=bpfを生成できません。それは起動時の事実です。doctorがLSMリストにBPFがないと表示する場合、それはカーネルコマンドラインであり、欠落しているマウントではありません。Securityfsが読み取り可能であることは、強制力があることと同じではありません。
非目標(意図的)
AgentGuardは以下ではありません:
- AnthropicのSeatbelt / bubblewrapサンドボックス、MDM、またはWeb上のClaude Codeの代替品
- Macネイティブの強制ツール
- ホストされたマイクロVM製品(E2B/Daytona/Modalなど)
- 完全な脱獄 — デフォルトのYAMLはスターターであり、完全性はポリシーの問題です
- ランダムなラップトップカーネルでの特権なしのインストール
脅威モデルが「信頼できないリポジトリ、ラップトップを破壊しないで」である場合、まず第一者のサンドボックスまたはVMから始めてください。この種のものは、あなたがすでに制御しているLinuxボックス上で、エージェントに依存しない、監査可能なシステムコールポリシーが必要な場合に使用してください。
AgentGuardという名前のGitHubリポジトリは他にも多数あります。これはカーネル側のものです。名前の衝突は迷惑ですが、主張とは無関係です。
「動作する」とはどういうことか
私が気にかけているデモは、漫画のような脱獄ではありません。
- フックと
CLAUDE.mdは次のように述べています:.envを読み取らない、rm -rfを実行しない。 - プロンプトは普通です:テストをデバッグする / イシューを要約する。
- バイパスはフックが購読したツールを通過しません。
- フックのみの場合:機密情報はコンテキスト内にあり、またはファイルは削除されています。
- LSM:
EPERM。プロセスはまだ生きています。オプションのfeedback:により、モデルはクリーンに再試行できます。
フックパスで失敗し、LSMパスで保持できることを示せない場合、私は製品を持っていません。余分なステップを持つポリシーコンパイラを持っているだけです。
なぜこれが存在するのか
コーディングエージェントの安全性が、Linux上の他のすべてのプロセスと同じレイヤー、つまりLSM、デフォルトで失敗(fail closed)、gitでのポリシー管理で実現できるかどうかを知りたかったのです。
プロトタイプは、通常のカーネルの制約(BTF、lsm=bpf、ロード時のsudo、Darwinの奇跡なし)を伴いますが、はい、と述べています。
業界は、工業規模で良心を出荷しています。それらのいくつかは良い良心です。それでも、良心が疲れていたり、混乱していたり、プロンプトに注入されたりしたときに、ドアがロックされることを望みます。
フックはエージェントの良心です。
カーネルはドアです。
AgentGuardはApache-2.0、v0.1.2、Linuxです。コードとより詳細なエンジニアリングノート:github.com/AgentGuard-hq/AgentGuard。