この章で分かること
- Hermes のセキュリティが「1 枚の壁」ではなく8 層の防御として設計されていること、そしてどの層が何を防ぎ、何を防がないか
- 危険コマンド承認のフロー(
smart/manual/off)と、一度承認した操作が許可リストとして育っていく仕組み - 鍵・トークン・認証情報がどこに置かれ、何が常にブロックされ、何がゲートウェイの公開設定と関わるか
hermes update(git pull ベースの更新)とhermes doctor(健全性診断)の仕組み、そしてhermes uninstallの手順- 初心者が実際につまずきやすい落とし穴と、日々の運用で回すべきチェックリスト
これは何か
これまでの章で見てきたメモリ・スキル・ゲートウェイ・cron・委譲・実行環境は、どれも「エージェントに任せる範囲を広げる」機能だった。任せる範囲が広がるほど、間違った操作や悪意ある入力が実害に変わるリスクも広がる。この章で扱うのは、その広がった任せる範囲に対して Hermes がどんな安全装置を積んでいるか、そして日々の運用(アップデート・診断・撤去)をどう回すかである。
触る入口は主に 3 つに分かれる。ひとつは ~/.hermes/config.yaml の approvals セクションと環境変数 HERMES_WRITE_SAFE_ROOT・HERMES_YOLO_MODE で、危険な操作をどこまで自動化するかを決める設定値だ。もうひとつはセッション中に使う /yolo スラッシュコマンドや、実行中に一度だけ出る承認プロンプトそのもの。最後がターミナルから直接叩く CLI サブコマンド群(hermes doctor・hermes update・hermes uninstall・hermes security audit・hermes approvals)で、こちらは会話の外側から Hermes 自身の健全性・最新性・存在そのものを管理する。
いつ使うのか
「セキュリティ」は単機能ではなく、状況ごとに手を伸ばすレバーが変わる。代表的な場面は次の 4 つだ。
- 初めてゲートウェイを外部に公開する、あるいは cron や webhook のように人が張り付いていない場所でエージェントを走らせたい → 承認モード・許可リストの設計(本章)と、第 7 章の許可リスト・DM ペアリング
- 「基本は自動でどんどん進めてほしいが、これだけは絶対にやらせたくない」という運用を組みたい →
approvals.denyによるユーザー定義の拒否ルール - 信頼しきれないコード実行・調査タスクをホストに影響させず隔離したい → コンテナ隔離(第 10 章のコンテナ強化)
- アップデートしたら調子が悪い、そもそも設定が壊れていそう、使うのをやめたい →
hermes doctor/hermes update/hermes uninstall
とくに最初の 2 つは、似た言葉が並ぶぶん混同されやすい。「どこまで自動で進めてよいか」を決めるレバーは 1 つではなく、守備範囲も強さもばらばらだ。迷ったらこの表で選ぶ。
| レバー | 対象 | 効くもの | 効かないもの |
|---|---|---|---|
危険コマンド承認(approvals.mode) | terminal ツールの危険パターン | 不用意・誤りによる破壊的操作 | パターンに一致しない操作。コンテナ系バックエンドでは丸ごとスキップ |
ユーザー定義の拒否(approvals.deny) | terminal ツールの特定コマンド | --yolo/off でも止めたい絶対禁止事項 | グロブパターンに一致しない言い換え・別コマンド |
| ハードラインブロックリスト | 数種類の破滅的コマンドのみ | あらゆる設定を上書きする最終防波堤 | それ以外の危険操作全般(対象は極めて狭い) |
書き込み安全性(denylist / HERMES_WRITE_SAFE_ROOT) | write_file/patch のみ | 誤字・不注意による機密ファイルの上書き | terminal ツール経由のシェルでの読み書き(同じ OS ユーザー権限) |
| コンテナ隔離(第 10 章) | プロセス実行環境そのもの | 暴走・悪意あるコードのホストへの波及 | コンテナの中で完結する被害そのもの |
この表からも分かるとおり、Hermes は「1 つの強い壁」ではなく「それぞれ守備範囲の違う複数の壁」を積み重ねる設計を選んでいる。次の節でその全体像を見る。
8 層防御モデル全体像
公式のセキュリティドキュメントは、Hermes の安全設計を明示的に 8 つの層として説明している。上から順にたどると、「誰が話しかけられるか」から「入力文字列の細部」まで、粒度がだんだん細かくなっていくのが分かる。
この章では、初心者が実務で最初に触ることになる層 1(ユーザー認可)・層 2(危険コマンド承認)・層 3(書き込み安全性)を中心に掘り下げる。層 4(コンテナ隔離)は第 10 章、層 1 のうちゲートウェイまわりは第 7 章に譲り、層 5〜8 は公式ドキュメントで詳細を確認してほしい設計として名前だけ押さえておけば十分だ。
危険コマンド承認の仕組み — 判定から許可リストが育つまで
Hermes は terminal ツールでコマンドを実行する前に、既知の危険パターン(rm -r・chmod 777・DROP TABLE・curl … | sh など数十種類)と照合する。一致したら、~/.hermes/config.yaml の approvals.mode に従って次のように振る舞いが分かれる。
| モード | 挙動 |
|---|---|
smart(既定) | 補助 LLM がリスクを評価する。低リスクなコマンド(例: python -c "print('hello')")はその 1 回だけ自動承認、明らかに危険なものは自動拒否、判断がつかないものだけ人間への手動プロンプトに回す |
manual | 危険パターンに一致したら常に手動で承認を求める |
off | 承認チェックをすべて無効化する。--yolo と同義 |
手動プロンプトが出た対話 CLI では、[o]nce | [s]ession | [a]lways | [d]eny の 4 択が表示される。「once」はその 1 回だけ、「session」は今のセッション中だけそのパターンを許可、「always」を選ぶと ~/.hermes/config.yaml の command_allowlist にパターンが恒久保存され、以降のセッションでも黙って自動承認されるようになる。つまり許可リストは、使えば使うほど「よく承認するコマンド」を学習して育っていく仕組みだ。ゲートウェイ経由では同じ選択肢がチャット上の yes/no 返信に置き換わる。
毎回同じような操作に「always」を押し続けるのが面倒なら、hermes approvals suggest で過去の承認履歴からまとめて学習させられる。
hermes approvals suggest # 直近90日の承認履歴からドライラン提案
hermes approvals suggest --apply 1,3 # 番号を選んで command_allowlist に反映
このコマンドはセッションデータベース(~/.hermes/state.db)から「実際に承認されて実行されたコマンド」を集計し、git push * のようなパターンへ丸めて頻度順に提案する。何もしない限り config.yaml は一切書き換わらず(既定はドライラン)、--apply を明示して初めて反映される。安全側の設計として、再帰的な削除・sudo・ディスク/デバイスへの書き込み・認証情報や systemファイルの編集・パイプ to シェル・SQL の DROP/TRUNCATE・プロセス強制終了など、どれだけ承認回数が多くても破壊的なコマンドクラスは提案対象から除外される。
この仕組みには 2 段の例外がある。ひとつはハードラインブロックリストで、rm -rf /・bash フォーク爆弾・稼働中デバイスへの mkfs のような文字どおり致命的なパターンは、--yolo/approvals.mode: off/cron の approve モードのいずれでも一切バイパスできない。もうひとつはユーザー定義の拒否ルール(approvals.deny)で、こちらは逆に「基本は yolo で進めてよいが、これだけは常に止める」という運用のために、グロブパターン一致のコマンドを yolo より手前でブロックする。cron ジョブや hermes chat -q のような一発実行、webhook のような無人プラットフォームでは人間が承認プロンプトに答えられないため、それぞれ cron_mode・single_query_mode・unattended_mode(既定はすべて deny)で挙動を個別に決める。cron の運用設計自体は第 8 章を参照してほしい。最後に、docker・singularity・modal などコンテナ系バックエンドでは、コンテナ自体が境界になるためこの危険コマンドチェック自体がスキップされる。
鍵・トークンの置き場所とゲートウェイの公開面
もう一段細かい層 3(書き込み安全性)は、write_file/patch ツールが書き込もうとするパス自体を検査する仕組みだ。~/.ssh/・~/.aws/・~/.kube/・/etc/sudoers のような OS 側の認証情報や、auth.json・.env・mcp-tokens/・pairing/ のような Hermes 自身の認証情報は常にブロックされ、承認プロンプトすら出ずにその場でエラーが返る。config.yaml と .env・auth.json の役割分担そのものは第 2 章で扱ったとおりで、秘密は必ず .env 側にある。HERMES_WRITE_SAFE_ROOT を設定すると、書き込み先を特定のディレクトリ配下だけに絞るサンドボックスとしても使える(公式 Docker イメージでは既定で /opt/data に設定済み)。
書き込み安全性は多層防御の 1 枚であって、完全なサンドボックスではない — このガードが効くのは write_file/patch の 2 ツールだけである。terminal ツールは同じ OS ユーザー権限で動くため、同じ禁止パスでも cat ~/.hermes/.env のようにシェル経由で読むことは技術的に可能なままだ。本当に読み書きを断ちたいなら、この層だけに頼らずコンテナ隔離(第 10 章)を重ねる必要がある。
ゲートウェイでメッセージングプラットフォームに公開すると、守る対象は「ファイル」から「誰が話しかけてよいか」に変わる。認可は「① プラットフォームごとの allow-all → ② DM ペアリング承認済みリスト → ③ プラットフォーム固有の許可リスト → ④ グローバル許可リスト → ⑤ グローバル allow-all → ⑥ 既定拒否」の順で判定される(層 1・ユーザー認可)。トークンの取得場所・許可リストの書式・DM ペアリングによる権限分離の具体的な手順は第 7 章「トークンの取得と許可リスト」および「DM ペアリングと権限分離」にまとめてあるので、ここでは「公開面を作るならまずそこを固める」とだけ押さえておけば十分だ。すべての URL 対応ツール(Web 検索・抽出・vision・ブラウザ)は、社内ネットワークやクラウドのメタデータエンドポイント(169.254.169.254 など)を含むプライベートアドレスへの通信を fail-closed で遮断する SSRF 対策も内蔵している。パターン一致だけでは検出できない脅威(ホモグラフ URL・パイプ to インタープリタなど)向けには、外部ツール tirith によるコマンド実行前スキャンも統合されている。ただしこの事前スキャンは Linux/macOS 向けのビルドしか提供されておらず、ネイティブ Windows では静かにスキップされる(WSL2 経由なら Linux 版が動く)。公式の Platform Support ドキュメント(v0.21.0 時点)はネイティブ Windows 自体を最優先でサポートする Tier 1 と位置づけている(専用ガイドの機能一覧表に載る未対応項目はダッシュボードの埋め込みターミナルペインで、Tirith のスキップは security.md 側に別途記載されている個別の制限)。こうした個別の機能差を避けたい場合は、WSL2 経由で Linux 版として動かす選択肢もある(第 3 章)。
依存関係の供給網も攻撃対象になりうる。Hermes は起動時に、venv 内の Python パッケージを既知の侵害バージョンのカタログと突き合わせる仕組み(hermes_cli/security_advisories.py)を持ち、確認済みとしてマークしたい場合は hermes doctor --ack <advisory-id> を使う。これとは別に、hermes security audit は venv・~/.hermes/plugins/ 配下のプラグイン依存・config.yaml にピン留めされた MCP サーバーを、外部の脆弱性データベース OSV.dev と突き合わせるオンデマンド監査コマンドだ。
hermes security audit # 一発診断(既定は critical で失敗扱い)
hermes security audit --fail-on high # high 以上で非ゼロ終了
hermes update と hermes doctor — 育てながら安全に更新する
hermes update の実体は、公式ドキュメントが明言するとおり「git から最新のコードを pull し、依存を入れ直す」という単純な処理だ。ただし、あなたの設定・メモリ・スキル・セッション履歴が消えてしまわないのは偶然ではなく、ディレクトリ構造がそれを保証している。コード本体は ~/.hermes/hermes-agent/ という git チェックアウトの中にあり、hermes update はこのチェックアウトの中でしか git pull・依存の再インストールを行わない。config.yaml・.env・auth.json・skills/・メモリ・state.db(セッション)・cron/ といったユーザーデータは ~/.hermes/ 直下の別領域にあり、コードの入れ替えでは一切触られない。
もう少し具体的な手順は次のとおりだ。① 既定で軽量な状態スナップショットを取得(updates.pre_update_backup が quick/full/off、既定は quick)② main ブランチから git pull ③ 起動時に読み込む主要ファイルの構文検証(壊れていたら pull 前の SHA に自動で git reset --hard)④ uv pip install -e ".[all]" による依存の再導入 ⑤ 新しく増えた設定項目があれば対話的に設定を促す ⑥ 動いているゲートウェイの自動再起動。ローカルにコミットしていない変更がある場合は自動で git stash されたうえで pull が進み、対話端末なら復元するか聞かれる。どのインストール方式(git installer/Docker/Nix)で入れたかは自動判定され、Docker イメージのように「その場更新」に対応しない構成では、正しい更新コマンド(docker pull など)を案内して安全に処理を止める。
hermes update は安定版ではなく main ブランチを直接追いかける — タグ付きリリースを選んで更新する仕組みではないため、実行するたびに挙動が変わりうる。本番相当の運用では、まず読み取り専用の hermes update --check(更新の有無だけ確認、何も変更しない)や hermes update --plan(どのサービスがどう再起動されるかの計画だけ表示)で様子を見てから、必要なら --backup で HERMES_HOME 全体の完全バックアップを添えて実行するとよい。
更新の状態を確認したり、詰まったときの入口になるのが hermes doctor だ。設定・依存関係・接続性をまとめて診断し、--fix で自動修復を試み、--live を付けると実際に外部サービスへ読み取り専用の疎通確認まで行う。困ったらまずこれ、というのが公式ドキュメント全体を通した基本姿勢である。ここで初心者がよく踏む FAQ をいくつか拾っておく。
terminalツールの中でnode/nvmが見つからない — Hermes はセッションごとの環境スナップショットをログインシェルの単発起動で作るが、ログインシェルは~/.bashrcを読まない(/etc/profile・~/.bash_profileのみ)。nvm/pyenv等を~/.bashrcで初期化している場合は見えないので、config.yamlのterminal.shell_init_filesに明示的にファイルを追加する。/modelを打っても 1 つのプロバイダしか出てこない —/model(セッション内コマンド)はすでに設定済みのプロバイダの中でしかモデルを切り替えられない。新しいプロバイダを追加したいときはセッションの外、ターミナルからhermes modelを使う。- プロファイルを 2 つのエージェントで同時に指すと状態が壊れる — プロファイルはメモリもセッションも共有しない前提で作られているため、同じ Hermes ホームに複数のエージェントを向けると、互いのメモリ書き込みをセッション開始時に読み込み合って劣化する。なお
hermes updateは一度実行すればマシン上の全プロファイルに反映されるので、プロファイルごとに実行し直す必要はない。
アンインストール
使うのをやめる、または入れ直したいときは hermes uninstall を使う。
hermes uninstall --dry-run # 何が削除されるかだけ確認(変更しない)
hermes uninstall # 対話的に確認しながら削除
hermes uninstall --full # 設定・データ(~/.hermes/)ごと完全削除
hermes uninstall --yes # 確認プロンプトをスキップ
既定では設定ファイル(~/.hermes/)を残すかどうかを選べるので、コードだけ入れ直して設定は引き継ぎたい場合に向いている。--full を付けたときだけ設定・メモリ・スキル・セッション履歴を含めて全消去される点は取り違えやすいので注意したい。ゲートウェイをシステムサービスとして登録していた場合は、先に hermes gateway stop と各 OS のサービス無効化(Linux は systemctl --user disable、macOS は launchctl remove)を済ませておく。別マシンへ引っ越すだけで手元からは消したくない場合は、削除の前に hermes backup(認証情報を含む ~/.hermes/ 全体の zip)を取っておくとよい。
ハンズオン 13-1 危険コマンド承認プロンプトを発火させて挙動を観察する
- 対話 CLI で、Hermes 自身に作らせたテスト用の一時ディレクトリを削除するよう頼む(例:「さっき作った作業用フォルダを
rm -rで消しておいて」)。 - 削除コマンドが危険パターンに一致すると、次のような承認プロンプトが表示される。
⚠️ DANGEROUS COMMAND: recursive delete
rm -r /tmp/scratch-dir
[o]nce | [s]ession | [a]lways | [d]eny
Choice [o/s/a/D]:
- ここでは安全のため
d(deny、既定の選択肢)を選んで様子を見るだけにする。
拒否すると、コマンドは実行されずにその旨がエージェントへ返る。もし本当にそのフォルダを消してよいと分かっているなら「once」を選べば 1 回だけ、頻繁に使う操作なら「always」を選べば command_allowlist に恒久登録される。既定の smart モードでは、python -c "print('hi')" のような明らかに無害なコマンドはこのプロンプト自体が出ずに自動承認される点も併せて確認しておくとよい。
ハンズオン 13-2 hermes doctor でセットアップの健全性をチェックする
- ターミナルから次のコマンドを実行する。
hermes doctor
設定・依存関係・インストール方式(git/Docker/Nix のどれで入れたか)などの診断結果が一覧で表示される。問題が見つかった場合は具体的な直し方も併せて示される。
- 問題が見つかった場合、自動修復を試す。
hermes doctor --fix
設定ファイルの欠落や依存関係のずれなど、機械的に直せるものはここで解消される。手動対応が要る項目は、その理由付きで引き続き一覧に残る。
ハンズオン 13-3 hermes update --check で更新の有無だけを安全に確認する
実際に更新まで走らせる前に — hermes update(--check なし)は git pull・依存の再導入・ゲートウェイ再起動まで実行する本番の更新コマンドである。main ブランチを直接追いかける以上、実行するたびに新しい変更が入りうる。まずは何も変更しない --check で様子を見るのが安全だ。
- ターミナルから次のコマンドを実行する。
hermes update --check
ローカルのコードと origin/main を比較し、更新があるかどうかだけを表示する。ファイルは一切変更されず、ゲートウェイの再起動も起きない。
- 実際に更新する準備ができたら、まず計画だけを確認する。
hermes update --plan
どのインストール方式で入っているか、動いているサービスがどう再起動されるかを、何も変更せずに事前確認できる。ここまで確認してから実際の hermes update に進むと、想定外の再起動やエラーに驚かずに済む。
つまずきポイント
「Hermes policy により拒否されました」という散文をそのまま鵜呑みにしない — モデル自身が、なぜ自分が拒否したのかを正確に説明できているとは限らない。Hermes の実行制御が実際に働いたときは、承認プロンプトやツールエラーという明確な形で現れる。モデルの発言だけを根拠に「これは Hermes のセキュリティ機構が止めたものだ」と断定しないほうがよい。
ハードラインブロックリストを「これさえあれば安全」と誤解しない — rm -rf / やフォーク爆弾など、対象は数種類の破滅的パターンに限られる。それ以外の危険操作(機密ファイルの読み出し、意図しない外部送信など)はこのリストの対象外で、承認モードや deny ルール、コンテナ隔離など他の層で個別に守る必要がある。
書き込み安全性を万能の鍵管理と誤解しない — write_file/patch の denylist が auth.json や .env を守っていても、terminal ツールは同じ OS ユーザー権限を持つため、シェル経由での読み取りまでは防がない。本当に見せたくないなら、その環境自体をコンテナ隔離するか、鍵をそもそもそのマシンに置かない設計を検討する。
hermes uninstall --full と無印の違いを取り違えない — 無印は設定・メモリなどの ~/.hermes/ を残すかどうかを選べるが、--full は問答無用でそれらも含めて完全削除する。引っ越しではなく本当に撤去したいとき以外は、まず --dry-run で対象を確認してから進める。
理解度チェック
Q1. 危険コマンド承認における smart モードでは、リスクの高低に応じてそれぞれどう扱われますか。
補助 LLM がリスクを評価し、低リスクなコマンドはその 1 回だけ自動承認、明らかに危険なコマンドは自動拒否、判断がつかない場合だけ人間への手動プロンプトにエスカレーションされる。
Q2. 手動プロンプトで「always」を選ぶと何が起きますか。また、過去の承認履歴から同じ効果をまとめて得るコマンドは何ですか。
そのコマンドパターンが ~/.hermes/config.yaml の command_allowlist に恒久保存され、以降のセッションでも自動承認されるようになる。過去の承認履歴からまとめて提案・反映したい場合は hermes approvals suggest(--apply で反映)を使う。
Q3. ハードラインブロックリストと approvals.deny(ユーザー定義の拒否ルール)の違いを説明してください。
ハードラインブロックリストはコードに組み込まれた固定のリストで、rm -rf / のような数種類の破滅的パターンのみを対象に、どんな設定でも絶対にバイパスできない。approvals.deny はユーザーが自由に追加できるグロブパターンの拒否リストで、「基本は yolo で進めてよいが、これだけは常に止めたい」という運用のために使う、対象を自分で選べる拒否ルールである。
Q4. hermes update がコード側だけを更新し、ユーザーの設定やメモリを壊さないのはなぜですか。
コード本体は ~/.hermes/hermes-agent/ という git チェックアウトの中にあり、hermes update の git pull・依存再導入はこのチェックアウト内でしか行われない。config.yaml・.env・auth.json・skills・メモリ・state.db・cron といったユーザーデータは ~/.hermes/ 直下の別領域にあり、この更新処理の対象に含まれない。
Q5. hermes uninstall(無印)と hermes uninstall --full の違いは何ですか。
無印は設定・メモリなどの ~/.hermes/ を将来の再インストール用に残すかどうかを選べるのに対し、--full はそれらを含めてすべて完全に削除する。
まとめ
- Hermes のセキュリティは 8 層の防御で構成され、層ごとに守備範囲がはっきり分かれている。どれか 1 層に頼り切らず、組み合わせで考える
- 危険コマンド承認は smart/manual/off の 3 モードと、常に効くハードラインブロックリスト、逆に自分で追加できる approvals.deny の 2 段の例外を持つ。「always」承認と hermes approvals suggest の 2 経路で許可リストは育っていく
- 鍵・トークンは常に
.env/auth.json側にあり、書き込み安全性の denylist はそれを守るが terminal ツール経由の読み取りまでは防がない。ゲートウェイの公開面は第 7 章の許可リスト・DM ペアリングが担う - hermes update は git pull ベースでコード側だけを更新し、ユーザーデータは触らない。main を直接追う以上、まず --check や --plan で様子を見る運用が安全。困ったらまず hermes doctor
全 13 章を通じて、Hermes は「常駐して育つエージェント」という発想を、メモリ・スキル・ゲートウェイ・cron・委譲・多様な実行環境という具体的な機能に落とし込んできた。育つ範囲が広いエージェントほど、任せる前に安全装置を理解しておく価値は大きい。最後に、日々の運用で立ち返るためのチェックリストをまとめておく。
| タイミング | やること |
|---|---|
| ゲートウェイを新しく公開する前 | トークンを .env に置いたか、許可リスト・DM ペアリングを設定したか確認する(第 7 章) |
| cron・webhook など無人運転を組む前 | cron_mode/unattended_mode を意図した値(既定 deny)にしているか確認する |
| 危険な操作を「always」で許可した直後 | hermes config edit で command_allowlist の中身を見直す |
hermes update を実行する前 | まず --check で更新の有無、--plan で再起動対象を確認し、必要なら --backup を付ける |
hermes update の直後 | git status --short(作業ツリーの汚れ確認)→ hermes doctor → hermes --version → ゲートウェイ運用中なら hermes gateway status |
| 定期的に(月イチ目安) | hermes security audit でサプライチェーンの脆弱性を確認する |
| マシンを手放す・撤去する前 | hermes backup で ~/.hermes/ を退避してから hermes uninstall(必要なら --full) |