Claude CodeのallowedHttpHookUrlsでHTTP hookの送信先を制限する
allowedHttpHookUrlsはtype: httpのHooksが送信できるURLをワイルドカードで絞り込む設定キーです。合算の仕組みとallowManagedHooksOnlyとの使い分けを扱います。
allowedHttpHookUrlsは、type: "http"のHooksが送信先にできるURLをワイルドカードパターンで絞り込む設定キーです。既定は未設定で、どのURLでも呼び出せます。HTTP hookそのものの設定方法はClaude CodeのHooksをHTTPエンドポイントで受けるにまとめてあるので、本記事は送信先を制限する仕組みとワイルドカードの書き方、関連するallowManagedHooksOnlyとの役割分担に絞ります。
allowedHttpHookUrlsが制限する範囲
allowedHttpHookUrlsが制限するのはHTTP hookの送信先URLだけです。定義すると、Claude Codeはこのキーに登録したパターンのいずれかに一致するURLを持つHTTP hookだけを実行し、一致しないものは黙って起動せずブロックします。
対象はtype: "http"のHookに限られます。コマンド型・MCPツール型・プロンプト型・エージェント型のHookはこのキーの影響を受けません。空の配列を指定するとすべてのHTTP hookをブロックする挙動になり、これはHTTP hookという機能自体を組織で使わせたくない場合の設定として使えます。この許可リストは、ユーザー・プロジェクト・ローカルはもちろん、管理ポリシー設定(managed settings)由来のHTTP hookにも等しく適用されます。管理者が配布したHookだからといって送信先チェックが免除されるわけではありません。
ワイルドカードパターンの書き方
パターンは*をワイルドカードとして使う文字列の配列です。次の例はhttps://hooks.example.com/配下の任意のパスと、任意のポートのhttp://localhost宛てURLを許可します。
{
"allowedHttpHookUrls": ["https://hooks.example.com/*", "http://localhost:*"]
}このキーのスコープはAny fileです。つまり~/.claude/settings.json(User)・.claude/settings.json(Project)・.claude/settings.local.json(Local)・managed settingsのどのファイルにも書け、配列は設定ファイルをまたいで合算されます。1つのファイルにまとめて全パターンを書く必要はなく、個人用のパターンをUser側、プロジェクト固有のパターンをProject側に分けて書いても、実行時には両方が有効な許可リストとして扱われます。
ホスト名の比較ルール
ホスト名の比較は大文字小文字を区別しません。また、完全修飾ドメイン名(FQDN)であることを示す末尾のピリオド付き表記(hooks.example.com.)は、ピリオドなしのhooks.example.comと同一のホストとして扱われます。これはDNSがこの2つの表記を同じ名前として解決する挙動に合わせたものです。パターンを書くときにホスト名の大文字・小文字や末尾ピリオドの有無を気にする必要はありません。
httpHookAllowedEnvVarsでヘッダーの環境変数も絞り込む
HTTP hookはheadersフィールドに$MY_TOKENのような形で環境変数の値を埋め込み、リクエストヘッダーとして送信できます。ただしこの埋め込みは、Hook定義自身が持つallowedEnvVarsにその変数名を列挙している場合に限られます。httpHookAllowedEnvVarsは、このallowedEnvVarsにさらに外側から上限をかける設定キーです。ある環境変数がヘッダーに載るのは、Hook定義側のallowedEnvVarsと、このグローバルなhttpHookAllowedEnvVarsの両方がその変数名を列挙しているときだけで、どちらか一方でも列挙していなければ空文字列に置き換わります。
{
"httpHookAllowedEnvVars": ["MY_TOKEN", "HOOK_SECRET"]
}この二重ゲートの狙いは、Hookの定義自体が想定外のシークレットを要求してきても、グローバル側の許可リストに無ければ読み出せないようにすることです。managed settingsでこのキーを定義しておけば、プロジェクトやプラグインが持ち込むHook定義がどんなallowedEnvVarsを書いていても、組織が許可した変数名以外はヘッダーに乗りません。スコープと合算の挙動はallowedHttpHookUrlsと同じAny fileで、User・Project・Local・Managedの各ファイルに書いたエントリが合算され、managed settings由来のHookにも等しく適用されます。
配列はスコープをまたいで合算される
Any fileスコープで配列が合算されるという挙動には、見落としやすい意味があります。Project(.claude/settings.json)はリポジトリにコミットできるファイルで、Local(.claude/settings.local.json)は各開発者のローカル環境で追記されるファイルです。どちらもこのキーにエントリを追加でき、追加されたパターンはそのセッションの許可リストに合算されます。
つまり、組織がmanaged settingsでallowedHttpHookUrlsを狭く定義していても、プロジェクト側の設定ファイルが独自のパターンを追加すれば、そのセッションで有効な許可リストは合算後の広い範囲になります。この許可リストはmanaged settings由来のHTTP hookにも等しく適用されるため、「managed settingsで絞ったから安全」という前提は、プロジェクトやローカルの設定ファイルを誰が書き換えられるか次第で崩れます。共有リポジトリの.claude/settings.jsonを信頼できないコントリビューターが変更できる環境では、この合算の仕組みを踏まえて運用する必要があります。同じ合算の挙動はhttpHookAllowedEnvVarsにも当てはまるため、送信先とヘッダーの両方を組織側で固定したい場合は、どちらのキーもこの前提で設計します。
Claude Code Channels組織管理で扱った、許可プラグインの制限をmanaged settingsに寄せる考え方と同じ構図です。下位スコープが追記できる設定と、Managedにしか書けない設定を混同すると、組織側の意図した制限より緩い状態で運用してしまいます。
信頼していないリポジトリで実行するときの注意
配列が合算されるという挙動が実際に問題になりやすいのは、書き換えられた.claude/settings.jsonを含むリポジトリを実行してしまう場面です。Claude Codeはワークスペースの信頼状態をセッションの種類によって別々に扱います。対話セッションでは、フォルダに対してワークスペース信頼ダイアログを承認するまで、~/.claude/settings.jsonを含むすべての設定ファイル由来のHookが保留されます。一方-pフラグやAgent SDK経由のセッションではこのダイアログ自体が出ず、フォルダは常に信頼済み扱いになるため、書いた覚えのないリポジトリの.claude/settings.jsonにコミットされたHookも、そのまま実行されます。
自分が書いていないリポジトリに対してclaude -pをスクリプトで回す前には、その.claude/配下の設定ファイルを事前に確認するか、起動を--bareにするか、--settings '{"disableAllHooks": true}'でその実行だけHookを止めるかのいずれかを検討します。allowedHttpHookUrlsとhttpHookAllowedEnvVarsが下位スコープからの追記で広がる可能性がある以上、この対策は「送信先を絞ったから安全」という判断だけに頼らないための実務上の備えになります。
allowManagedHooksOnlyとの役割分担
似た目的で使われる設定キーにallowManagedHooksOnlyがあります。両者は制限する対象がまったく異なります。
| 項目 | allowedHttpHookUrls | allowManagedHooksOnly |
|---|---|---|
| 制限する対象 | allowedHttpHookUrlsHTTP hookの送信先URL | allowManagedHooksOnly実行できるHookそのもの(型を問わない) |
| 設定できる場所 | allowedHttpHookUrlsAny file(User/Project/Local/Managed、合算) | allowManagedHooksOnlyManagedのみ |
| 既定 | allowedHttpHookUrls未設定 = 制限なし | allowManagedHooksOnly未設定 = 全ソースのHookが実行される |
| trueまたは定義した場合の効果 | allowedHttpHookUrls一致しないURLのHTTP hookをブロック | allowManagedHooksOnlymanaged settings由来のHookとAgent SDKのHook、managedのenabledPluginsで強制有効化されたプラグインのHookだけが実行され、ユーザー・プロジェクト・ローカル・その他プラグインのHookとagent frontmatter由来のHookは全部ブロックされる |
allowManagedHooksOnlyはManagedスコープにしか書けないため、allowedHttpHookUrlsのように下位スコープから合算で広げられることがありません。ユーザーやプロジェクトが独自のHTTP hookを追加できないようにしたいなら、allowedHttpHookUrls単体ではなくallowManagedHooksOnlyをtrueにする方が確実です。allowManagedHooksOnlyが有効な間は、statusLine・fileSuggestion・subagentStatusLineもmanaged settings由来のものだけに絞られ、/goalコマンドはHookに依存するため使えなくなります。
実務での組み合わせ方
個人のローカル開発だけで完結させるなら、allowedHttpHookUrlsをhttp://localhost:*だけに絞れば十分です。検証用のHTTP hookサーバーをローカルで立てて動作確認する用途に向きます。
組織で配布するHookの送信先を固定したい場合は、managed settingsでallowedHttpHookUrlsを社内ドメインのパターンに絞り込みます。ただし前述のとおり、この設定だけではプロジェクトやローカルの設定ファイルからの追加を防げません。ユーザー・プロジェクト・ローカル由来のHookそのものを一切実行させたくないなら、allowManagedHooksOnlyをtrueにして組み合わせます。この状態では許可された送信先の中でも、実行できるHookはmanaged settings由来のものだけに絞られるため、二重の制限として機能します。次のようなmanaged-settings.jsonが、送信先・ヘッダーの環境変数・実行元のすべてを組織側に固定する構成です。
{
"allowedHttpHookUrls": ["https://hooks.internal.example.com/*"],
"httpHookAllowedEnvVars": ["HOOK_SECRET"],
"allowManagedHooksOnly": true
}Agent Teams Hooksで強制する品質ゲートの仕組みのように、Hookで品質ゲートを組織全体に強制する構成では、このパターンを使えばゲート用HTTP hookの送信先とヘッダーの秘密情報を組織側に固定しつつ、開発者が独自のHTTP hookを追加して同じゲートを迂回することを防げます。
HTTP hookという機能自体を組織で禁止したい場合は、allowedHttpHookUrlsを空配列にするのが最短です。コマンド型やMCPツール型のHookは影響を受けないので、Hooks全体を止めたいわけではなく送信先付きの仕組みだけを止めたいときに使えます。
よくある誤解
allowedHttpHookUrlsはHTTP hookの送信先だけを見ており、コマンド型のHookが呼び出すスクリプトの中身までは検査しません。スクリプトが内部で任意のURLにリクエストを送ることまでは制限できないため、送信先の制御はあくまでHTTP hookという仕組みに限定した対策です。Hooks全体を一時的に止めたいだけなら、送信先の許可リストではなくdisableAllHooksを使う方が目的に合います。
まとめ
allowedHttpHookUrlsはHTTP hookの送信先をワイルドカードパターンで絞り込む設定キーで、既定では制限がなく、配列はUser・Project・Local・Managedの各設定ファイルをまたいで合算されます。この合算の仕組みにより、managed settingsだけで狭く絞っても下位スコープから広げられる余地が残る点には注意が必要です。実行できるHookそのものを組織側で固定したい場合は、Managedスコープにしか書けないallowManagedHooksOnlyと組み合わせるのが確実な構成になります。