8月21日、Jake Saundersが「Building an (almost) fully self-hosted, sandboxed, agentic software factory」と題した記事を公開した。「カロリー管理アプリを作ってデプロイして」という1プロンプトを送るだけで、コード生成・CI・HTTPS付きデプロイまでを人間の介入なしに完走させる——そんなシステムを自宅サーバーに構築した記録だ。
AIによる「Vibe Coding」(自然言語だけでコードを生成させる開発スタイル。Simon Willison氏による解説が広く参照されている)が普及する中、「LLMに自分のマシンのroot権限を渡したまま自律動作させるのは気持ち悪い」という感覚を持つ開発者は少なくない。Devin・Claude Computer Useといったエージェントがホストマシン上でコマンドを実行できるようになった2024〜2025年以降、「エージェントをどう封じ込めるか」はセキュリティ界隈でも実用的な問いになりつつある。本記事はその問いに正面から向き合い、「信頼するのではなく構造的に封じ込める」という設計思想でシステムを作り上げた実践報告だ。
1プロンプトで「repo作成→テスト→CI→デプロイ」まで全自動
送ったプロンプトはこれだけだ:
Please build me an app for tracking my calorie intake. It should be similar to MyFitnessPal...
Your task is to build it, commit it to a new repo with tests, test it with CI, and deploy it to
http://calories.internal.jakeshomelab.me.
エージェントはその後、人間の介入なしに以下を順番に実行した:
- SvelteKit・Drizzle・Postgres・Tailwindでプロジェクトをブートストラップ
- アプリとテストを実装し、適切な粒度でコミット
- CIパイプラインを作成し、テスト失敗を自力で修正してグリーンに
- Docker Composeでコンテナ化し、専用のPostgresインスタンスごとデプロイ
- CoolifyにHTTPS付きのURLでデプロイ完了
その後CSRFの問題が発生したため追加プロンプトを1件送ると、診断・修正・回帰テスト追加・再デプロイまで自動で完結した。
「LLMにrootを渡すのが嫌だ」という問題意識
このシステムが生まれた動機はシンプルだ。Jake Saundersはジムで使うウェイトトラッカーが欲しくなり、Claudeでサクッと作った。だが「LLMに自分のマシンのroot権限を与えたまま自律動作させるのは気持ち悪い」という感覚が拭えなかった。
そこで立てた問いが「LLMを信頼するのではなく、構造的に封じ込めつつ、ソフトウェア開発ライフサイクル(SDLC)全体を自律的に走り切らせるにはどうするか」だ。
サンドボックスの設計:「壊れても惜しくない」機械を用意する
ハードウェアは2台体制。普段使いのホームラボサーバー(2014年製 Core i3、45個のDockerコンテナを稼働中)とは別に、eBayで新規購入した2021年製 Core i7・32GB RAMのマシンをエージェント専用機として用意した。「壊れてもeBayの箱を再構築してキーをローテートすれば済む」という設計思想だ。
ネットワーク面では、エージェント専用機には外部からのポート開放を一切しない。インターネットからのインバウンドがなければ、攻撃面が大幅に削れる。
外部公開なしでHTTPSを出す仕組み
外部アクセスなしでHTTPS付きURLを実現するため、DNS-01チャレンジを採用した。これはLet's Encryptの証明書発行方式の一つで、HTTPで到達できないホストに対しても、DNSのTXTレコードでドメイン所有を証明して証明書を取得できる方式だ(参考:Let's Encrypt公式ドキュメント)。
具体的にはCoolifyのDocker Compose設定でlegoとPorkbun APIを組み合わせ、こう設定する:
- '--certificatesresolvers.letsencrypt.acme.dnschallenge=true'
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=porkbun'
新サービスを登録すると、Traefik(CoolifyのリバースプロキシとしてHTTPSルーティングを担うコンポーネント)がPorkbun APIでTXTレコードを作成→Let's Encryptが検証→証明書発行→TXTレコード削除、という流れが自動で走る。
外部にAレコードを公開せず、**Tailscale経由のtailnet内からのみ到達可能なHTTPS URL**が手に入る。Coolifyはこれをサービス登録のたびにオンザフライで処理するため、エージェントが新しいサブドメインを作成すれば自動的に証明書まで揃う。
スタック構成
| コンポーネント | 役割 |
|---|---|
| Coolify | セルフホスト型PaaS。HerokuライクにDockerベースでサービスを管理 |
| Forgejo(+runners) | セルフホストのGitおよびCI。GitHubの完全互換代替 |
| Hermes(+WebUI) | Jake自作のカスタムエージェントフレームワーク。推論バックエンドにOpenAI Codexを使用し、スキルを自分で作成・登録できる拡張可能な設計になっている |
| Firecrawl(セルフホスト) | エージェントがWebスクレイピングやSERPデータにアクセスするためのレイヤー |
| Tailscale | VPNでホームネットワークをどこでも持ち歩く |
| Pi-hole | ローカルDNSルールを管理 |
| Telegram | スマートフォンからエージェントに指示を送る |
| Porkbun + Let's Encrypt | ドメイン管理とSSL証明書の自動発行 |
GitHubを使わない理由として、「エージェント専用機にGitHubトークンを渡すと隔離の意味が薄れる」「APIやCI分数の制限がスケールしない」「最近よく落ちている」の3点を挙げている。
エージェント(Hermes)は自分でスキルを作成・登録できる。適切なCoolifyスキルが見つからなかったため、ドキュメントとMCPを読んで自分でビルドしたという。
サンドボックスの限界と今後の課題
正直に「完全に安全ではない」と明示しているのがこの記事の誠実な部分だ。現状のエージェントには以下のことができてしまう:
- 専用サーバーとその上の全コンテナを破壊する
- リポジトリ・DB・デプロイを削除する
- 渡したクレデンシャルを漏洩・悪用する
- 推論トークンを大量消費する
- ネットワーク内の他ホストへアクセスする(ファイアウォールが許す範囲で)
次のステップとして挙げられているのは、専用VLANでホームネットワーク全体からの隔離、クレデンシャルの最小権限スコープと定期ローテーション、ボックス再構築の完全自動化、「公開状態になる・ロールバックが困難な操作」への承認ゲート追加だ。
ただし、承認ゲートを増やすほど「自律ソフトウェアファクトリー」が「フォームだらけのワークフロー」に近づく、というジレンマも率直に指摘している。セキュリティと自律性のトレードオフをどこで引くかは、読者それぞれのユースケース次第だろう。
詳細はBuilding an (almost) fully self-hosted, sandboxed, agentic software factoryを参照していただきたい。