【ITニュース解説】core.hooksPath moves executable policy outside the repository
2026年11月05日に「Dev.to」が公開したITニュース「core.hooksPath moves executable policy outside the repository」について初心者にもわかりやすく解説しています。
ITニュース概要
Gitのcore.hooksPathは、フックの実行場所をリポジトリ外に設定できる機能だ。フックの集中管理や無効化に役立つが、リポジトリと別の場所でコードが実行されるため、セキュリティに十分注意し、適切な設定と監査が重要だ。
ITニュース解説
Gitフックとは、Gitを使ってコードを管理する際に、特定のタイミングで自動的に実行されるプログラムのことである。例えば、コードをコミットする前や、リモートリポジトリにプッシュする前など、開発ワークフローの特定の段階でこれらのプログラムが実行される。通常、GitフックはそれぞれのGitリポジトリの内部にある.git/hooksというディレクトリに置かれている。
しかし、core.hooksPathという設定を使うことで、このフックの実行場所を柔軟に変更できるようになる。この設定は、Gitがフックを探す場所を、リポジトリ内部の.git/hooksから、システム全体で共有される中央のパスへ変更したり、あるいはフック機能を完全に無効にしたりすることを可能にする。この機能は、多くのビルドを自動的に実行するビルドファームや、開発者のPC環境が厳しく管理されている場合に非常に役立つ。フックのコードを一元的に管理し、すべてのプロジェクトや開発者に対して同じルールやチェックを適用できるため、組織全体の品質やセキュリティを向上させる手助けとなる。
しかし、この柔軟性には注意が必要である。core.hooksPathによってフックの実行ポリシー(どんな処理が走るか)がリポジトリの外部に置かれるため、通常のコードレビューでは確認されないファイルがシステムの挙動に影響を与える可能性がある。
フックのパスがどのように解決されるかについて見てみよう。Gitの公式ドキュメントでは、フックは通常$GIT_DIR/hooks、つまりGitリポジトリの管理ディレクトリ内に存在すると説明されている。core.hooksPathに異なるパスを設定すると、Gitは代わりにその新しいパスを探しに行く。この設定値は、/opt/company/git-hooksのようなシステム上の完全な場所を指定する「絶対パス」でも、現在作業しているディレクトリからの相対的な場所を指定する「相対パス」でも指定可能である。
特にCI(継続的インテグレーション)環境では、相対パスの使用に注意が必要である。同じGit設定を使っている場合でも、異なるビルドジョブが異なる作業ディレクトリで実行されると、それぞれでフックの実行パスが意図せず変わってしまう可能性があるからだ。そのため、共有のフックディレクトリを設定する際は、常にシステム全体で一意の絶対パスを使うか、ビルド自動化スクリプト内でフックパスを明示的に指定することが推奨される。
また、core.hooksPath=/dev/nullと設定すると、すべてのGitフックを無効にできる。これは特定の状況で非常に有用な設定だが、Gitのマニュアルでは「パワーユーザー向け」とされており、一時的にフックを無効にしたいだけであれば、特定のGitコマンドを実行する際にだけ設定を上書きする、コマンドスコープの設定を使う方が良いとされている。システム全体に影響を与える設定変更は、予期せぬ挙動を引き起こす可能性があり、後でその影響を追跡するのが難しくなるため、慎重に扱うべきだ。
Gitフックは、それが実行されるGitプロセスと同じ権限でコマンドを実行する。開発者のローカルPCでフックが実行される場合、それはその開発者のアカウント権限で動作する。しかし、ビルドサーバーのワーカープロセスでフックが実行される場合、そのプロセスはシステムレジストリの認証情報や、ソフトウェアの署名キー、デプロイ先へのアクセス権限など、より高い機密情報にアクセスできる権限を持っている可能性がある。そして、フックはリポジトリにコミットされていなくても実行されうるという点も重要だ。
リポジトリ管理者は、コミットメッセージの書式を強制したり、すべてのコミットに署名を義務付けたり、本番環境へのデプロイ前に最終的なチェックを行ったりするために、中央で管理されるフックリポジトリを運用することがある。このような中央リポジトリは、開発からデプロイまでのソフトウェア供給チェーンの重要な一部となるため、そのセキュリティは非常に重要である。ブランチへのアクセス権限を厳重に保護し、フックコードへの変更は通常のコードレビューと同じくらい慎重に行い、デプロイされたフックファイルのハッシュ値などを記録して、改ざんがないか監視すべきだ。もしフックパスが、一般ユーザーが書き込み可能なディレクトリへのシンボリックリンク(別の場所を指すファイル)になっている場合、そのユーザーはフックと同じ権限を行使できてしまうため、これは重大なセキュリティリスクとなる。
フックの設定源も考慮する必要がある。フックパスは、特定のリポジトリ内の設定、ユーザーのグローバル設定、環境変数、またはgitコマンドのオプションなど、複数の場所から指定される可能性がある。どの設定が最終的に適用されているかを把握することが、フックを正しくレビューするための最初のステップだ。git config --show-origin --get-all core.hooksPathというコマンドを使えば、core.hooksPathの現在の設定値と、それがどの設定ファイル(または設定源)から来ているかを詳細に確認できる。リポジトリのローカル設定が常に最も優先されるとは限らないため、この確認は非常に重要である。
CI/CD(継続的インテグレーション/継続的デプロイメント)のビルドにおいて、リポジトリ内のフックを実行する意図がない場合は、gitコマンドを実行する際に明示的にフックを無効にすることが強く推奨される。例えば、git -c core.hooksPath=/dev/null commit -m "release"のように、-cオプションを使ってコマンド実行時に一時的にcore.hooksPathの設定を上書きできる。中央で管理されたフックの使用を必須とするビルドでは、そのパスを固定し、適切に保護する必要がある。具体的には、git -c core.hooksPath=/opt/company/git-hooks commit -m "release"のように指定する。
しかし、単にパスを指定するだけではセキュリティが完全に保証されるわけではない。フックが置かれるディレクトリは、特権を持つデプロイアカウントが所有し、ビルドを実行するユーザーやチェックアウトされたリポジトリからは書き込みできないように、厳重に権限が設定されている必要がある。また、フックファイル自体も、そのハッシュ値が管理され、他のビルドツールと同様に、レビュープロセスを経た信頼できる経路を通じてデプロイされるべきだ。ワークフロー内で実行される他のコマンドも同様にレビュー対象となる。ローカルで実行されるクライアントサイドフックは、特定のGitオプションを使うことでバイパスされてしまう可能性があるが、プッシュ時にサーバー側で実行されるサーバーサイドフックは、Gitサーバーの受信サービスの一部として機能するため、バイパスが難しい。したがって、ローカルでのコミットフックは、サーバー側で必須とされるブランチ保護チェックの代わりにはならないということを理解しておく必要がある。
信頼できないリポジトリをチェックアウトした後、Gitコマンドを実行する前には、そのリポジトリの設定とフックファイルを必ず検査することが非常に重要である。以下のコマンドを使って確認作業を進める。
git config --show-origin --get-all core.hooksPath:フックパスの設定元と値を確認し、予期しない設定がないかをチェックする。git --no-optional-locks status --short:フックを実行せずにリポジトリの現在の状態を簡潔に確認する。find "$(git rev-parse --git-dir)/hooks" -maxdepth 1 -type f -perm -u+x:リポジトリ内の.git/hooksディレクトリに、実行可能な(つまりスクリプトとして実行されうる)フックファイルが存在しないかを確認する。
これらの検査コマンド自体も、異常なGit設定下ではエイリアスや外部ヘルパーを実行してしまう可能性があるため、常に信頼できるGit設定コンテキストと、環境変数がクリアな状態で実行すべきだ。フックのパスや設定源が完全に把握できるまで、git commitやgit push、あるいはビルドスクリプトのような、フックが実行される可能性のあるコマンドは絶対に実行してはならない。
もし、フック自体やフックのパスが何らかのセキュリティ侵害を受けた疑いがある場合は、直ちに対処が必要である。まずは、フックの設定ソース、実際のフックファイル、ファイルのハッシュ値、およびそれらの親ディレクトリの権限設定をすべて保存しておく。次に、その侵害されたフックを実行したアカウントがアクセスできた可能性のあるすべての資格情報(パスワード、APIキー、SSHキーなど)をローテーション(新しいものに変更)する。侵害が疑われる期間中に作成されたビルド成果物や、デプロイの履歴なども詳細にレビューし、安全性に問題がないか確認する必要がある。単に侵害されたフックファイルを削除するだけでは不十分であり、侵害された資格情報による不正なアクセス経路が残ってしまう可能性があるため、必ず資格情報のローテーションを伴うべきである。
core.hooksPathは、Gitフックのコードを一元的に管理できるという点で、組織にとって非常に有用な機能である。しかし、その機能は、ビルドプロセスでロードされ、実行される他のあらゆるプログラムと同様に、厳格なレビューと適切なセキュリティ対策が講じられるべきである。Gitリポジトリからチェックアウトされるコードだけがシステム上で実行されるコードではない、という認識を持つことが、安全なソフトウェア開発において極めて重要となる。