要約

Hermes AgentはLLMそのものではない。SlackやCLIから依頼を受け取り、会話履歴・ツール・権限・認証情報を管理し、選択したLLMプロバイダーへ推論を依頼するエージェント実行基盤である。Codexは、Hermesから利用できる推論先のひとつにあたる。

LLMが直接PCやDockerを操作するわけではない。LLMは文章やツール実行の提案を返し、実際に許可されたコマンドや外部サービスを呼び出すのはHermes側である。このため、モデルの認証と、Hermesへ与える実行権限は分けて考える必要がある。

OpenAI CodexのDevice Loginは、Hermesコンテナのようにブラウザを直接扱いにくいクライアントを、別のブラウザで本人確認してChatGPTアカウントへ結び付けるOAuth系の認証方式である。短い表示コード自体が長期認証情報なのではなく、本人がOpenAI公式画面で承認した後に、Hermes側が専用の認証情報を受け取る。

今回の構成では、その認証情報をホストPCの既存Codex環境からコピーせず、Docker named volume内だけに保存する。Device Loginは認証を安全に受け渡す仕組みであり、Hermesのファイル操作やネットワーク操作を制限するサンドボックスそのものではない。

背景

Hermes AgentをホストPC上のDocker環境で隔離して動かし、推論プロバイダーとしてOpenAI Codexを利用する構成を検討した。Hermesのセットアップ中に「OpenAI Codex device login」のURLと短いコードが表示されたため、この認証が何を行い、どこに情報が保存され、ChatGPTサブスクリプションやAPIキー認証とどう違うのかを整理する。

OpenAI公式ドキュメントでは、OpenAIモデルを使うCodexの認証方法を次の2種類に分けている。

  • Sign in with ChatGPT: ChatGPTサブスクリプション/Workspaceの権限と利用枠を使う
  • Sign in with an API key: OpenAI PlatformのAPIアカウントへ従量課金する

今回選んだのは前者である。APIキーをHermesへ登録する方式ではない。

Hermes・Codex・LLMプロバイダーの関係

混同しやすいので、まず役割を分けておく。

たとえるなら、LLMは「考えて指示案を作る部分」、Hermesは「依頼を受け、必要な情報を集め、許可された道具を実際に動かす作業環境」である。CodexはHermesそのものではなく、Hermesが選択できる推論先のひとつである。

flowchart LR
    U["ユーザー<br>Slack / CLI"] --> H["Hermes Agent<br>会話・権限・ツールを管理"]
    H -->|"認証付きのモデル要求"| P["LLMプロバイダー<br>Codex / API / ローカルモデル"]
    P -->|"回答またはツール利用の提案"| H
    H -->|"許可範囲で実行"| T["ツール<br>ファイル・シェル・Web・外部サービス"]
    T -->|"実行結果"| H
    H -->|"結果を含めて再度推論"| P
    H -->|"最終回答"| U

HermesがLLMを使う流れ

  1. SlackやCLIからHermesへ依頼が届く
  2. Hermesが依頼、会話履歴、設定、利用可能なツールの説明をまとめる
  3. Hermesが選択中のLLMプロバイダーへモデル要求を送る
  4. LLMが回答、または「このツールをこの引数で使いたい」という提案を返す
  5. Hermesが権限と設定に従ってツールを実行する
  6. Hermesが実行結果をLLMへ戻し、次の判断または最終回答を得る
  7. HermesがSlackやCLIへ回答する

重要なのは、LLMの認証に成功しても、それだけでホストPCのファイルや認証情報が見えるようにはならない点である。見える範囲は、Hermesのコンテナへ何をmountしたか、どのツールを有効にしたか、どのユーザーやチャンネルからの指示を許可したかで決まる。

LLMプロバイダーへの主な接続方法

APIキー方式は主流なのか

一般的なLLMアプリやサーバー間連携では、APIキー方式が今も標準的である。自動化しやすく、サービスの利用者個人ではなく、プロジェクトや組織のAPI利用として料金・上限を管理しやすいためである。HermesもOpenRouter、Anthropic、Geminiをはじめ、多数のAPIキープロバイダーへ接続できる。

一方、個人が手元のエージェントで既存のAIサブスクリプションを使う場合は、OAuthやDevice Loginも増えている。HermesのOpenAI Codex接続はこの型で、ChatGPTアカウントをブラウザで承認する。つまり「LLMエージェント全体ではAPIキーが一般的だが、今回のCodex連携ではDevice Loginが正式な接続方法」と理解するとよい。

APIキーもOAuthトークンも、HermesにLLMを呼び出す権限を与える認証情報である。どちらを選んでも、Hermesのツール権限やサンドボックスが自動的に安全になるわけではない。

今回の構成で起きていること

今回、Hermesはopenai-codexというプロバイダーを選択し、ChatGPTのDevice OAuthで認証している。Hermesは取得した認証情報を自分の認証ストアへ保存し、その情報を使ってCodexサービスへモデル要求を送る。ホストPC上のCodexアプリを遠隔操作しているわけでも、別プロセスのCodex CLIへ依頼を横流ししているわけでもない。

また、Codex以外のプロバイダーへ切り替える場合は、Hermesのモデル設定と認証方法を変更する。同じHermesのSlack連携やツール構成を保ちながら、推論先だけをAPIキープロバイダーやローカルモデルへ替えられるのが、この分離の利点である。

CodexだけではなくHermesを経由する理由

Codexにも、ローカルファイルの操作、コマンド実行、Skills、外部サービスとの連携、長時間の作業、Slackからのタスク開始など、Hermesと重なる機能がある。そのため、Hermesを追加すれば常に機能が増える、という単純な関係ではない。

違いは、どちらをシステムの中心に置くかにある。

  • Codex単体では、OpenAIが提供するCodexのアプリ、CLI、クラウド環境を中心に作業する
  • Hermes経由では、自分で動かすHermesを会話・ツール・運用の中心に置き、Codexを交換可能な推論先として利用する

つまり、Hermesを挟む目的はCodexの代替ではなく、Codexを自分のエージェント基盤の一部として使うことにある。

1. Slackに常駐するチームメンバーのように扱える

今回の目的では、ここが最も大きなメリットになる。

HermesのMessaging Gatewayはバックグラウンドで動き、SlackのDM、チャンネル、スレッドごとのセッションを管理する。チャンネル内の会話を受け取り、その場で質問へ答えたり、許可されたツールを使ったり、結果を同じスレッドへ返したりできる。

CodexにもSlack連携はあり、Slackの内容を扱ったり、SlackからCodexの作業を開始したりできる。ただし、HermesではSlackそのものをエージェントの常設UIとして運用し、mention要否、許可チャンネル、スレッドへの返信方法、定期実行結果の配送先などを自分で細かく構成できる。

今回やろうとしている「チャンネルの会話を踏まえ、同じチームメンバーのように応答する」という使い方には、HermesのGateway中心の設計が合っている。

2. LLMプロバイダーを後から切り替えられる

Hermes側にSlack、会話、ツール、Skillsを置いておけば、推論先をCodexから別のサービスへ変更しても、入口と作業環境を大きく作り直さずに済む。

例えば、用途や費用に応じて次のような変更が考えられる。

  • 普段はCodexを使う
  • 特定のタスクだけ別のAPIキーモデルを使う
  • 機密性を優先する処理をローカルモデルへ寄せる
  • 将来、価格や品質が変わったら別プロバイダーへ移る

これはモデルロックインを完全になくすものではない。モデルごとに品質、ツール呼び出し、コンテキスト長、利用規約が異なるため、切り替え時の検証は必要になる。それでも、Slack連携からすべて作り直すより変更範囲を小さくできる。

3. 会話、記憶、人格、SkillsをHermes側に蓄積できる

Hermesには、セッションをまたぐMemory、ユーザー情報、人格設定、Skillsの仕組みがある。これらをHermes側へ保持することで、推論モデルを交換しても「どう振る舞うか」「どの手順で仕事をするか」「過去に何を覚えたか」をある程度維持できる。

CodexにもSkills、設定、メモリや長時間作業の機能があるため、この領域も完全にHermesだけの機能ではない。Hermesを選ぶ意味は、それらをOpenAI製品の外側にある自分のランタイムへ置き、自分で保存場所や運用方法を決められる点にある。

4. 定期実行と通知先をひとつのGatewayで管理できる

HermesのGatewayは、メッセージ受信だけでなくcronスケジューラーも動かせる。自然言語で定期タスクを登録し、結果をSlackのチャンネルやDMへ戻す構成が可能である。

例えば、次のようなコーディング以外の用途が考えられる。

  • 毎朝、指定した情報源を確認して要約する
  • 定期的に状況を点検し、異常がある場合だけSlackへ通知する
  • チームの会話や資料から週次サマリーを作る
  • 決まった手順の調査や整理を繰り返す

CodexにもScheduled Tasksや長時間作業がある。Hermesのメリットは、実行環境、会話セッション、複数のメッセージサービス、配送先を自前のGatewayでまとめて管理できることにある。

5. 実行環境とデータ境界を自分で設計できる

HermesをDockerや専用VMへ置けば、次の範囲を自分で決められる。

  • どのディレクトリをmountするか
  • どの認証情報を渡すか
  • どのネットワークへ接続できるか
  • どのツールを有効にするか
  • どのSlackユーザーやチャンネルを許可するか
  • ログやMemoryをどこへ保存するか

これは自由度であると同時に責任でもある。設定を誤れば、Codex単体より安全になるとは限らない。隔離、更新、バックアップ、秘密情報管理、監視を自分で行う必要がある。

Hermesを使わなくてもよいケース

次の条件なら、まずCodex単体を使うほうが合理的である。

  • 自分ひとりがPC上で対話的に使う
  • 主な用途がリポジトリ内のコーディングや調査である
  • Slack常駐や複数チャネル対応が不要
  • モデルをOpenAI以外へ切り替える予定がない
  • サーバー、Docker、Bot token、更新、監視を管理したくない
  • Codex標準のSkills、連携、長時間作業、Scheduled Tasksで足りる

この場合、Hermesは便利な抽象化ではなく、保守対象と攻撃面をひとつ増やす可能性がある。

今回の構成でHermesを使う意味

今回の要件は、単にCodexへ質問することではない。

  • SlackのDM、mention、チャンネル、スレッドから利用したい
  • チャンネルの会話を踏まえて応答させたい
  • コーディング以外の調査、整理、定期作業にも使いたい
  • 将来はMacが起動していなくても動く常時運用を検討したい
  • 推論モデルやホスティング先を後から選び直せるようにしたい
  • エージェントへ見せるファイルや認証情報を隔離したい

この条件では、Hermesを会話と運用の基盤にし、Codexを推論エンジンとして使う構成に意味がある。短く言えば、Codex単体は「高機能な作業エージェント」、Hermes+Codexは「Codexの能力を使う、自前運用のSlack常駐エージェント」である。

全体像

flowchart LR
    U["本人<br>ホストPCのブラウザ"] -->|"1. OpenAI公式ページへログイン"| O["OpenAI認証サーバー"]
    H["Hermes Agent<br>Dockerコンテナ"] -->|"2. Device Login開始<br>外向きHTTPS"| O
    O -->|"3. URL・user code・device code"| H
    H -->|"4. URLと短いuser codeを表示"| U
    U -->|"5. 接続を承認/拒否"| O
    H -->|"6. device codeで状態をpolling"| O
    O -->|"7. 承認後に認証情報を返す"| H
    H -->|"8. Hermes専用領域へ保存"| V["Docker named volume<br>/opt/data"]
    H -->|"9. 認証済みリクエスト"| C["Codexサービス"]

ホストPCのブラウザとHermesコンテナが直接通信する必要はない。双方がOpenAIのサーバーへ外向きHTTPS通信を行う。したがって、コンテナへ受信ポートを開けたり、ホストPCからコンテナへコールバックURLを通したりする必要がない。

処理の流れ

1. HermesがDevice Loginを開始する

HermesはOpenAI側へ「このクライアントをユーザーのアカウントへ接続したい」と要求する。一般的なOAuth 2.0 Device Authorization Grantでは、認証サーバーから以下が返る。

  • verification_uri: ユーザーがブラウザで開くURL
  • user_code: 人間が入力する短いコード
  • device_code: Hermes側だけが保持して照合に使う長いコード
  • expires_in: コードの有効時間
  • interval: 承認状態を確認する最小間隔

表示される短いコードは、OpenAIアカウントのパスワードでも、恒久的なアクセストークンでもない。特定の認証要求を本人のブラウザ操作と対応付けるための、短時間有効な識別子である。

2. 本人が別のブラウザでOpenAIへログインする

ユーザーはHermesの画面へOpenAIパスワードを入力しない。ホストPCのブラウザでOpenAI公式のDevice Loginページを開き、普段どおりOpenAIへログインする。多要素認証が設定されていれば、その確認もOpenAI側で行われる。

URLのドメインが本当にOpenAI公式であることを確認する。チャット、メール、第三者サイトなどから別のURLへ誘導された場合は承認しない。

3. 短いコードを入力して接続をレビューする

ブラウザで短いコードを入力すると、OpenAI側はそのコードに対応するDevice Login要求を特定する。ユーザーは、意図したタイミングで開始した要求かを確認し、許可または拒否する。

4. Hermesは承認状態を定期確認する

Hermesはブラウザからの受信接続を待つのではなく、OpenAIのトークンエンドポイントへ定期的に問い合わせる。この方式をpollingという。

  • 未承認: authorization_pending相当。指定間隔を空けて再確認
  • 拒否: 認証失敗として終了
  • 期限切れ: 新しいDevice Loginをやり直す
  • 承認済み: OpenAI側が認証済みの情報を返す

そのため、URLや短いコードが期限切れになっても問題はない。新しいコードを発行して最初からやり直せばよい。

5. 承認後の認証情報をHermesが保存する

承認後、Hermesは今後のCodexアクセスに使う認証情報を受け取る。OAuthの一般論ではaccess tokenと、構成によってはrefresh tokenが含まれる。ただし、OpenAIとHermesの現在の実装がどの種類・形式・寿命のトークンを保存するかは公開仕様だけから断定しない。

今回確認できている事実:

  • Hermesは「自分専用のセッションを作り、ホストPC上の既存Codex CLIやVS Codeのセッションへ影響しない」と表示する
  • Hermes公式Docker構成では設定・認証の保存先として/opt/dataが使われる
  • /opt/dataは専用Docker named volumeへだけ接続されている
  • ホストPCの~/.codex、ホームディレクトリ、Keychainはコンテナへ共有していない

つまり、ホストPC上の既存認証を読み取って流用するのではなく、Hermes用の新しい認証セッションをOpenAIで承認する構成である。

認証後の信頼境界

flowchart TB
    subgraph MAC["ホストOS"]
        B["ホストPCのブラウザ<br>OpenAIログインセッション"]
        K["Keychain・~/.codex・~/.ssh<br>Hermesへ非共有"]
        subgraph DVM["Docker Desktop Linux VM"]
            subgraph CT["Hermesコンテナ"]
                HP["Hermesプロセス<br>実タスクは非特権ユーザー"]
                VOL["/opt/data<br>設定・Hermes専用認証"]
                HP <--> VOL
            end
        end
    end
    HP -->|"外向きTLS通信"| OAI["OpenAI / Codex"]
    B -->|"ログイン・承認"| OAI
    K -.-|"mountなし・参照不可"| HP
    HP -.-|"Docker socketなし"| DS["ホストDocker daemon"]

Device Loginが守るもの

  • パスワードをHermesへ直接入力・保存しなくてよい
  • ブラウザを持たないコンテナでも本人確認できる
  • ユーザーがOpenAI公式画面で許可/拒否を判断できる
  • 短いコードが期限切れになる
  • ホストPCの既存Codex認証をコピーせず、Hermes用セッションを分けられる

Device Loginだけでは守らないもの

  • Hermesが認証後に送信するプロンプトやデータ
  • Hermesのコマンド実行権限
  • コンテナ内のファイル
  • /opt/dataに保存された認証情報
  • 悪意あるskill、プロンプトインジェクション、誤操作
  • DockerやOSの脆弱性
  • Slack経由で誰がHermesへ指示できるか

これらはDocker隔離、mount制限、非特権ユーザー、Slack allowlist、手動承認、skill制限、秘密情報を渡さない運用などで別途守る。

ChatGPTサブスクリプションとAPI課金

OpenAI公式ドキュメントは、CodexクライアントについてChatGPTサインインを「subscription access」、APIキーを「usage-based access」と説明している。今回のHermesはAPIキーではなくChatGPTのDevice OAuthで認証するため、OpenAI PlatformのAPIキー従量課金を直接使う構成ではない。

ただし、Hermes公式ドキュメントは、対応するChatGPTプランや、Hermes経由の利用がプランのCodex利用枠へ具体的にどう算入されるかを「現時点で未文書化」としている。そのため、「ChatGPTサブスクリプションに入っていればHermesのLLM費用は必ずすべて賄える」とまでは断定できない。運用前に、実際のプラン上限、利用状況、OpenAI側の最新条件を確認する必要がある。

Hermesの第三者ツール、別provider、外部検索、音声、ホスティング、Slackなどの費用は別であり、ChatGPTサブスクリプションに含まれるとは限らない。

情報ごとの役割と重要度

セキュリティチェックリスト

認証前

認証後

よくある誤解

「短いコードを知った人は、すぐ自分のアカウントへ入れる?」

短いコードだけでOpenAIアカウントのパスワードや既存ブラウザセッションを盗めるわけではない。ただし、第三者が開始した認証要求を自分が誤って承認すると、第三者のクライアントへ自分の権限を与える可能性がある。コードではなく、何を承認しているかが重要。

「ブラウザ認証したらホストPCの全情報をHermesへ渡す?」

渡さない。OpenAIの認証と、ホストPCのファイルアクセス権は別問題。今回のDocker構成ではホストPCのホームディレクトリやKeychainをmountしていないため、Device Loginしただけでそれらが見えるようにはならない。

「認証したらHermesは安全?」

認証の正当性は確保できるが、Hermesの実行権限や入力データの安全性は保証しない。Hermesが認証済みであることと、Hermesへ機密情報を渡してよいことは別。

「ChatGPTサブスクなら完全に無制限?」

無制限ではない。プラン、Workspace、モデル、機能、レート/利用上限の影響を受ける。APIキーを使わない限りAPIの通常従量課金とは区別されるが、第三者サービス費用までサブスクに含まれるわけではない。

手順・再現方法

  1. Hermesコンテナ内でセットアップを開始する
  2. ProviderとしてOpenAI Codexを選ぶ
  3. 表示されたOpenAI公式Device Login URLをホストPCのブラウザで開く
  4. 表示された短いコードを入力する
  5. OpenAIの画面でアカウント・Workspace・接続内容を確認して許可する
  6. Hermesがpollingを終え、ログイン成功を返すまで待つ
  7. 認証値を表示せず、provider名とログイン状態だけを確認する
  8. 安全設定を確認してからSlack Gatewayを構成する

成果物・参照先

未解決事項

  • Hermes v0.20.0がOpenAI認証情報を内部的にどのファイル名・token形式・更新周期で保持するかは、秘密値を表示せず別途確認する
  • OpenAI側でHermes専用セッションを個別に確認・失効する具体的なUIは、認証完了後に確認する
  • ChatGPTプランごとの現行Codex利用上限は変動し得るため、運用開始時点の公式プラン情報を確認する
  • Slack接続後、allowlist外のユーザーやチャンネルを確実に拒否することを実地テストする
  • Device Login完了後にHermes設定の安全項目と同梱skillの許可範囲をレビューする

出典