AIエージェントが生成したコードやユーザー提供のデータ変換スクリプトを、そのまま実行するのは危険だ。共有カーネルのコンテナより一段厳しい「ハードウェア隔離VM」という選択肢を、Simon WillisonがAIエージェント自身(Claude Fable 5)に検証させた記録から読み解く。
ハードウェア隔離VM「smolvm」が持つCPU/RAM上限・タイムアウト・ネットワーク遮断・ファイルアクセス制限という具体的な隔離機能と、冷起動0.6〜1.5秒・ウォーム実行約50ミリ秒という実測性能。そして検証環境にKVMが無かったときにどう代替したか、という手順自体も持ち帰れる形にする。
自作のツールやエージェントで「ユーザーが渡してきたコード」や「AIが生成したコード」をそのまま実行する場面は増えている。データ変換タスクの自動化などが典型だ。だが、Dockerのようなコンテナはホストと同じカーネルを共有する。カーネルの脆弱性やコンテナ実装の不備があれば、隔離が破られる可能性が原理的に残る。
Simon Willisonが2026年8月19日に公開した検証記録は、この一段先の選択肢としてsmol-machines/smolvm(GitHub★約4.6k、検証時のバージョン1.8.3)を扱っている。VMM本体はlibkrunと専用カーネルlibkrunfwで構成され、Linux上ではKVM、macOSではHypervisor.framework、WindowsではWHPをバックエンドに使う。ポイントは、実行するワークロードごとに専用のゲストカーネルを持つ本物のVMが割り当たる点——共有カーネルのコンテナとは隔離の"厚み"が違う。
この検証を実際に手を動かして行ったのはSimon Willison本人ではなく、AIエージェント(Claude Fable 5)だった、という点も記事の見どころのひとつ。AIエージェントが「AIエージェントに実行権限を持たせる際の防御策」を自ら検証する、入れ子の構図になっている。
検証ノートは、ユーザー提供のデータ変換タスクを動かすうえで必要な制限項目を、smolvmが一通りコマンドラインオプションとして持っていることを確認している。
--cpus <N>(既定4)と--mem <MiB>(既定8192)でハード上限を指定できる。メモリはvirtio-balloonによる動的な調整も効く。
--timeout <DURATION>はrun・execの両コマンドに対応し、HTTP API経由ではtimeout_secsパラメータで同じ制御ができる。無限ループしたコードを自動で打ち切れる。
既定でネットワークは無効。--netで明示的に有効化した場合も、--allow-host/--allow-cidrで到達先を絞り込める。「何もつながらない」が既定値になっているのが安心材料。
-v HOST:GUEST[:ro]でディレクトリ単位のマウント(読み取り専用指定つき)ができ、machine cpでファイル単位のやり取りもできる。入力は読み取り専用、出力だけ書き込み可、という非対称な設計が組みやすい。
--unprivilegedフラグで機能を絞り込み、読み取り専用cgroupを適用できる。ストレージクォータの指定も可能。
「本物のVMを毎回起動する」と聞くと重そうに感じるが、実測された起動時間は冷起動0.6〜1.5秒・ウォーム実行で約50ミリ秒だった。ウォームプールは、事前に起動しておいたVMをmemfdとディスクのCopy-on-Writeクローンで複製し、fork方式のリースで使い回すことで実現している。データ変換のような短命タスクを繰り返し実行する用途には現実的な速度感といえる。
検証中に見つかった実務上の癖もひとつ記録されている。--image alpineのようにレジストリからイメージを直接参照する場合、--netを指定しないと事前に拒否される(オフラインでレジストリに問い合わせようがないため当然ではある)。オフラインで完結させたい場合は、docker saveで作ったtarアーカイブ(--image ./img.tar)や.smolmachineパック形式を使う、という代替経路が用意されている。なお初回起動時に限り、レジストリホストへのエグレスは自動的に許可される設計になっている。
この検証で地味に実務的なのが、検証環境そのものの制約とその回避策だ。Claude Code for webのコンテナ環境は、Firecracker guest内で動くLinux 6.18.5であり、ネスト仮想化に対応しておらず/dev/kvmも存在しない。VMの中でVMを動かすようなものなので、直接smolvmを検証することができなかった。
代替策として使われたのがGitHub ActionsのUbuntuランナーだ。こちらは/dev/kvmが露出しているため、一時的なワークフローファイル(.github/workflows/smolvm-sandbox-test.yml)をリポジトリに追加し、そこでsmolvmの検証を実行してログだけ回収し、最後にワークフローを削除する、という手順を踏んでいる。権限周りでは、Androidエミュレータの検証でよく使われる定番の対処——udevルール経由で/dev/kvmに0666権限を付与する——をそのまま流用した。
ここが持ち帰れる型。「自分の実行環境ではハードウェア仮想化が使えない」という壁にぶつかったとき、CIランナーを一時的な検証環境として借りるのは、個人開発でも応用が効く発想だ。恒久的な検証パイプラインとして残す前に、一時ワークフローで手早く実行可能性だけ確認する、という順番も参考になる。
このポートフォリオでもPythonスクリプトを使った自動化を多数運用しているが、実行しているのはすべて自分で書いたコードで、外部から渡された未信頼のコードを実行する場面は今のところない。だからこそ、この検証記録は「まだ要らない備え」を先に知っておく価値がある——将来、読者投稿のデータ変換やAI生成コードをその場で実行させるような機能を作るとしたら、コンテナでは足りないという判断がいつ必要になるかを、あらかじめ知っておけるからだ。
Hugging Faceの侵害事故を扱ったAIエージェントが4.5日間、脱走したまま暴れた話——Hugging Face侵入の技術タイムラインを読むと合わせて読むと、「AIエージェントに実行権限を持たせるなら、権限の境界線をどこに引くか」という同じ問いに、別の角度(侵入事故の事後分析 vs. 隔離技術の事前検証)から迫っていることが分かる。
留保: この記事はSimon Willisonの検証記録(ブログ本文およびsimonw/researchリポジトリのnotes.md)の内容整理であり、筆者自身の環境での再現検証は行っていない。smolvmはmacOS/Linux/Windowsに対応するが、Windows環境(WHPバックエンド)での動作確認はしていない。導入・運用に踏み込む場合は公式README(smol-machines/smolvm)を一次情報として当たってほしい。
--unprivilegedがすべてコマンドラインオプションで一級対応。/dev/kvm露出)に一時ワークフローを立てて検証し、ログ回収後に削除する、という借り方。