こんにちは、テクマトリックスの米田です。
構成管理のツールとしてGitHubやGitLabなどを日常的に利用し、リモートリポジトリへアクセスするようになっている方も多いと思います。ただ一方で、git cloneやgit pushの裏側でどのように認証が行われているのか、意識しなくなっていることも多いと思います。そこで最近Gitの認証方式を振り返ってみたので、本記事で整理します。

Gitのリモートリポジトリへのアクセス方式

Gitのリモートリポジトリへ接続する方式は、主にHTTPSとSSHが使われます。それぞれの方式は、接続方式だけでなく、認証の仕組みも異なります。

HTTPS

HTTPSはWebブラウザと同じ仕組みを利用してリポジトリにアクセスする方式です。URLは次のような形式になります。

https://github.com/ユーザー名/リポジトリ名.git

HTTPS方式では、リポジトリへのアクセス時にユーザー認証が必要となる場合があります。現在はパスワードのほかにPersonal Access Token(PAT)を利用することができます。PATの利用の詳細はPersonal Access Token(PAT)の利用の章に記載します。
また、Git Credential Managerなどのツールと組み合わせることで、認証情報を安全に保存し、次回以降の操作で自動的に再利用することができます。詳細はCredential HelperとGit Credential Managerの章に記載します。

SSH

SSHは公開鍵認証方式を利用します。URLは次のような形式になります。

git@github.com:ユーザー名/リポジトリ名.git

あらかじめ公開鍵と秘密鍵のペアを作成し、公開鍵をGitホスティングサービスに登録しておくことで、ユーザー名やパスワード、PATを入力することなく認証が行われます。一度設定すれば認証操作を省略することができます。

Personal Access Token(PAT)の利用

HTTPSでリモートリポジトリにアクセスする場合、現在はアカウントのパスワードではなく、Personal Access Token(PAT)を使って認証をすることが多いです。GitHubでは、Git操作におけるパスワードを使用した認証は廃止されています(リンク)。
HTTPSでプライベートリポジトリにアクセスすると、Gitがユーザー名とパスワードの入力を求めることがあります。PATを使う場合には「パスワード」の欄にPATを入力します。
この背景には、パスワードを各種ツールや端末で使い回すよりも安全に運用できるためです。PATは権限や有効期限を設定でき、不要になったり漏洩の可能性がある場合も、そのトークンだけを失効できます。
GitHub以外のGitホスティングサービスでも同様に、パスワードの代わりにPATを使う方が安全に運用しやすいです。

GitのHTTPS認証のフロー

GitでHTTPSを利用してリモートリポジトリにアクセスする場合、認証はどのように行われているのでしょうか。
例えばgit cloneコマンドの実行時、HTTPS認証では次のような流れになります。

GitがHTTPSでリモートリポジトリに接続しようとした時、認証情報が必要であれば、まずは設定されているCredential Helperに問い合わせます。Credential Helper側に保存済みの資格情報があればそれを返し、保存されていなければログインやトークンの入力を促してその結果を今後使えるように保存します。認証が成功した後、クローンすることができます。

Credential HelperとGit Credential Manager

Credential Helperとは

Credential Helperとは、Gitが認証情報(ユーザー名やパスワード・PATなど)を取得・保存するために利用する仕組みのことです。Git自身には認証情報を安全に保管する機能がないため、Credential Helperを通じて認証情報の取得や保存を行います。
Credential Helperにはいくつかの種類があり、認証情報の保存方法や扱いが異なります。代表的なものは以下の通りです。

種類保存方法特徴
storeファイルに保存パスワードが暗号化なしのテキストファイルで保存される。セキュリティに注意が必要。
cacheメモリに一時保存一定時間のみ保持される。ディスクには保存されない。
managerOSの安全な領域に保存Git Credential Managerが利用される。
参考:Git のさまざまなツール – 認証情報の保存

Git Credential Managerとは

Credential Helperの代表的な実装の一つとして、Git Credential Manager(GCM)があります。GCMは、Gitから呼び出されて実際に認証情報を扱うツールです。Gitが認証情報を必要とした時、GCMが保存済みの認証情報を取得したり、必要に応じてユーザーに入力を求めたりします。また、入力された認証情報は次回以降のために保存されます。
Git Credential Managerの公式リポジトリでは以下のように説明されています。

Git Credential Manager (GCM) is a secure Git credential helper built on .NET that runs on Windows, macOS, and Linux. It aims to provide a consistent and secure authentication experience, including multi-factor auth, to every major source control hosting service and platform.

https://github.com/git-ecosystem/git-credential-manager#git-credential-manager

Git Credential Manager (GCM)は、.NETで実装されたセキュアなGit credential helperであり、Windows、macOS、Linuxで動作します。主要なソースコードホスティングサービスに対して一貫した安全な認証体験を提供することを目指している

Google 翻訳を基に一部修正

GCMがあると何が嬉しいのか

GCMを利用することで、GitのHTTPS認証は大きく使いやすくなります。以下にGCMを利用することによるメリットを記載します。

  • 認証情報を毎回入力する必要がなくなる
    初回の認証時にはパスワードやPATなどの入力が必要になりますが、一度保存されれば、次回以降は自動的に認証が行われます。そのため、日常的なGit操作において認証を意識する場面はほとんどなくなります。
  • トラブル時の切り分け
    認証情報が一元的に管理されるので、認証エラーが発生した場合は「Gitの問題」ではなく「保存されている認証情報の問題」と考えることができるため、問題を切り分けやすくなります。
  • 認証情報のセキュアな管理
    OSのセキュアな保存領域と連携して認証情報を管理します。そのため、認証情報を平文で保存する方式と比較して、より安全に運用できます。

認証情報の保存と設定の確認

認証情報はどこに保存されるか

Git自体は認証情報の保存場所を持たず、Credential Helperを通じて外部に保管する仕組みになっています。そのため、どこに保存されるかは利用しているCredential Helperによって異なります。
Credential HelperとしてGCMを利用している場合、保存先はOSのセキュアな保存領域に保管されます。

OS保存先
Windows資格情報マネージャー
macOSkeychain
LinuxGNOME KeyringやKDE Walletなどのシークレットサービス
参考:Git credential helpers

特にWindowsでは、認証情報は資格情報マネージャーに保存されますが、[コントロールパネル] > [ユーザーアカウント] > [資格情報マネージャー] > [Windows資格情報]の順で確認することができ、ここから認証情報の編集や削除ができます。

Credential Helperの設定の確認方法

現在どのCredential Helperが登録されているのかは、以下のコマンドを実行することで確認できます。

$ git config --global --get credential.helper

コマンド実行後、managerや、旧表記のmanager-coreが表示されれば、GCMを利用しています(GitHubのドキュメントより)。

Credential Helperを変更したい場合は、以下のコマンドを実行することで変更できます。

$ git config --global credential.helper <変更したいCredential Helper名> <option>

Credential Helper変更時のコマンドオプションの一例は公式ページに記載があります。

認証トラブルが起きたときに見るべきポイント

GitのHTTPS認証でAuthentication failedなどのエラーが発生した場合、Git本体ではなく認証情報やそれを保存・取得する仕組み側(Credential Helper)側に原因があることがよくあります。GitはCredential Helperを通じて保存している認証情報を再利用するため、保存されていた認証情報が古かったり、誤っていると認証は失敗してしまいます。トラブル時は「どの認証方式が使われているか」「どこに保存されているか」を確認することが重要です。

  1. 保存されている認証情報を確認する
    ・PATが期限切れになっていないか
    ・PATの権限が不足していないか
    ・別アカウントの認証情報が残っていないか
    これらの場合は、必要に応じて該当する保存済みの認証情報を削除し、再度認証してみると解決に向かいます。
  2. Credential Helperの設定を確認する
    想定しているCredential Helperが設定されているか確認します。想定しているCredential Helperと設定が異なる場合、次のような問題が起きます。
    ・保存したつもりの場所に認証情報が保存されていない
    ・別のCredential Helperが動作し、期待していない認証情報が返ってくる
    これらの場合は、現在どのCredential Helperが有効になっているかを確認し、想定しているCredential Helperとなるよう修正します。

まとめ

GitのリモートリポジトリへのアクセスにはHTTPSとSSHがありますが、今回取り上げたHTTPSの認証を利用されている方は多いと思います。Gitを利用していくと認証の詳細を意識しなくても困らないことが多いですが、いざエラーが起きた時には、Gitの認証の仕組みを把握しておくとトラブルシューティングや運用の見直しで役に立ちます。
この記事がGitのHTTPS認証を振り返る際に参考になれば幸いです。

宣伝

テクマトリックスのソフトウェア開発基盤ソリューションでは、Gitを用いたソフトウェア構成管理の環境構築を支援するサービスをご提供しています。構成管理の環境について気になることがあれば、お気軽にお問い合わせください。

By yoneta