Hermes Agent 入門 — 初心者のためのハンズオンガイド|2026-09 版
第 13 章

セキュリティと運用 — 8 層防御と日々のメンテナンス

危険コマンド承認・コンテナ強化・鍵の置き場所から、update・doctor・FAQ まで

この章で分かること

これは何か

これまでの章で見てきたメモリ・スキル・ゲートウェイ・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 つだ。

とくに最初の 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. ユーザー認可 (User authorization) 2. 危険コマンド承認 (Dangerous command approval) 3. 書き込み安全性 (File write safety) 4. コンテナ隔離 (Container isolation) 5. MCP資格情報の隔離 (MCP credential filtering) 6. コンテキストスキャン (Context file scanning) 7. セッション間隔離 (Cross-session isolation) 8. 入力のサニタイズ (Input sanitization) 許可リスト外の相手からの操作 rm -rf 等の破壊的コマンド auth.json 等の機密ファイル上書き 悪意あるコードのホストへの波及 MCPサブプロセスへの鍵の漏洩 仕込まれたプロンプトインジェクション 他セッションのデータへの越境 作業ディレクトリ経由のシェル注入
図 13-1 8 層はそれぞれ守備範囲が異なり、代表的な脅威 1 つに対して防ぐ層も 1 つ決まっている。上の層ほど「誰が」、下の層ほど「どう実行されるか」に近い粒度を扱う。

この章では、初心者が実務で最初に触ることになる層 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・プロセス強制終了など、どれだけ承認回数が多くても破壊的なコマンドクラスは提案対象から除外される。

危険パターンに 一致するコマンド smart 分類 (補助LLM) 低リスク → 自動承認 不確実 → 手動プロンプト 高リスク → 自動拒否 「always」を選択 実行履歴 (state.db) → approvals suggest 許可リスト command_allowlist
図 13-2 「不確実」に分類されたコマンドは手動プロンプトへ回り、「always」を選ぶとその場で許可リストに追加される。もう 1 つの経路として、過去の承認履歴を hermes approvals suggest でまとめて許可リストへ反映することもできる。

この仕組みには 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/ 直下の別領域にあり、コードの入れ替えでは一切触られない。

~/.hermes/ の中の 2 領域 hermes-agent/ (git チェックアウト = コード) config.yaml / .env / auth.json skills・memory・state.db・cron = ユーザーデータ ① git pull (origin/main) ② 依存を再導入 (uv pip install) ③ 起動中ゲートウェイを自動再起動 任意の事前スナップショット quick(既定)/full/off — 変更はしない
図 13-3 hermes update が実際に書き換えるのは左の hermes-agent/(コード)だけ。右のユーザーデータ領域は変更されず、pre_update_backup 設定に応じて読み取り専用のスナップショットが取られるだけである。

もう少し具体的な手順は次のとおりだ。① 既定で軽量な状態スナップショットを取得(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 をいくつか拾っておく。

アンインストール

使うのをやめる、または入れ直したいときは 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 危険コマンド承認プロンプトを発火させて挙動を観察する

  1. 対話 CLI で、Hermes 自身に作らせたテスト用の一時ディレクトリを削除するよう頼む(例:「さっき作った作業用フォルダを rm -r で消しておいて」)。
  2. 削除コマンドが危険パターンに一致すると、次のような承認プロンプトが表示される。
⚠️  DANGEROUS COMMAND: recursive delete
    rm -r /tmp/scratch-dir

    [o]nce  |  [s]ession  |  [a]lways  |  [d]eny

    Choice [o/s/a/D]:
  1. ここでは安全のため d(deny、既定の選択肢)を選んで様子を見るだけにする。

拒否すると、コマンドは実行されずにその旨がエージェントへ返る。もし本当にそのフォルダを消してよいと分かっているなら「once」を選べば 1 回だけ、頻繁に使う操作なら「always」を選べば command_allowlist に恒久登録される。既定の smart モードでは、python -c "print('hi')" のような明らかに無害なコマンドはこのプロンプト自体が出ずに自動承認される点も併せて確認しておくとよい。

ハンズオン 13-2 hermes doctor でセットアップの健全性をチェックする

  1. ターミナルから次のコマンドを実行する。
hermes doctor

設定・依存関係・インストール方式(git/Docker/Nix のどれで入れたか)などの診断結果が一覧で表示される。問題が見つかった場合は具体的な直し方も併せて示される。

  1. 問題が見つかった場合、自動修復を試す。
hermes doctor --fix

設定ファイルの欠落や依存関係のずれなど、機械的に直せるものはここで解消される。手動対応が要る項目は、その理由付きで引き続き一覧に残る。

ハンズオン 13-3 hermes update --check で更新の有無だけを安全に確認する

実際に更新まで走らせる前に — hermes update(--check なし)は git pull・依存の再導入・ゲートウェイ再起動まで実行する本番の更新コマンドである。main ブランチを直接追いかける以上、実行するたびに新しい変更が入りうる。まずは何も変更しない --check で様子を見るのが安全だ。

  1. ターミナルから次のコマンドを実行する。
hermes update --check

ローカルのコードと origin/main を比較し、更新があるかどうかだけを表示する。ファイルは一切変更されず、ゲートウェイの再起動も起きない。

  1. 実際に更新する準備ができたら、まず計画だけを確認する。
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 はそれらを含めてすべて完全に削除する。

まとめ

全 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)

参考リンク