eBPF を活用した AI と API の魔法のような機能強化に関するプレゼンテーション
本文の状態
日本語全文を表示中
詳細モードで約48分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
InfoQ AI/ML
カーネルレベルのソケットフックを活用することで、アプリケーションソースコードを変更したりコンテナを再起動したりせずに AI API トラフィックを監視・制御できる。
AI深層分析を開く2026年8月21日 22:30
AI深層分析
キーポイント
eBPF による非侵入型制御
カーネルレベルのソケットフックを活用することで、アプリケーションソースコードを変更したりコンテナを再起動したりせずに AI API トラフィックを監視・制御できる。
具体的なセキュリティ機能
プロンプトのフィルタリング、モデルの動的切り替え(スワッピング)、トークン数の制限、およびシステムコールの制限といった機能を透明に実装可能である。
未所有コードのリスク管理
本発表は、生産環境で生成された AI コードが誰のものか不明確な状態(unowned)にあるリスクを指摘し、それを eBPF で制御することで緩和するアプローチを示す。
クラウドネイティブ環境への適応
Kubernetes 環境において、AI エージェントのセキュリティを担保するための実用的なアーキテクチャと運用手法が提案されている。
eBPFの普及と用途
eBPFはLinuxカーネルの一部であり、Android端末でも無意識に利用されている技術である。
重要な引用
Dan Finneran discusses the risks of unowned AI-generated code in production and demonstrates how eBPF can intercept and control AI API traffic in Kubernetes.
He explains how kernel-level socket hooks enable transparent prompt filtering, model swapping, token limits, and syscall restrictions to secure AI agents without modifying application source code or restarting containers.
If you have an Android phone on you right now, you will be running and using eBPF without actually realizing it.
Cilium is networking for Kubernetes clusters, and eBPF is a technology that is part of the Linux kernel.
編集コメントを表示
編集コメント
アプリケーションコードの変更を伴わない AI セキュリティ制御というアプローチは、急速に進化する AI エージェント運用において極めて実用的な価値を持つ。特に Kubernetes 環境での導入コストとリスクを最小化できる点は、現場の技術責任者にとって重要な示唆となる。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
https://www.infoq.com/ | プレゼンテーション
eBPF の魔法で AI と API を魅了する 🪄
プレゼンテーションを見る
再生時間:
ダウンロード
49:54
/presentations/ebpf-ai-gateway-kubernetes-security/en/slides/slide-1786345389423.jpg)
概要
Dan Finneran は、本番環境で所有権が不明な AI 生成コードのリスクについて議論し、eBPF を用いて Kubernetes 内の AI API トラフィックをインターセプトして制御する方法を実演します。カーネルレベルのソケットフックを活用することで、アプリケーションソースコードの変更やコンテナの再起動なしに、プロンプトのフィルタリング、モデルの切り替え、トークン数の制限、システムコール(syscall)の制限などを透明に行う仕組みを解説し、AI エージェントのセキュリティを強化します。
登壇者紹介
Dan Finneran は Cisco の Isovalent でシニアコミュニティ・アデボケートを務めています。これまでに物理サーバー、jails、zones、VM、コンテナなど多様な環境で経験を積み、現在はクラウドネイティブ分野の急速な変化の中で活躍しています。また、Kubernetes 向けの人気オープンソースロードバランサーの開発・保守を行い、アップストリームの Kubernetes プロジェクトにも貢献しています。
コンファレンスについて
ソフトウェアは世界を変えています。QCon London は、開発者コミュニティにおける知識とイノベーションの普及を促進することで、ソフトウェア開発を支援します。実践者が主導するこのカンファレンスは、チーム内でイノベーションに影響を与える技術リーダー、アーキテクト、エンジニアリングディレクター、プロジェクトマネージャーを対象に設計されています。
INFOQ EVENTS
2026 年 8 月 27 日(木)午後 1 時 EDT
スケーラビリティの壁:AI エージェントが失敗する理由、それは文脈を扱うデータレイヤーの問題だ
登壇者:Boyd Stowe 氏(Tacnode 創設ソリューションアーキテクト)
2026 年 9 月 17 日(木)午後 1 時 EDT
PR を超えて:エージェント型ソフトウェアデリバリーのための新たなコントロールプレーン
登壇者:Mohit Suman 氏(Harness スタッフプロダクトマネージャー)
トランスクリプト
ダン・フィネラン氏:本日は AI と API、そして比較的低レベルな技術である eBPF についてお話しします。必要であれば eBPF のコードを見ていただくこともできますし、eBPF がどのように動作するかを概説することも可能です。皆様にとって有益な内容であれば、何でも掘り下げてご説明いたします。
自己紹介をさせていただきますと、私は現在シスコシステムズ傘下の企業である Isovalent に所属しており、主に eBPF や Cilium プロジェクトといった技術の理解促進に注力しています。これらはいずれもオープンソースプロジェクトです。Cilium は Kubernetes クラスター向けのネットワークソリューションであり、eBPF は Linux カーネルの一部として実装された技術です。
もし今お持ちのスマートフォンが Android 端末であれば、気づかずに eBPF を実行・利用していることになります。また、私の趣味の時間には CNCF(Cloud Native Computing Foundation)に所属するクラウドネイティブベースのソリューションを多数開発してきました。具体的には Kubernetes クラスター向けのソフトウェアロードバランサーや、同クラスターのベアメタル環境向けプロビジョニングツールなどです。
本講演では、クラウドネイティブ業界および Kubernetes における動向に加え、実際の運用環境やデプロイメント現場で起きている変化についてお話しします。ご存知の通り、現在コードが以前にも増して急速に生成されるようになっています。多くの人々が AI に指示を出し、「これをしてほしい」と依頼するだけで、AI が大量のコードを出力し、作業は完了という状況です。
しかし、そのコードを理解し、責任を持って引き受けることとの間には、大きな隔たりが生じています。私は複数のオープンソースリポジトリを管理していますが、ここに来て AI によって生成されたプルリクエストが急増しているのを痛感しています。これは素晴らしい現象で、新しい機能や高品質なコードが追加されるケースも多々あります。
ただ、私がこれらの PR を提出した開発者に「このコードについて説明してほしい。どのように動作するのか、今後どうサポートしていくのか」と尋ねると、通常は返事がなく、連絡が取れなくなってしまう(ゴーストされてしまう)ことがほとんどです。
彼らからの連絡が途絶えてしまうケースも少なくありません。これは大きな問題です。自分が書かないコードを突然 1,000 行も受け入れてしまい、その中身を理解していない場合、今後誰がそれをサポートするのでしょうか?この問題は徐々に深刻化しています。
コードがいきなり本番環境に登場する事態が起きているのです。誰かが思いついたアイデアを即座に「バイブコーディング」したり、AI に生成させたりしてそのまま本番へ投入されるケースです。するとあっという間に、そのコードに対するビジネス上の依存関係が生まれます。しかし、誰が書いたのか、どのように動作するのか、そして今後誰がサポートするのかが誰もわからない状態になります。このように、責任所在と理解度のギャップが広がっているのです。
さらに別の問題もあります。AI プログラムの振る舞いに関する懸念です。最近では、カレンダーやファイルシステム、さらにはノートパソコンといった重要な領域を AI エージェントに委譲する事例が増え、それに伴うリスクについて多くの議論が行われています。
過去には、Terraform の destroy コマンドを実行した結果、本番環境が削除されたり、フォルダやソースコードまで消滅したりする事例がありました。これは「支援しているつもり」で行われた悲劇です。
こうしたプログラムを本番環境に投入した後、どうやって監視し、理解し、挙動を変更すればよいのでしょうか?そして、現状を正しく把握した上で、必要な対策を講じた後、最も適切な実装方法とは何でしょうか。
今日私が紹介するのは、まさにそのための概念実証(PoC)です。Kubernetes の世界では現在、「AI ゲートウェイ」の構築を中心とした新しいワーキンググループが活動しています。このグループは、Kubernetes クラスター内の AI エージェントや AI ベースのプログラムをキャプチャし、理解し、制御するための標準化を進めています。
現在進行中のこの取り組みにおいて、私が今日お見せするのは、その議論に基づいた具体的な実装例です。
アウトライン
本日は、AI エンドポイントに呼び出すアプリケーションの一般的なアーキテクチャとそのコード構成について解説します。また、eBPF についても簡単に紹介します。eBPF は低レベルな技術であり、Linux カーネルを自在に操作できます(Windows カーネルへの対応も近日予定されています)。詳しく掘り下げていきますが、カーネルプログラミングの話になるため、あまり深く立ち入ることは避けたいと思います。
その後、eBPF を活用してこれらのアプリケーションの観測と制御を実現するソリューションの構築について議論します。最後にまとめを行い、デモも行います。
モダンな AI アプリケーション - 進化を続けるプラットフォーム
プラットフォームの進化について、簡単に振り返ってみましょう。現在、Kubernetes をご存知ですか?あるいは、実際に活用されていますか?
私が最近 Cisco の一部門として活動する中で感じたのは、Kubernetes について語る時、まるで誰も知らない顔をしているような不思議な感覚です。スタートアップ文化に身を置く私にとって、周囲の誰もが Kubernetes に精通しているはずなのに、なぜそう感じるのか。
私たちはどうやってこの状況に至ったのでしょうか?
何年も前、CPU はギガヘルツの限界に達し、コア数を増やす方向へ進化を遂げました。同時に、メモリの容量も飛躍的に増加しました。こうした大規模システムを管理するために、我々は古い技術へと回帰し、リソースを分割する必要性に迫られました。
その結果、仮想マシン(VM)がアプリケーションやオペレーティングシステムを実行するための事実上の標準リソースとなりました。しかし、開発者たちは仮想マシンの扱いに苦慮しました。管理が煩雑で、ビルドからデプロイまでの時間が長く、重すぎるという課題があったのです。
2014 年頃、Docker のソロモン・ハイクス氏によって「コンテナ」という概念が生まれました。これはアプリケーションをより高速に実行するための標準化手法であり、コンテナ化することで実行速度の向上やリソース使用量の削減といったメリットを得られます。さらに現在多くの人が実感している通り、Docker などのオープンソース技術へ移行することで、仮想化に伴うライセンス費用を大幅に削減できるという利点もあります。
ただし、これは円環的な話になりますが、実は FreeBSD の jails や Solaris の Zones という形で、私たちははるか以前に同様の仕組みを実装していました。結局のところ、私たちは再び同じ車輪を再発明してしまったのです。
その後は、より高速な処理を実現する進化の話をしましょう。かつては、この分野で競合する複数のプロジェクトが存在していました。
HashiCorp の「Nomad」や、Docker 社自身が開発した「Docker Swarm」、そして Google が立ち上げた「Kubernetes」などが代表的です。私は以前、Docker Swarm のエンジニアとして活動していました。
これらすべての技術とプロジェクトは、アプリケーションのライフサイクル管理を容易にするために存在しています。その恩恵は計り知れません。コンテナのライフサイクルを管理するだけでなく、「アプリを起動し、スケールし、停止して片付ける」という一連の流れを、はるかにスムーズに扱えるようになります。
これまで構築や起動、そして削除と後片付けまでを手掛けてきた経験から言えるのは、仮想化環境を管理してきた人なら誰もが知っている通り、管理が追いつかないまま残された「孤児」の仮想マシンがインフラ上に放置されるリスクは、こうした新しい技術によって劇的に軽減されるということです。
そのようなリソースの所有権を特定しようとすると非常に手間がかかり、管理も困難です。Kubernetes には多くの利点があります。すべてがクラウドネイティブな設計で、インフラ自体の自動スケーリングやアプリケーションの増減による自動スケーリングが可能です。また、これらのアプリケーションの健全性を監視するためのクラウドネイティブなツールも充実しており、管理を容易にしています。
Kubernetes へのデプロイは、まだ行ったことがない方にとって、YAML ベースのテキスト記述が中心となります。具体的には、「このようにアプリケーションを構成したい」という仕様を定義し、特定の要件に基づいて記述します。これを Kubernetes に投げかけると、Kubernetes が自動的に実行してくれます。
裏側では主に 2 つのコンポーネントが存在します。1 つはコントロールプレーン、もう 1 つがワーカーノードです。実際のワークロードが稼働するのはワーカーノード上です。YAML をコントロールプレーンに適用すると、コントロールプレーンが管理するワーカーと通信し、実際にワークロードを実行してくれます。
ここでは Pod が起動している様子が見えます。この Pod 内には 1 つ以上のコンテナが含まれており、例えば Web サーバーやその隣に設置された監視エージェントなどが該当します。これが、Kubernetes クラスターおよびその中で稼働するアプリケーションの典型的なアーキテクチャです。
AI Enabled Code
現在、Kubernetes クラスター内で動作するコンテナ内に AI ベースのアプリケーションが導入され始めています。しかし、それらがどのように機能しているのか、何をしているのかを理解している人はほとんどいません。その実態を把握するためには、API 自体に目を向け、AI との相互作用が実際にはどのようなものかを知る必要があります。
結局のところ、OpenAI や Ollama など、どの LLM(大規模言語モデル)と対話する場合でも、それは単なる API です。やり取りされるのは基本的には JSON データの塊であり、リクエストとレスポンスという形をとります。LLM バックエンドに送るリクエストには、使用したいモデルを指定します。モデルの種類によって生成される応答の内容も異なります。画像や動画の生成に特化したものもあれば、コード生成に関する情報で訓練されたため、コード作成の依頼に対してより適切な回答を返すように設計されているものもあります。
AI が返すレスポンスにはさまざまな種類があります。テキストの場合は、コードの断片として出力されたり、ドキュメント画像の要約を求められたりします。また、「日没のような風景を描いて」といった具体的な指示を出せば、そのイメージに合う画像が生成されて戻ってきます。
最後に重要なのが「プロンプト」です。これは実質的に、あなたが AI に対して行うリクエストそのものを指します。先ほどの例で言えば、「素敵な日没の画像をください」というのがプロンプトになります。LLM はこの指示を受け取り、内部処理を行い、結果としてレスポンスを返す仕組みです。
こうしたリクエストはすべてプロンプトに基づいて成り立っており、その種類も多岐にわたります。一般的にはユーザーが直接求める「ユーザープロンプト」が使われますが、場合によっては「アシスタントプロンプト」を指定することも可能です。例えば、「DALL·E のようなスタイルで」といった指示をアシスタント側に与え、ユーザー側では「このように描いてほしい」と具体的なイメージを伝えるといった使い分けができます。
このアシスタントは、LLM が実際に生成すべき内容の基準を設定する役割を果たします。LLM による応答を生成する際、トークンが一般的に使用されます。リクエストに含まれる処理対象のトークンと、応答として実際に出力されるトークンの両方が存在します。これらは、AI エンドポイントを利用する際に課金対象となる要素です。
さらに、トークンの上限(キャリング)を指定することも可能です。しかし、多くの人がこれを設定しないため、気づかないうちに想定外の高額利用が発生するケースが増えています。この上限を設定することで、コストをコントロールできます。ただし、上限に達した際、LLM はその時点で生成できた内容のみを返すことになります。つまり、応答が不正確になったり、不完全な状態で終了したりするリスクがあります。
最後に、これらの API では通常、推論レベルとして「小」「中」「大」の選択肢が用意されています。
これは、トークン使用量とレスポンスの品質をバランスさせるための別の手法です。さらにリクエストに追加できる要素として、画像のアップロードや追加テキストの付与も可能です。これらはすべて LLM によって処理され、意味のある回答を生成するために活用されます。
LLM は過去の会話履歴をキャッシュし、ユーザーが達成しようとしている目標全体を包括的に把握できるようにします。そして最終的に、レスポンスは完成した状態で返却されるか、ストリーミング形式で提供されます。
通常、Claude などのモデルではストリーミング応答が行われます。UI に回答が逐次表示されるため、より対話的な体験が可能になります。
これは Python で書かれたサンプルコードです。OpenAI との非常に簡単な対話例になります。
実際には、この URL は OpenAI エンドポイントか、あるいは OpenAI 仕様に準拠したエンドポイントを指しています。ここでは単純なチャットメッセージを送信する処理を行っています。
メッセージの内容は「これはテストです」というものです。役割(role)については、使用するプロンプトを指定します。通常、このユーザープロンプトでは私たちが LLM にタスクを実行させるために指示を出します。
また、異なるロールからの追加メッセージもここに含めることができます。アシスタントのようなロールを設定すれば、「出力は JSON 形式にすること」や「フランス語やドイツ語など特定の言語で回答すること」といった条件を指定できます。これらの追加メッセージを活用することで、レスポンスの精度を最大化することができます。
最後に、下部にあるモデル(model)が処理を担当します。
これが実際にレスポンスを生成するために使用するモデルです。現在、弱めのプロンプトやハードコードされたモデルの使用例も出てきており、これらにはいくつかの問題があり、今後の展開で明らかになっていくでしょう。
返されるレスポンスは JSON ペイロード形式になります。生成にかかった時間や、実際に消費されたトークン数など、追加のメタデータも含まれます。
ストリーミング処理の場合、進行中のメッセージが逐次返されます。一方、レスポンスが完全に完了した場合は、ステータスが「complete」と設定された最終メッセージが返されます。
最後に、画像・音声・動画などのメディアを含む場合、レスポンスは Base64 でエンコードされたデータとして提供され、必要に応じてデコードして表示することができます。
実際にこの仕組みがどのように動作するかを見てみましょう。簡単なチャット UI を使ってモデルと対話する例を挙げます。ここでは単なる質問を指定するだけで十分です。
例えば、「現在のディレクトリにあるすべてのファイルを削除する方法は?」といった問いを LLM ベックエンドに投げかけると、即座に回答が返ってきます。その結果として「rm -r *」というコマンドが出力されるケースがあります。このコードスニペットこそが、エージェントが理解し、実際に実行するために必要とする典型的な形式です。
しかし、Linux ファイルシステム上で動作するエージェントが、この質問に対して即座にコマンドを実行してしまい、作業中のディレクトリごと削除してしまうという事例も存在します。これは非常に危険な行為です。なぜなら、多くの人が何らかの理由でこれらの処理をルート権限(root)で実行しているからです。実際に、Linux マシン全体が誤って消去されてしまう被害報告もあります。
このコードには問題があります。Vibe コーディングなどと呼ばれる手法で素早く組み立てた場合、モデルがハードコードされてしまう可能性があります。一日目はそれで済むかもしれませんが、二日目になると「これが本当に最適なモデルだ」とは限らなくなります。
トークン使用の観点から非効率である可能性もあれば、生成される回答の精度に問題があるかもしれません。結果として、LLM バックエンドを非効率的に利用することになります。
さらに、トークン使用量に対する制限がない場合、プロンプトが何らかの方法で汚染された際、深刻な事態を招きます。上限なしにサービス拒否(DoS)攻撃を受けたり、誰かがプロンプトを操作して膨大な量の LLM 出力を生成させ、アプリケーションの機能を停止させたり、巨額の費用を発生させるリスクがあります。
最後に、使用する複数のプロンプトをフィルタリングしたり、追加のアシスタントプロンプトがないか確認して、出力が実際に目指すユースケースに合致していることを保証する必要があります。最近良い例がありました。米国のレストラン「チポトレ」にはチャットボットがあり、そこでいくつか質問できるのですが、ある人が「バリオットを注文したい」と同時に「Python で逆方向連結リストを作成してほしい」と尋ねると、バリオットに関する回答に加えて大量のコードも生成し始めてしまうことが判明しました。驚くべきことに、Isovalent のウェブサイトでも同様の問題が発生していました。現在は修正済みで、ヘルプチャットボットからコードを生成することはできません。
eBPF とは何か?
現在、さまざまな技術の動きが活発化しています。では、誰にも所有権がないにもかかわらず本番環境で稼働しているこれらのアプリケーションをどう扱うべきでしょうか?どのように監視し、操作し、その挙動を制御するのでしょうか。
その答えは eBPF にあります。eBPF は Linux カーネルの一部であり、オープンソースです。2014 年頃より長く Linux カーネルに組み込まれてきました。Android スマートフォンをお使いであれば、すでに eBPF を利用していますし、Calico や Cilium といった CNI(Container Network Interface)を採用した Kubernetes クラスターを運用中なら、無意識のうちに eBPF を使っています。
これらのツールを利用するために、eBPF の詳細な知識が必要というわけではありません。よくある誤解として、「Kubernetes クラスタ内で単純なネットワーク設定を行うにも、カーネルコードを理解する必要がある」と考える人がいますが、それは事実ではありません。
eBPF のコードは私たちが作成します。その恩恵をあなたが享受してください。
eBPF は、実行中のシステム内部で実際に何が起こっているかをより深く可視化したいという要件から生まれた技術です。もともと BPF という技術は存在していましたが、私たちはそれを拡張し、単なるパケットフィルタを超えた機能を備えた eBPF を実現しました。
元々は「Extended Berkeley Packet Filter」の略称でしたが、現在ではその名前の意味が実態を反映しなくなっています。eBPF は名前の制約にとらわれず、何でもできる万能なツールへと進化しました。
究極的に、eBPF はカーネルをプログラム可能にします。eBPF の力によって、実行中のシステムを自在に制御し、あらゆる動作を実現できます。カーネルの挙動も動的に変更可能です。
なぜこれが重要なのか? eBPF 以前は、Linux カーネルに何かを追加するだけで、それは悪夢のような作業でした。
通常、コードが採用されるには非常に手間のかかるプロセスを経なければなりません。多くの人が審査し、チェックを行うのは良いことですが、Linux カーネルに組み込まれるまでには数ヶ月、あるいは数年かかることもあります。最終的には Linus 自身が確認しますが、その際に厳しい指摘を受けたり、結局は採用されなかったりすることさえあります。
仮に上流プロジェクト(upstream)へ取り込まれたとしても、そこから Red Hat のカーネルに反映されるまでにはさらに時間がかかります。その頃には、すでに技術者としてのキャリアを引退しているかもしれません。それほど長い期間がかかるため、誰も面倒くさくなってしまいます。このプロセスではもはや実用的ではありません。
実は、少し立ち返って別の選択肢をお話ししましょう。それがカーネルモジュールです。ただし、カーネルモジュールは特定のカーネル向けにビルドされたものであり、異なるシステム間での移行にはあまり適していません。複数の人が利用可能なカーネルモジュールを作成するのは非常に困難です。
そこで登場するのが eBPF です。eBPF のアイデアは、Linux カーネルや Windows カーネルにフックするコードを書くことで、必要な機能を追加し、柔軟に複数のシステム間で移動できるようにすることにあります。比較的新しいカーネル(5.12 以降、つまり過去 5〜6 年以内にリリースされたもの)であれば、eBPF は特別な設定なしですぐに動作します。
実行中の Linux カーネルの任意の部分にコードを記述してアタッチできるため、本番環境への反映を待ってメインストリームのカーネルに組み込まれるのを待つ必要もありません。
まず、Linux カーネルがファイル、ネットワーク、メモリ、プロセスを操作する仕組みを見てみましょう。eBPF プログラムを作成し、これを Linux カーネル内のさまざまな領域に効果的にアタッチできます。本日は、AI 呼び出しを操作するために eBPF プログラムをネットワークスタックにアタッチする方法について解説します。
eBPF コードは低レベルなもので、Linux カーネルに直接組み込むためのコードです。そのため、安全性とセキュリティが最優先されます。そのために eBPF には専用のツールセットが用意されており、無限ループに陥ったり、カーネルをクラッシュさせたりする可能性を未然に防ぎます。実行中のカーネルに機能を追加するのは確かに怖いことですが、eBPF の仕組みを使えば、そうしたリスクは実質的に排除できます。
eBPF プログラムは多岐にわたる領域にアタッチ可能です。Kprobes(カーネルプローブ)や Uprobes(ユーザーランドプローブ)を利用すれば、ユーザー空間のあらゆる箇所に eBPF を組み込むことができます。
現在、eBPF の主な用途はネットワークパケットの処理です。その他にもハードウェアデバイス、Linux セキュリティモジュール、パフォーマンスイベントなど、多くの領域で活用されています。ファイルシステムに関しても、ブロックデバイスからその上に構築された仮想ファイルシステムに至るまで、さまざまな層にアタッチ可能です。さらに、ネットワークスタック内の多様なポイントや、Linux カーネル内部の特定箇所にさえも接続できます。これにより、実行中の Linux システムに対して、何をすべきか・何をするべきでないかを細かく制御できる強力な能力が得られます。
AI/API ゲートウェイの構築
課題は明確です。実行中のシステムにフックをかけることで、こうした振る舞いを変革できる技術が今や存在します。では、その具体的な姿を見ていきましょう。
まず、Kubernetes 上で動作する AI ゲートウェイを構築するために必要な要素をリストアップします。
第一段階は、AI エージェントプログラム(あるいは同様のもの)から LLM エンドポイントへ向かうトラフィックを、透過的にインターセプトすることです。このトラフィックをユーザーランドのプロキシに透明性を持ってリダイレクトし、そこで内容の修正や変更を行えるようにします。
さらに、すべての AI 関連のリクエストとレスポンスを観察可能にする必要があります。必要に応じてモデルの変更、プロンプトの確認、トークン数の制限などを行い、前述したような問題からシステムを保護する仕組みを整備します。
これらのリクエストを、ルールに基づいてブロックしたい場合もあります。では、eBPF プログラムはどこにアタッチすべきでしょうか?これは非常に重要です。なぜなら、処理できる領域は多岐にわたるからです。
スタックのより下層に位置づけるほど、制御の粒度は細かくなります。しかし、ネットワークカード自体に直接アタッチすることも可能です。具体的には、ネットワークインターフェースカード(NIC)のドライバ内部へ直接接続できます。その場合、得られるのは生フレーム(raw frames)のみとなり、これを操作したり理解したりするのは極めて困難になります。なぜなら、出力されるデータは順序がバラバラになった JSON パケットの集合であり、一部のデータが破損して再送を要するケースもあるからです。対象となるのは特定の 1 つのパケットだけではありません。ボックスへ出入りするすべてのトラフィックが見えてしまうためです。
作業を少し楽にするために、私たちはスタックを一段階高く上げ、ソケット(sockets)領域に接続することを選びます。
プログラムが外部に接続を試み、API を呼び出す先の Web サーバーなど他の IP エンドポイントへダイアルアウトする際、eBPF プログラムはそこでフックインします。これにより、実際に何が起こっているかを把握し、必要な変更を加えることが可能になります。
具体的なイメージとしては、左側のプロセスが AI エージェントとなり、OpenAI への接続を試みます。ユーザーランドでソケットが作成され、必要に応じて iptables を通過し、Linux カーネル内の「トラフィックコントロール(traffic control)」と呼ばれる領域を経て、最終的にネットワークカードへ到達します。こうして通信は必要な宛先へと流れていきます。
eBPF プログラムを接続できる箇所はいくつかあります。最もパフォーマンスに優れているのは NIC ドライバへのフックですが、ここでは生のフレームデータしか得られません。生フレームからアプリケーションが理解できるデータストリームへ変換するのは非常に困難です。トラフィックコントロールも同様に高速ですが、カーネル内部での処理であり、やはり生パケットの扱いになります。
一方、eBPF プログラムをソケットにフックさせることで、カーネル側で実際のデータをすべて処理しつつ、私たちはそのデータストリームを直接監視することが可能になります。
これが実現した際のイメージです。実行中のプロセスがあり、その隣にプロキシという概念を配置します。新しいソケットが作成された際に eBPF プログラムをソケットにアタッチすることで、プロセスは気づかないうちにそのトラフィックをプロキシへリダイレクトされます。すべてが透明に行われます。
また、アプリケーションの再起動を必要としないことも可能です。eBPF プログラムによって強制的に新しい接続が発生し、アプリケーション自体には影響を与えずに再度トラフィックをキャプチャできます。こうしてプロキシ側でこれらのリクエストを確認できるようになります。
通常のリクエストは以下のようになります。ここでは古いモデルを使用しているため、このモデルを差し替える必要があるかもしれません。しかし、アプリケーション側を変更する必要はありません。実際に変更が行われていることにさえ気づきません。これもすべて、アプリケーションに対して透明に行われる処理です。
入力リクエストの変更も検討すべきでしょう。例えば、他の動物に関するジョークではなくキリンに関するジョークが返ってくるようプロンプトを調整したり、特定の領域での出力制限をかけたりするケースです。API を通じてこれらの挙動に対する制御は多岐にわたります。
通常、レスポンスの観点からは以下のような流れになります。トラフィックは AI エージェントから発生し、eBPF によってプロキシへリダイレクトされます。プロキシはその内容を解析し、適用したルールに基づいて必要に応じて変更を加えます。その後、プロキシは元のプロセスに代わって AI プロバイダへ接続し、レスポンスを受信します。
例えば「キリンに関するジョークを一つ教えて」という問いに対し、「AI の大規模言語モデル(LLM)は面白いジョークが苦手だ。彼らの出すジョークはたいてい酷いものだ」といった回答が返ってくるのが典型的なパターンです。
キリンが玩具のジェット機を飲み込んだとき、それを何と呼ぶか?答えは「首の中の飛行機」です。この回答から、生成に必要だったトークンの数がわかります。また、そのすべての情報をフィルタリングすることも可能です。そこへ出入りするすべてのデータを把握する能力も備えています。さらに暗号化の対応も可能です。
アプリケーション間の暗号化を効果的に強制できます。LLM プロセスを Kubernetes クラスター内部で実行している場合、通常は両者の間で暗号化が行われていないことがわかります。そこで、バックエンドにプロキシを追加し、双方の間で mTLS を適用することで、同様の効果を達成できます。アプリケーション側にはその変化は感知されません。相手側で復号化されるため、以前と同じ形式のトラフィックを受け取るだけです。
Demo
ここからは、これまでお話しした内容をほぼすべて盛り込んだデモを行います。これから行うのは、ターミナル上での操作が中心となる内容です。
Kubernetes クラスターはすでに起動しており、現在稼働しているワークロードはありません。ただし、画面下部には Ollama が動作しています。これにより、Kubernetes クラスター内でローカルに大規模言語モデル(LLM)を実行することが可能です。
次に、非常にシンプルなワークロードをデプロイします。これは AI ポッド、つまり AI エージェントです。このエージェントはごく単純な処理を行っており、数秒ごとに LLM にアクセスして「Go に関するジョークを一つ教えて」と要求するだけです。
実際に確認してみましょう。モデル名やプロンプトに使用されたトークン数、レスポンスに含まれるトークン数が表示されます。非常にシンプルな仕組みです。
これはハードコードされたもので、まさにその兆候が見え始めています。現在のモデルは完璧ではなく、面白いジョークを返すような能力も十分ではありません。
そこで私たちは、このハードコードされた AI エージェントの動作を透明性を持って変更するアプローチを取ります。ここで登場するのが「ウォッチャー(watcher)」と呼ばれる仕組みです。Kubernetes には多数のウォッチャーが組み込まれており、クラスター内で実際に発生するイベントを常時監視しています。
今回の概念実証(PoC)で構築したウォッチャーは、ワークロードに注釈(annotation)が付与されるのを監視します。まず最初に付与するのは「netflush」という注釈です。これは以前も触れましたが、この注釈によりエージェントが起動した際に eBPF を使用して新しいソケット接続を再構築するようになります。
最後に、「AI=true」という注釈を追加します。ウォッチャーはこの注釈がポッドに付与されたことを検知し、処理を開始します。
では始めましょう。画面の上部を見ると、3 つのアノテーションが表示されています。「3 つ?」と思った方もいるでしょうが、実際には私が追加したのは 2 つだけです。
なぜ 3 つに見えるのかというと、AI="true"という設定を追加した際、ウォッチャー(監視機能)がそれを検知し、自動的に Pod に新しいコンテナを 1 つ追加したからです。画面の下部を確認すると、まさにその直下に、Pod に追加された新しいコンテナが見えます。
通常、これは不可能なことです。Kubernetes は、一度ワークロードに適用されてしまうと、変更できることとできないことを非常に厳格に定めています。例えば、「サイドカー」という概念をご存知でしょうか?
サイドカーを追加するには、通常、何かしらの監視機能が働きます。API サーバーがリクエストを受け取る前にそれをキャプチャし、修正を加えてサイドカーを付加した上で、初めて処理が進みます。一度 API サーバーがワークロードの起動を開始してしまえば、その後にサイドカーを追加することはできません。
今回私が行ったのは、Kubernetes API に比較的新しく追加された「エフェメラルコンテナ」を利用することです。これを使えば、既存のワークロードの隣に、追加のワークロードを後から付け加えることが可能になります。
ゲートウェイの設定が完了しました。ログを確認すると、ゲートウェイは正常に起動し、いくつかの処理を実行していることがわかります。
まず「netflush」が有効になっており、既存のすべてのネットワークセッションを検索しています。すでに AI クライアントを見つけてプロセス ID を特定しており、この特定のプロセスを監視対象と認識しています。また、自身(ゲートウェイ)と Ollama の間に既に接続が存在することも把握しており、通信先の正確な位置を特定しました。
その結果、ゲートウェイは強制的に新しい接続を作成し、現在はプロキシを経由して Ollama と通信する形になっています。これにより、AI エージェントが実際にやり取りを行う相手とのすべての通信を完全に制御できるようになりました。
では、この制御を実行してみましょう。設定済みである ConfigMap を確認します。
ここで適用するポリシーには2つの役割があります。1つ目はモデルの差し替えです。従来の Llama モデルから、Gemma 2 モデルに切り替えます。2つ目は応答内容の変更で、これまで Go 言語に関するジョークを返していた部分を、Go 言語に関する事実情報へと変更します。
実際に確認してみましょう。現在使用されているのは Llama ではなく Gemma 2 です。また、応答内容は Go に関するジョークから、Go の事実情報へと変わっています。
この仕組みをより明確に示すことができます。設定マップを変更した結果、応答内容が「Go に関するジョーク」から「馬に関するジョーク」へと切り替わりました。実際、馬には3種類の歯があるという、非常に有用な情報が返ってきました。
これでアプリケーション側には透明性を保ちながら、使用しているモデルの差し替えやプロンプト挙動の変更、特定のキーワードの除外などが可能になりました。一方で、特定の動作をブロックしたいケースもあるでしょう。ここでは「ウサギに関する事実」を試してみます。すぐにわかる通り、これはブロックされます。応答にウサギに関する記述が含まれている場合、実際のユーザーへ返却しないというフィルタが機能しているからです。
結果として、「Kube-gateway says no」という応答が返され、望ましくないキーワードを含む応答を透明性を持って完全に遮断できることが確認できました。
最後に、観測可能性の観点から、API の視点から何が起きているかを理解することも重要です。次回リクエストが発生した際、実際に何が行われているのかをすべて透明性を持って確認できるようになります。
先ほど「ウサギ」に関する内容が見つかった場面ですが、ここでは LLM へ送信される JSON ペイロードそのものも確認できます。このペイロードは後で解析され、状況に応じて変更が必要か、あるいはブロックすべきかなどが判断されます。
最終的には、リクエストとレスポンスの両方を同時に確認できるようになります。元のリクエストは「Go に関するジョークを話して」という内容でしたが、実際には大幅に修正されています。その結果、レスポンスでは「ウサギ」や「カエル」の話になり、「カエルの豆知識」や「カエルのジョーク」が提供されるようになります。
このように、実行中の AI エージェント自体は全く変化に気づかずに、その挙動を透明性を持って変更することができました。これがデモの要点です。
eBPF を用いた AI プログラムの観測可能性とセキュリティ
eBPF を活用して、さらに多くのセキュリティと観測性の対策を講じる方法についてご紹介します。今日お話しした内容は、主にネットワークや API 側の観点からシステムを理解し、可視化するための話でした。
しかし eBPF を使えば、実行中のシステムのさまざまな内部領域にフックを張ることができます。ある登壇では、AI エージェントがタスクを完了するために追加のツールを呼び出す仕組みについて詳しく語られていましたね。eBPF を利用すればカーネル自体にフックを張り、「rm コマンドを実行しようとする試み」があれば、そのプログラムが実際に実行されるのを単純にブロックすることも可能です。
あるいは「/etc/passwd の削除」「/etc/passwd のオープン」などの操作を試みた場合にも、ファイルシステム領域の eBPF にフックを張ることで、「このプロセスにはその権限がない」と即座に拒否できます。
ご覧のとおり、eBPF を使えばネットワーク動作も制御でき、アプリケーション側には透明性を持たせたまま、トラフィックを別の場所にリダイレクトすることも可能です。
eBPF を利用すれば、許可すべきシステムコールを制限することも可能です。例えば、権限昇格を試みる行為や、AI エージェントが実行を求められた際、必要な権限を持たずにプロセスファイルシステム(proc ファイルシステム)をいじって別のルートアクセスを取得しようとするようなケースでも、eBPF は即座に検知して阻止できます。これはまさに、サンドボックスからの脱出を試みた行為です。
こうした振る舞いは「許可されない」と明確に定義でき、実行自体を禁止できます。「そのような権限はない」という理由で、特定の操作をブロックできるのです。現在、稼働中のシステム内で何を許可し、何を阻止するかという点については、eBPF を通じてほぼ無限の柔軟性が得られています。
まとめ
現在、AI 関連の動きは非常に活発です。自分の課題を解決するための AI コードを生成するのは、今や極めて簡単で迅速になりました。しかし、そのコードがすぐに本番環境に導入され、システムがそれらに依存してしまうケースも増えています。一方で、明確な責任所在がないまま、作成者が次のプロジェクトへ移ってしまい、成果物の管理が行き届いていないという問題も頻発しています。
一度本番環境に投入された後、そのコードを作成して放り出した人物はもう別の場所へ行ってしまっています。では、誰がその資産を所有し、維持していくのでしょうか?更新が必要になった際や、依存するライブラリ・使用しているモデル・プロンプトなどにセキュリティ上の問題が発生した際に、誰が対応するのでしょうか。この点は非常に大きな課題となり得ます。
そこで必要なのは、AI プログラムや AI エージェントの特定の機能に対して、何を許可し何を制限するかを明確に制御できる仕組みです。
今日ご紹介したのは、Kubernetes プロジェクト内の「AI egress ワーキンググループ」に基づいた概念実証(PoC)です。現在、当社を含む多くの企業が協力し、Kubernetes クラスター内で AI ベースのアプリケーションの動作を観察・制御・判断するためのルールと合意されたアプローチを標準化しようとしています。
ただし、今日ご紹介した手法は Kubernetes クラスター外でも適用可能です。私たちは本質的にトラフィックの転送や API 呼び出しのパース処理などを実現しています。
リソース
さらに詳しく学びたい場合は、ebpf.io が素晴らしいリソースです。eBPF コードの学習もすべてそこで可能です。
Cilium のラボセクションには多数の無料ラボが用意されており、その中には eBPF に関するものもあります。eBPF プログラムの管理方法について知りたい場合も同様で、Web ブラウザからアクセスできる無料の実習環境が提供されていますので、実際に触りながら学ぶことができます。
もし eBPF に深く興味を持たれたなら、約 1 時間のドキュメンタリー映画もあります。eBPF がどのようにして誕生したのか、その経緯を詳しく解説しています。
現在、eBPF はほぼあらゆる場所に存在します。すべての Android スマートフォンに搭載されており、Facebook(Meta)ではメタバース関連のネットワーク管理などにも利用されています。また、ほとんどの Kubernetes クラスターでも、観測機能やネットワーク制御、ポリシー適用などの目的で使われています。
さらに、Liz Rice 氏の著書『What Is eBPF?』も公式サイトから無料でダウンロード可能です。
Q&A
参加者 1: eBPF のコードも示していただけますか?
Dan Finneran: はい、今日お話ししたすべての機能を支えているのがこのコードです。もしご希望であれば、一つずつ解説することもできますが、要点を申し上げます。
このコードの「SEC」と書かれた部分はセクションヘッダーであり、「connect4」は TCP IPv4 の接続イベントを示しています。これは外部へ接続する際に発生するイベントで、私たちのコードがカーネル処理の前にここで実行されます。eBPF コードは常にカーネルやその後の処理よりも先に動作し、システムに実際に影響を与える前に挙動を変更したり、特定の振る舞いを強制したりすることが可能になります。
具体的には、関心のある事象に対して処理を低レベルで行い、宛先を実際の到達先から変更することで、eBPF 内でトラフィックをハイジャックし、プロキシへ転送します。これらはすべてオープンソースで提供されており、同様の事例は多数存在しますが、これは IPv4 の TCP 接続イベントに eBPF コードをフックさせるシンプルな例です。
Bryant: これらの仕組みについて文書化する方法についてのアドバイスはありますか?私は古くからの Java デベロッパーですが、アスペクト指向プログラミングにも取り組んだことがあります。JVM レベルで似たような感覚でしたが、デバッグが非常に困難になりました。なぜなら、アスペクトが任意の箇所に機能を入力して干渉するためです。どのようにデバッグすればよいのでしょうか?また、何が起きているのかをどう理解すればよいでしょうか?非常に強力な技術であることは承知していますが、一方で「足撃ち」のような危険性はないのでしょうか?
Dan Finneran:このデモはウェブページ上で行いました。Isovalent に入社したばかりの頃、私が最初に試したのは、これを自分のラップトップで実行してすべてのイベントを出力させるというものでした。すると「ok」という結果が返ってきます。次に「return not ok」に切り替えてみてください。そうすると一瞬にしてすべてのパケットがドロップされ、私自身もこのデモを通じてラップトップへのサービス拒否(DoS)攻撃を実行することになります。これほど簡単にできるものはありません。
デバッガーなど存在しません。使えるのは実質的に bpf_printk イベントだけです。これはカーネルのログ出力機能です。つまり、カーネルにログを書き込み、それを sys_trace のデバッグモードや trace_pipe などで出力させることができます。これが内部で何が起こっているかを理解するための唯一の方法なのです。
重要なのは、誰もが eBPF コードを書く必要があるわけではないということです。一度コードを書いて必要な部分を公開すればよいのです。私が言うように、Cilium や Calico などのプロダクション環境で見られるネットワーク関連の機能については、eBPF の知識は不要です。「ネットワークを動かしている」「トラフィックを監視し、転送している」という事実さえ知っていれば十分です。
Bryant:プロデューサーとコンシューマーは、ある意味で全く異なる役割の人たちですね。プロデューサー側ではすべての仕組みを知っていますが、私はその先のコンシューマー側にいます。
ダン・フィネラン:はい。eBPF を本当に学びたいなら、素晴らしいことです。私の仕事は果たされたと思います。これは車を運転することに似ています。エンジンの仕組みをすべて知る必要はありません。特に現代の電気自動車では、その必要性はほぼありません。なぜなら、それは過剰だからです。
これについても同じことが言えます。eBPF で動作するツールを活用すれば十分です。eBPF 自体について学びたいなら大歓迎ですが、その内部で何が行われているかという基礎的な仕組みをすべて理解する必要はありません。
参加者2:最後にシステムコールの制限について触れられていましたが、どこまでが「軍拡競争」に陥るポイントになるのでしょうか?自己複製やフォーク処理が可能になると想像されるため、結局はサンドボックス化が必要になるのではないかと思っています。
Dan Finneran: 私たちが実装するフックは、本質的にイベントとして機能します。例えば、ファイルオープンという事象に対して eBPF コードを適用する場合、open システムコールにフックを張ることで、そのコードがカーネルのシステムコール実行前に最初に動作するように設計できます。
もし AI エージェントが /etc/passwd の開封を試みた場合、実際のカーネルシステムコールが発生する前に、私たちの eBPF プログラムが最優先で介入します。これにより、システム内で実際に起こりうるあらゆる事象に対して、常に一歩先を行くことが可能になります。
私たちはこのシステムコールを監視し、「許可しない」と判断すれば false を返すことで、処理を即座に停止させることができます。これにより、対象のアクションは事実上不可能になります。エージェントが同じ試みを繰り返したり、別のシステムコールを試みたりすることは可能ですが、Linux カーネルにおいてファイルを開くためのシステムコール経由のメカニズムは本質的にこの一つしかありません。つまり、私たちのイベントが常にトリガーされることになります。
また、syscall ret(システムコールの戻り値)にもフックを張ることができます。これにより、カーネルにシステムコールを実行させた後、その結果を取得し、戻り値に基づいて eBPF コードが何らかの処理を行うことも可能になります。つまり、システムコールの実行前と実行後の両方にフックを適用できるのです。
See more presentations with transcripts
Recorded at:
Aug 21, 2026
原文を表示
Enchant Your AI and APIs with eBPF Magic 🪄
View Presentation
Speed:
Download
49:54
/presentations/ebpf-ai-gateway-kubernetes-security/en/slides/slide-1786345389423.jpg)
まとめ
Dan Finneran discusses the risks of unowned AI-generated code in production and demonstrates how eBPF can intercept and control AI API traffic in Kubernetes. He explains how kernel-level socket hooks enable transparent prompt filtering, model swapping, token limits, and syscall restrictions to secure AI agents without modifying application source code or restarting containers.
Bio
Dan Finneran is a Principal Community Advocate at Isovalent at Cisco. His journey to today has included bare-metal, jails, zones, vms and containers where he is currently enjoying the fast-paced ride in the cloud native space. He also created & maintains a popular Open-Source load-balancer for Kubernetes and contributes to upstream Kubernetes.
About the conference
Software is changing the world. QCon London empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.
INFOQ EVENTS
- August 27th, 2026, 1 PM EDT
Why AI Agents Fail at Scale: Context Is a Data Layer Problem
Presented by: Boyd Stowe - Founding Solutions Architect at Tacnode
- September 17th, 2026, 1 PM EDT
Beyond the PR: The New Control Plane for Agentic Software Delivery
Presented by: Mohit Suman - Staff Product Manager at Harness
Transcript
Dan Finneran: We're going to be talking a little bit about AI, APIs. We're going to talk about eBPF, which is a relatively low-level technology. We can look at some eBPF code if you really want to, or we can basically just talk about how eBPF works. I'm fully happy to delve into anything that makes sense to you. Who am I? I am part of a company called Isovalent, which is now part of Cisco, where I largely focus on helping the community understand technologies like eBPF, or the Cilium project. All of these are all open source. Cilium is networking for Kubernetes clusters, and eBPF is a technology that is part of the Linux kernel. If you have an Android phone on you right now, you will be running and using eBPF without actually realizing it. Then, in my spare time, I have created a number of cloud-native-based solutions that are part of the CNCF, so software-based load balancers for Kubernetes clusters, and bare metal provisioning tooling for Kubernetes clusters and things like that as well.
To level set, this talk is largely around some of the things that we're seeing both in the cloud-native industry and in Kubernetes, but what we're also starting to see in people's production platforms and in their deployments and things like that. As we pretty much all know at this point, people are creating code at an ever-increasing rate. They're basically prompting, asking AI to do something. They get a bunch of code, job done as such. There is a disconnect between understanding and owning this code. I maintain a number of open-source repos, and we're now starting to see a lot of pull requests generated by AI, which is great. Good new code, maybe new features are being added. Ultimately, when I ask these people who've raised the PR, can you explain the code to me, how it works, how we're going to support it moving forward, typically I get ghosted.
I never hear from them again. This is a big problem, because if I suddenly accept 1,000 lines of code that I haven't written, and they don't understand, who's going to support that moving forward? This is becoming a bit of a growing issue. This code is just popping up into production. If somebody comes up with a quick idea, they vibe code it or get AI to generate that stuff, it goes into production. All of a sudden, there's a dependency on that code in the business, and nobody knows who wrote it, nobody knows how it works, and nobody will support it moving forward. Again, that growing disconnect. There are some additional issues as well. The behavior of these AI programs. There's been a load of talks about issues recently where people have been handing over more and more control of things like their calendars and their file systems and their laptops to these AI agents.
In some instances, there's been a case where it's done a terraform destroy and wiped out production, deleted folders, deleted source code and things like that in its thought that it was actually helping. These programs thrown into production, how do we observe them? How do we understand them? How do we change their behavior? Then, finally, we know what we're seeing. We know what we need to do. What is the best implementation for doing these sorts of things? One of the things that I'll be showing today is effectively a proof of concept, because in the Kubernetes space, there is a new working group which is all around building things like AI gateways in order to capture and understand and change AI agents and the AI-based programs in Kubernetes clusters. That is an ongoing working group at the moment where they're standardizing what this would look like. Today, I'll show you an implementation of what we're actually talking about in that working group.
Outline
What we're going to cover today, the typical architecture of applications that call out to AI endpoints, so what that code looks like. A quick overview into eBPF. eBPF is low-level. It allows me to do whatever I want with a Linux kernel, and a Windows kernel coming soon. We will delve into it. We won't go too deep because we're talking about kernel programming. Then we'll talk about building a solution for observing and controlling these applications powered through eBPF, and then a summary. There will also be a demo as well.
Modern AI Applications - Evolving Platforms
A quick walkthrough in terms of evolving platforms. Are you using Kubernetes today or understand it? It's been a bit of a journey for me recently being part of now Cisco. When I start talking about Kubernetes, it's like a completely blank face, which is a bit weird because being part of a startup culture, it's like everybody knows about Kubernetes from my perspective. How did we get there? Many years ago, there was endless evolutions. We saw CPUs gaining more and more cores as we hit gigahertz ceiling limits, and more and more memory. We reached back into using older technologies to partition these larger systems. Virtual machines became the de facto resource for running your applications and your operating systems. Then the issues around virtual machines where the developers struggled with them, so they were unwieldy to manage. The time to build and then the time to deploy was slow and deemed too heavy.
In around 2014, there was the concept of a container created by a person called Solomon Hykes at Docker. That is the standardization for running your applications in a much faster way is containerizing those applications. We got the speed benefits from that. We got lower resource usage. It also meant, and people are really feeling this right now, is that we could remove a lot of the license fee costs from virtualization by moving to open-source technologies such as Docker containers. In a circular fashion, though, we did do this a very long time ago with both FreeBSD jails and Solaris Zones. We basically just reinvented the wheel yet again. Here we are.
Moving on from that, evolving to being able to move much quicker, there originally was a number of competing projects to do this. There was a project called Nomad from HashiCorp. There was Docker themselves, developed Docker Swarm. I was an engineer on Docker Swarm many years ago. Then, Kubernetes, which came from Google. All of these technologies and projects were all around making it easier for you to manage the lifecycle of those applications. It comes with a lot of benefits. Not only are you managing the lifecycle of those containers, it becomes much easier for you to handle the lifecycle of them from a case of, I spin up my application, I scale it, and then I spin it down. I've been taking care of the buildup, the startup, and then the removal and tidy up of all of that. People who've managed virtualization environments will have seen it's very easy for orphaned virtual machines to live throughout the infrastructure.
Trying to work out who owns that sort of thing is quite a pain and very hard to actually manage. Kubernetes came with a lot of benefits. They're all very cloud-native. Automatic scaling of your infrastructure itself. Automatic scaling up and down of the application itself. A lot more cloud-native tooling to be able to monitor the health of those applications, making things easy to manage. Deploying on Kubernetes, for those that haven't done it, is all very YAML-based, lots of text, typically. Effectively, you have your specification, which says my application should look like this. It's based upon these particular requirements. You throw that at Kubernetes, and Kubernetes will take care of running that for you. Under the cover, you have two components. You have the control plane, and you have your worker nodes. Your worker nodes is where the workloads will actually run. You apply your YAML to the control plane, and then the control plane will take care of speaking to the workers that it manages to run those actual workloads for you. Here we can see we've spun up a pod, and inside that pod, we have one or more containers. They would be your web server and perhaps a monitoring agent that sits next to it and things like that. That's the typical architecture of both the Kubernetes cluster and an application that's actually running within that cluster.
AI Enabled Code
We're now, obviously, starting to see AI-based applications inside these containers running inside Kubernetes clusters. They're being thrown over the fence, and nobody understands what they do or how they work. To understand what they actually look like, we need to look at the API itself a little bit and understand what AI interactions actually look like. Ultimately, when you speak to an LLM, whether it's OpenAI, or Ollama, or anything like that, it is just an API to interact. It's just basically JSON blobs going back and forth. It's typically a request and a response, so your request that you send to an LLM backend is the model that you would like to use. Different models will produce different sorts of response. Some are predominantly about generating images or video. Some are trained more on coding information so that they will produce better responses when asking to generate code for you.
There are various types of response that you can get, so often text will basically be lumps of code, or you'll ask it to write a summary of a document image. You'll describe what you want it to look like, a sunset or whatever, and you'll get an image back and things like that. Then finally is the prompt. The prompt is effectively what your request actually is. As I mentioned, I want an image of a lovely sunset. That would be the prompt. The LLM would pass that, do its magic, and you would get the response back. The request is based upon prompts. There are a number of different types of prompts. Typically, the user prompt is what I will be asking for. However, I can also say, I want an assistant prompt, and that assistant prompt would say, in the style of DALL·E, for instance. My userland prompt would be, paint me a picture that looks like this.
The assistant is for setting ground rules for what the LLM should actually produce on top of all of that. To generate any response with LLM, tokens are typically used. You have tokens in the request that are processed, and then tokens that are actually in the response as well. They are effectively what you are charged on when you are interacting with AI endpoints. Additionally, you can specify ceiling limits on tokens. Not a lot of people do, which is why we're starting to see some crazy spends that people are starting to see without realizing it. You can specify a ceiling on that. However, when that ceiling is hit, the LLM will basically give you what it has managed to build up until that point. That ceiling, once hit, you may get a response that's inaccurate or only partially complete. Then, finally, these APIs offer a level of reasoning, typically small, large, medium.
That is another method for balancing out the amount of spend in terms of tokens versus the quality of the response that you are actually going to get as well. Finally, some of the other things that you can add on to your request is you can upload images or you can add an additional text. All of that is processed by the LLM to help generate a response that makes sense. It can cache the previous conversation that you have been having with it in order for it to build a holistic view of what it is that you are aiming to achieve. Then, finally, the response. We can have that delivered whole. Effectively, the request goes and then you wait for however long it takes for it to process all of that. Or you can have that as a stream. Typically, things like Claude will do a streamed response. It looks more conversation-like as you are starting to see the response streamed into the UI from that perspective.
This is some sample code in Python. This is a very quick interaction with OpenAI. Effectively, the URL for an OpenAI endpoint or an endpoint that supports the OpenAI spec. Then, effectively, we're just doing a simple chat message here. The message is, say this is a test. The role is effectively, type a prompt that we are going to use. This is going to be a user prompt where typically it is I who is asking the LLM to do this. We can add additional messages in here from different roles. Roles like the assistant, which will specify more things such as ensure the output is in JSON, or ensure that the output in a particular language like French or German or things like that. These additional messages that we can use to make sure that the response is as accurate as possible. Then, finally, the model down at the bottom there.
That's the model that we're actually going to use in order to generate the response. Now, we're starting to see things like weak prompts. We're starting to see hard-coded models. There are a number of issues with that that will become apparent as we start to move forward. The responses, it's a JSON payload that you get back. There will be a bunch of additional metadata such as how long it took in order to generate the response. How many tokens were actually consumed in order to do that. If it's streamed, you'll either get in-progress messages. Or if the response is complete and finished, then we'll get a final one where the status is set at complete. Then the final bit of information really is if it is image, audio, video, the response is basically just going to be Base64 encoded media for you to decode and display as needed.
Let's have a look at what it looks like when you're interacting with this. A quick example of using a quick chat UI in order to interact with a model. Basically, just specifying a simple question here. Like, how do I delete all of the files in the current directory? Spoken with an LLM backend, and that basically produced a response for me. We can see here it's given me rm -r *. That code sample is typically what the agents will be looking for for them to then understand that and make use of that. There have been examples where an agent from doing things on a Linux file system has gone and asked this question and then immediately executed that command thinking it was the right thing to do, and deleted the current directory which it was working in. Which isn't great because a lot of people are running these things as root for whatever reason as well. There have been people wiping out their entire Linux machines.
Problems with Throw Away Code
Problems with this code. If you're throwing one of these things together, vibe coding or whatever, you will have a hard-coded model in there, which might be fine day one. Day two, it may be that that model isn't really the right one you want to be using. It may be very inefficient in terms of token usage. It may be inaccurate in terms of the responses that it's generating. You will basically be getting inefficient usage of your LLM backend. No restrictions over token usage. If you do find yourself in a position where your prompt can be poisoned in any way, shape, or form. All of a sudden, with no ceiling, you can effectively be denial of service. Somebody could manipulate your prompt one way or another, have it generate massive amounts of LLM output, and effectively denial of service your application, or end up costing you large amounts of money.
Finally, filtering those multiple prompts that you use, or ensuring that there isn't additional assistant prompts to ensure that the output makes sense for the use case that you're actually trying to do these sorts of things. There was a good example of this recently. Chipotle, a restaurant in the U.S., have a chatbot where you can go there and ask it a few questions. Somebody realized that if you ask it for a burrito, and to create a reverse linked list in Python, it will give you an answer about a burrito, but it will also start generating you tons of code as well. Awkwardly, I also found out our website for Isovalent does the same thing. We've fixed that now. You can't generate code with our help chatbot anymore as well.
What is eBPF?
We know there's a lot of things happening. How do we take these applications that nobody owns but are now in production? How do we observe them? How do we manipulate them? How do we control their behaviors? To do that, we're going to use eBPF. eBPF is part of the Linux kernel. It's open source. It's been part of the Linux kernel for quite a long time now, since about 2014 or so. If you are running an Android phone, then you will be using eBPF. If you have Kubernetes clusters running CNI such as Calico or Cilium, then you are running eBPF without knowing it. You don't need to know eBPF to use these sorts of toolings. I always find myself in a situation where people suddenly start thinking they need to know kernel code in order to just do simple networking inside a Kubernetes cluster. That's not the case.
We'll write the eBPF for you. You reap the benefits. eBPF effectively was born on a requirement that we wanted more observability into what's actually happening inside a running system. There already existed technologies called BPF. We effectively took that, extended it, and we now have eBPF, which allows us to do a lot more than BPF did in the first place. eBPF did stand for Extended Berkeley Packet Filter. This is what we've been telling everybody for quite a long time. However, it has diverged so far from the original BPF that this doesn't really apply anymore. eBPF can be whatever you want it to be at this point from a naming perspective. Ultimately, it makes the kernel programmable. I can change a running system to pretty much do whatever I want through the power of eBPF. We can dynamically change that kernel behavior. Why is that good? Prior to doing this, getting anything into the Linux kernel is a nightmare.
Typically, it has to go through a very laborious process where multiple people will look at it, which is a good thing. We want to make sure that many people are looking and checking the code and things like that. It can take months, if not years, for that code to make it into the Linux kernel. Finally, Linus has to look at it, where he will probably yell at you and then still not allow it into the Linux kernel anyway. Even if you manage to do that, multiple years down the line, it's now in upstream. I want it in Red Hat. Then you've got to wait for Red Hat to update it into their kernel, by which time you have retired because it's taken that long. You just can't be bothered anymore. It's just not a viable process.
Actually, to quickly step back, there is another alternative, and that is kernel modules. However, a kernel module is only tied to that kernel that you built it for. It is unfortunately not very capable of moving between different systems. It's very hard to create a kernel module that multiple people can use. Enter eBPF. The idea behind eBPF is we can write eBPF code that is going to hook into a Linux kernel and Windows kernel and add to that functionality that we want and be flexible to move between multiple systems and things like that. As long as you have a relatively recent kernel, 5.12, so anything in the last 5 or 6 years, eBPF will just work out of the box. You can write your code and attach it to any part of the running Linux kernel. No more dependencies on waiting for it to actually make its way to the actual upstream main kernel.
What it looks like is we have our kernel. It will manipulate files, networking, memory, processes. We have our eBPF program, and we can effectively attach it to various areas inside the Linux kernel. Today we're going to look at attaching eBPF programs to the networking stack in order for us to manipulate these AI calls. eBPF code is low-level. It is code that you are writing that is going to attach into a Linux kernel. It does need to be safe and secure. In order to do that, eBPF comes with tooling to ensure that your code won't loop forever and cannot in any way crash a Linux kernel, because adding stuff into running kernels is quite scary. We want to ensure that the scaredness doesn't actually exist when we're doing these sorts of things. We can attach eBPF programs to a lot of different areas. Kprobes, kernel probes, user probes or Uprobes allows us to attach our eBPF programs to anything in userland.
Network packets is the main use case for eBPF today. Then there's a bunch of other areas as well. Now hardware devices, Linux security modules, performance events and things like that. You can attach it to so many different areas. As I mentioned, various areas of the file system from the block device all the way to the virtual file system that sits on top of all of that. A number of different areas in the networking stack to various areas inside the Linux kernel itself as well. A huge amount of control over what we may or may not want to do with a running Linux system.
Building an AI/API Gateway
We know what the problem is. We now have a technology that's going to allow us to start changing these sorts of behaviors by hooking in to a running system. Let's step through what that will look like. This is the shopping list for everything that we're going to need in order to build an AI gateway that's going to run within Kubernetes. Step one is we're going to want to transparently intercept the traffic from our AI agent program or whatever it is to our LLM endpoint. We're going to redirect that traffic transparently to a userland proxy where we'll be able to modify and change that. We want to be able to observe all of those AI requests and responses. We may want to modify that, change the model, look at the prompt, cap the tokens, all of the things to protect us from issues that I mentioned earlier.
We may want to block those requests, again, based upon those rules. Where are we going to attach our eBPF programs? This is important because there are a lot of different areas that we can do all of this. The lower down the stack, the more fine-grained control that you're going to have. However, if I'm attaching my eBPF program to the network card itself, which I can do. I can attach directly into the driver of the network interface card. I'll just be receiving raw frames, which is going to be very hard for me to manipulate and understand that that is basically a bunch of JSON packets come out of order. Some things get corrupted and will need to be resent. It's not just going to be that packet. I will see all traffic leaving and entering the box and things like that. In order to make life a bit easier, we're going to go a little bit higher up, and we're going to connect to the sockets area.
Effectively, whenever our program dials out, tries to do a connect to a other IP endpoint, which will be the web server that we're doing our API call to, that is where our eBPF program will hook in. It will see everything that's actually happening and allow us to start making changes. This is what it looks like. Our process on the left would be our AI agent that is going to try and dial out to OpenAI. It will create a socket in userland. That socket will go through iptables if needed. It will go through an area called traffic control in the Linux kernel, and then finally onto the network card, and traffic will go where it needs to go. This is the different areas in terms of what it actually looks like. There are a bunch of areas where we can attach our eBPF program to. The most performant would be on the NIC driver, but that's just going to give us raw frames.
It's very hard for us to actually turn those raw frames back into a data stream that makes sense to the application. Traffic control, again, very performant, but is inside the kernel, and again, it's just raw packets. Attaching our eBPF program to the socket allows the kernel to take care of all of the actual data itself, but we will be able just to see those streams.
This is what it would look like. We have our running process. We have the concept of a proxy that sits next to it. We attach our eBPF program to the socket when a new socket is created, and with the process, without realizing it, has its traffic then redirected to our proxy. All transparent. We can also do this with ensuring that there's no restarts required to the application as well. We can actually force a new connect to occur, meaning our eBPF program will actually capture that traffic again transparent to the application itself. That proxy now can start to see these requests. This is what the request would typically look like. Here we can see we're using an old model, so we may want to inline change that model. The application itself doesn't need changing. It doesn't realize anything has actually changed. We're doing that transparently to the application itself.
We may want to make changes to the input request as well, so we may want to change the prompt so that we get jokes about giraffes instead of other animals and things like that. As mentioned as well, we may want to cap on other areas. There are a number of different areas through the API we can start to assert control on those behaviors. This is what it would typically look like from a response perspective. Traffic goes from our AI agent. eBPF has redirected it to the proxy. The proxy has looked at it, may have made changes based upon some of the rules that we've applied. The proxy is then dialed out on behalf of the original process to the AI provider, and then we get our response back. The original question, what's the joke about giraffes? AI LLMs make terrible jokers. The jokes are usually quite terrible.
The answer to, what do you call it when a giraffe swallows a toy jet, is a plane in the neck. We can see the response gives us the amount of tokens that we've required in order to generate that. We can then filter based upon all of that as well. We have the capability of understanding everything going in and out from there. Finally, encryption as well. We can effectively enforce encryption between applications. If you're running your LLM process internally within the Kubernetes cluster, you typically will find that there'll be no encryption between the two. We can effectively do the same thing where we add a proxy on the backend, and then effectively just do mTLS between the two as well. The applications are none the wiser. It decrypts on the other end, and it will just receive the traffic as it looked before.
Demo
We're going to do a demo of pretty much everything that I've talked about. It is going to be quite a lot of terminal action that we're going to get right now. Kubernetes cluster up and running. There is no workload that's actually running on here at the moment. However, at the bottom is Ollama, which allows me to run LLMs locally within a Kubernetes cluster. What we're going to do now is we're going to deploy our very basic workload. We have an AI pod, which is effectively an AI agent. Very simple, all it does is dials to our LLM and asks it to tell a joke about Go every few seconds. We can quickly look at that. There we go. It's very simple. We can see here the model that it used, how many tokens were required in the prompt, and how many tokens were in the response.
This is hard-coded, like we are starting to see. The model isn't great, doesn't give us very good jokes and things like that. What we're going to do is we're going to transparently modify the behavior of this hard-coded AI agent. What we have here is, I think, called a watcher. You have lots of watchers inside Kubernetes, and they all watch for events that are actually happening within the cluster. Our watcher that we've created as part of this proof of concept is going to watch for annotations being added to a workload. The first annotation I'm going to add to our workload is an annotation called netflush. I mentioned this previously, that annotation means when the agent spins into life, it will use eBPF to reforce a brand-new socket connection. Then, finally, one other annotation, AI="true". The watcher will have basically seen that annotation be added to our pod.
Here we go. Right at the top, now we can see our three annotations. Three, I only added two. What's actually happened is when we added the AI="true", the watcher saw that, and it added an additional container to our pod. If we look down at the bottom here, we will see just underneath that we added an additional container to our pod. Typically, this isn't possible. Kubernetes has very strict rules on what you can and can't change once things have been applied to a workload. For instance, has anybody heard of the concept of a sidecar? A sidecar typically requires something watching for workloads being applied, captures it before the API server, modifies it, adds the sidecar, and then it goes. Once the API server has started the workload, you can't add sidecars to it. What we've done here is we've added an ephemeral container to it, which is a relatively new thing added to the Kubernetes API, which allows us to add an additional workload next to the existing one.
We now have our gateway set there. If we look at the logs, we can see our gateway has actually started, and it's doing a few things here. We can see here the netflush is true, and it's going to look for all of the networking sessions that already existed. It's already found our AI client. It's found its process ID, so it knows to look for that particular process. It's found that it already had a connection between itself, and that's the Ollama, so it knows where it was actually going. It's forced it to do a brand-new connection, so it's now speaking to the proxy, and now the proxy is now speaking to Ollama. We are now in complete control of all of the communication between our AI agent and whatever it's actually speaking to. Let's control it. I've added a config map. I'll quickly show you this config map so you know what I'm actually talking about.
This is a policy that we're going to apply. This policy is going to do two things. One, it's going to swap the model out, so it's going to swap the old Llama model for this Gemma 2 model, and further down, instead of it saying jokes about Go, it's actually going to give us facts about Go. We can quickly see this now. Here we go. The model is now Gemma 2 as opposed to Llama, and the responses are facts as opposed to jokes about Go and things like that as well.
We can demonstrate this a bit better. The config map has been changed, and we'll now see in the responses that instead of telling us jokes about Go, it's going to give us jokes about horses instead. Here we go. Horses have three kinds of teeth. Very useful information. We now have the capability of transparently to the application swapping out things like the model that it's using, changing the prompt behavior, omitting keywords and things like that. There may be things where we want to block certain behaviors. Let's have facts about rabbits. In a second, we'll see that this will be blocked because I'll show you, we have a filter which effectively says that if the response contains anything about rabbits, it shouldn't be allowed to come back to the actual user itself. There we go. Kube-gateway says no. We've effectively now transparently stopped any of those sorts of responses that contain keywords that we don't actually want to allow.
Then, finally, from an observability perspective, we may want to actually understand what things look like from an API perspective. Next time there is a request, we'll be able to see what all of that actually looks like. Again, transparently to everything that's actually occurring within here. We can see here, earlier it found the thing about rabbits. Now we can actually see the JSON payload that it is actually sending over to the LLM that we are actually then parsing and determining if things should change, if we should block things, and things like that. Then, finally, we can see both the request and the response now. We can see the original request was telling me a joke about Go. We've actually changed a bunch of it. We can now see that the response is telling us about rabbits or frogs, and things like that. We've got frog facts or frog jokes. Transparently, we've changed the behavior of a running AI agent without it actually knowing that anything has actually changed at all. That's the demo.
AI Programs - Observability and Security with eBPF
Additional ways that we can now use eBPF to apply additional security and observability. Everything we've talked about today from an observability and understanding perspective has all been around the networking and the API side of things. With eBPF we can hook into a variety of different areas inside the running system. There was a talk which talked a lot about how a lot of these AI agents will be shelling out additional tooling to eventually effectively do what tasks they are trying to do. With eBPF, we can hook in to the kernel itself and say, if anybody tries to run rm, just simply don't allow that program to ever actually run. If somebody tries to delete /etc/passwd or open /etc/passwd or anything like that, we can hook into the eBPF area of the file system and effectively say, this process is not allowed to do that. As shown, we can control the networking behavior to transparently redirect traffic to somewhere else so that we can do things transparently to the application itself.
eBPF can enforce which syscalls are allowed as well, so if something is trying to elevate privileges, which there was another demo recently of an AI agent asked to do something and it didn't have the privileges to do it, and it effectively started messing around in the proc file system to get another root access to it. It basically broke itself out of the sandbox. We can typically say just that behavior is not allowed, you simply can't do that. You don't have the privileges to do these sorts of things. It's pretty limitless at the moment in terms of what we can allow and what we can block within a running system.
まとめ
There's a lot of things happening at the moment. It's super easy these days to generate some AI code that scratches an itch that you have. Very quick and easy for that code to end up in production, for things to actually depend on it. No real ownership. These things are being thrown over the fence a lot of times because people are moving so quickly onto the next thing that no one is really taking ownership of what it is that they've created. Once these things are often dropped into production, that person who threw that together and has moved on, like, who's going to own that? Who's going to update that, should it need updating, should there be security issues in the libraries that it depends on, the model that it's using, the prompts that it's making use of? That can become a really large issue. As seen, we need a method for clear control over what is allowed from these parts of AI programs and AI agents.
What I showed you today is a proof of concept based upon the AI egress working group as part of the Kubernetes project. A lot of different companies at the moment, ourselves included, are working together to come up with a standardization for having rules and an agreed upon approach in order to observe, control, and determine the behavior of AI-based applications within Kubernetes clusters. However, what I showed you today is also possible outside of a Kubernetes cluster as well. We're effectively redirecting traffic and parsing the API calls and things like that as well.
Resources
If you want to learn more, ebpf.io is a fantastic resource. If you want to learn eBPF code, it's all there. On the Cilium lab section, so we have a number of free labs, you can go there. I think there's 45 different labs, but there is one about eBPF. If you want to learn about managing eBPF programs, we have free lab environments that you can basically just hit with a web browser, play with, and learn more. If you're really into eBPF, there is a documentary that you can watch. I think it's about an hour long. It details how eBPF came into creation. eBPF is pretty much everywhere at this point. It's on all Android phones. Facebook use it to manage the networking for all of their Meta fleet and things like that. It's in most Kubernetes clusters, either doing observability, networking, or enforcement of behaviors and things like that as well. There is also Liz Rice's book, "What Is eBPF?" available to download from the website as well.
Questions and Answers
Participant 1: Can you also show the eBPF code?
Dan Finneran: Yes. This is the code that powers everything that I talked about today. Now, I can step you through this if you really want to. Effectively, this bit of code here, if you look at the area where it says SEC, that's the section header, and connect4, that is a TCP IPv4 connection event, which is what happens when you connect out to something. This is where our code will actually run before the kernel will do anything. eBPF code always happens before the kernel, or whatever it is will actually process it. It allows us the capability to change things and enforce behaviors before they can actually impact a running system. Typically, what this will do is, if we care about it, we will lower down. We will change the destination to where it's actually going, so we hijack the traffic in the eBPF, sending it to our proxy. This is all open source. There's a number of examples of doing this sort of thing, but yes, this is a quick example of eBPF code hooking into IPv4 TCP connect events.
Bryant: Is there any advice on how to document some of this stuff? I'm an old-school Java dev, and I got into aspect-oriented programming, similar vibes but at the JVM level, and it became a nightmare to debug some stuff, because I had these aspects cutting in, and I was almost injecting functionality arbitrarily. How do I debug it? How do I understand what's going on? I'm conscious that it's very powerful, but is it a bit of a foot gun as well?
Dan Finneran: We did this example on the webpage. When I first joined Isovalent, the first example I had was, look at this, connect this to running on your laptop, and it will print out all these events, and it will return ok. Now try saying return not ok, which all of a sudden meant all packets were just dropped. I basically denial of service my laptop from the example. It is incredibly easy to do that. There's no debugger. All you've got are effectively bpf_printk events, so that is a kernel logging mechanism. Effectively, you can write logs to the kernel, and the kernel will output those in sys tracing debug, trace pipe, or whatever it is. That's the only way you can understand what's actually happening in there. This is the thing. Not everybody needs to write eBPF code. The idea really being is that you write it once, expose the bits that you need to do. As I say, for all the networking side of stuff that you see in production, like from Cilium and Calico and things like that, you don't need to know eBPF. You just know that it's powering your network. It's looking at traffic, and it's redirecting it, and doing things like that.
Bryant: The producer and the consumer are quite different people in some regards there. You produce it, you know all the stuff, but I'm a consumer at the other end.
Dan Finneran: Yes. If you really want to learn eBPF, then brilliant. I think I've done my job. It's a bit like driving a car. You don't really need to know how the engine works, especially not with today's modern electric cars, because that is bonkers. It's the same with this. Use the things powered by eBPF. If you want to learn about eBPF, that's great, but you don't need to know the fundamentals fully about what it's doing.
Participant 2: You mentioned restricting syscalls towards the end. I'm wondering, at what point does that just become an arms race, and you just have to sandbox it, since I can imagine it could start cloning itself, forking.
Dan Finneran: The hooks that we apply are effectively events. Our eBPF code, we would have, for instance, file open. We would create our eBPF code, which attaches to the syscall file open, or open. Our code would execute first. If an AI agent tries to open /etc/passwd, our eBPF program will be the first thing that actually happens before the kernel syscall actually occurs. We can always be one step ahead of anything that's actually happening within the system itself. We see that syscall and we say, no, you're not allowed to do it, we return false, effectively that's a stop dead, there's nothing it can really do. It can keep trying that, or try a different syscall, but whatever it is, that is really the only mechanism for opening files through syscalls in the Linux kernel. It's always going to trigger our event. There is syscall ret, so we can actually attach to the return of the syscall. We can allow the kernel to run that syscall, and then we can capture the results of all of that, and have eBPF code that does something based upon the return of that as well. We can attach to the before and after the syscalls.
See more presentations with transcripts
Recorded at:
Aug 21, 2026
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み