LinuxでGit Credential ManagerとlibsecretでGit Credentialsを安全に管理する:GitHub/GitLabトークンを自動保存

Git tutorial - IT technology blog
Git tutorial - IT technology blog

実際の問題:パスワード/トークンを毎回入力するのは面倒だ

GitHubが2021年8月にパスワード認証を廃止してから、Personal Access Token(PAT)を使わざるを得なくなりました。git pushのたびに40文字のトークンを貼り付ける作業は本当に面倒です。しかも、トークンは30〜90日で期限切れになり、新しいものを生成して更新しなければなりません。

6ヶ月の実際のデプロイ経験の中で、最もシンプルな方法から現在使っている方法まで、4つの異なるアプローチを試してきました。この記事では、その経験から学んだことをまとめます。

LinuxでGit Credentialsを保存する4つの方法を比較

方法1:git-credential-store(ファイルにプレーンテキストで保存)

Gitに標準で組み込まれており、追加インストール不要です。コマンド一つで完了:

git config --global credential.helper store

Credentialsは~/.git-credentialsにプレーンテキスト形式で保存されます:

https://username:[email protected]

メリット:セットアップ不要、即座に動作、追加パッケージへの依存なし。

デメリット:トークンがプレーンテキストで保存されるため、ユーザー権限で実行されるどのプロセスからも読み取れます。マシンが侵害されると、トークンが完全に漏洩します。共有マシンや本番サーバーには不向きです。

方法2:git-credential-cache(RAMに一時保存)

# RAMにcredentialsを保存し、1時間(3600秒)でタイムアウト
git config --global credential.helper 'cache --timeout=3600'

メリット:Credentialsをディスクに書き込まないため、storeより安全。

デメリット:再起動すると失われ、再入力が必要です。Unixソケットがないシステム(一部のディストロの最小セットアップ)では動作しません。24時間365日稼働するサーバーでは毎時間再入力が必要で、実用的ではありません。

方法3:libsecret(GNOME Keyring / KWalletとの統合)

GNOMEが入っているUbuntuやFedoraでは、多くの人が見過ごしがちな優れた選択肢です。libsecretはSecret Service APIと直接通信し、credentialsはアプリではなくOSによって暗号化され、システムのキーリングに保存されます。

# libsecretをインストール
sudo apt install libsecret-1-0 libsecret-1-dev git

# git-credential-libsecretをビルド
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make

# 設定
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

メリット:CredentialsはOSによって暗号化され、GNOME/KDEとネイティブ統合、専用デーモン不要。

デメリット:デスクトップ環境(GNOME、KDE)がある場合のみ動作します。ヘッドレスサーバーでは、GNOME KeyringはD-BusセッションとGUI環境が必要なため起動できません。

方法4:Git Credential Manager(GCM)— クロスプラットフォーム

Microsoftがビルドしてオープンソースにしたツールです。GCMはOAuth2を完全に処理するため、手動でPATを作成する必要がなく、ブラウザで一度ログインするだけで完了します。GitHub、GitLab、Bitbucket、Azure DevOpsをすべてサポートします。Linuxでは、複数のバックエンドストレージに対応し、柔軟に使えます。

メリット:OAuth2の自動処理(手動PAT不要)、デスクトップとヘッドレスサーバーの両方で動作、複数のバックエンドストレージ対応、クロスプラットフォーム。

デメリット:.NETランタイムの追加インストールが必要で、バイナリが大きい(約100MB)。サービスが一つだけならやや過剰です。

分析:どの方法を選ぶべきか?

評価基準 store cache libsecret GCM
セキュリティ ❌ プレーンテキスト ✅ RAMのみ ✅ 暗号化 ✅ 暗号化
永続性
ヘッドレスサーバー ✅(secret-serviceまたはplaintext使用時)
デスクトップLinux
OAuth2の自動化
セットアップの難易度 非常に簡単 非常に簡単 普通 普通

私の実際の結論:

  • デスクトップLinux(Ubuntu、Fedora、Mint)libsecretを使用 — ネイティブ、軽量、安全、既存のキーリングとシームレスに統合。
  • ヘッドレスサーバー / VPSGPG暗号化プレーンテキストストアを使ったGCM、またはよりシンプルにSSHキー(credentialヘルパー不要)を使用。
  • 複数サービスを扱うチーム(GitHub + GitLab + Bitbucket):OAuth2自動処理のためにGCMを使用。

libsecretのセットアップ:Ubuntu/Debianデスクトップ編

ステップ1:インストール

sudo apt update
sudo apt install libsecret-1-0 libsecret-1-dev git make gcc

ステップ2:git-credential-libsecretのビルド

# ソースパスを確認(gitのバージョンによって異なる)
ls /usr/share/doc/git/contrib/credential/libsecret/

# ビルド
cd /usr/share/doc/git/contrib/credential/libsecret/
sudo make

# 確認
ls -la git-credential-libsecret

ステップ3:グローバル設定

git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret

# 設定を確認
cat ~/.gitconfig | grep credential

初回のgit pushでトークンの入力を求められます。入力後、libsecretがGNOME Keyringに保存します。以降は自動的に取得され、再入力不要です。

Git Credential Managerのセットアップ:ヘッドレスサーバー編

ステップ1:GCMのダウンロードとインストール

# 最新リリースはこちらで確認:https://github.com/git-ecosystem/git-credential-manager/releases
GCM_VERSION="2.5.1"
wget https://github.com/git-ecosystem/git-credential-manager/releases/download/v${GCM_VERSION}/gcm-linux_amd64.${GCM_VERSION}.deb

sudo dpkg -i gcm-linux_amd64.${GCM_VERSION}.deb

ステップ2:ストレージバックエンドの設定

ヘッドレスサーバーでは、GCMはGNOME Keyringを使用できません。2つの選択肢があります:

# オプションA:GPG暗号化ファイルを使用(推奨)
git-credential-manager configure
git config --global credential.credentialStore gpg

# GPGキーがなければ作成
gpg --gen-key

# オプションB:プレーンテキスト(GCM経由でgit-credential-storeと同等)
git config --global credential.credentialStore plaintext

ステップ3:GitHubでのテスト

# テスト用のプライベートリポジトリをクローン
git clone https://github.com/your-org/private-repo.git

# GCMはブラウザを開く(利用可能な場合)か、認証用URLを表示
# 初回認証後は、すべてのgit操作が自動化される

実際に経験したこと

以前、誤ったブランチへのforce pushで重要なコードを失ったことがあり、それ以来git push --forceには常に注意しています。しかしそのインシデントをきっかけに、ターミナルにトークンを無造作に貼り付けていることに気づきました。ターミナルの履歴にそのトークンが残る可能性を全く意識していなかったのです。

# これはやってはいけない — historyにトークンが残る!
git clone https://username:[email protected]/org/repo.git

# bash historyを確認
history | grep ghp_
# → インラインtokenではなくcredential helperが必要な理由はここにある

libsecretに移行してから、トークンはコマンドラインや履歴に表示されなくなりました。Gitがキーリングからトークンを内部的に取得するため、はるかにクリーンです。

ボーナス:複数のGitHubアカウントを同時に管理する

GitHubに個人アカウントと会社アカウントの両方がある場合、GCMはlibsecretよりもこのケースを上手く処理します:

# リポジトリごとの設定(グローバルをオーバーライド)
cd ~/work-project
git config credential.https://github.com.username work-username

# または複数キーのSSHを使う(私が好む方法)
# ~/.ssh/configに追加
Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

# エイリアスを使ってクローン
git clone git@github-personal:username/personal-repo.git
git clone git@github-work:org/work-repo.git

古いcredentialsのクリーンアップ

古いcredentialsを削除したり、最初から再入力するためにリセットしたりする場合 — 各メソッドに対応するコマンドは以下の通りです:

# 保存されたcredentialsを削除(libsecret)
git credential-libsecret erase
protocol=https
host=github.com
# Ctrl+Dを押す

# キャッシュをすべてクリア(git-credential-cache)
git credential-cache exit

# storeファイルを手動で削除
rm ~/.git-credentials

まとめ

デスクトップLinuxを使っているなら、まずlibsecretを試してください — 軽量で、ネイティブで、10分でセットアップ完了です。サーバー管理や複数のGitサービスを扱う必要がある場合は、GCMの初期セットアップ時間は十分価値があります。サーバーが一つのリポジトリへのpull/pushのみに使われているなら、SSHキーをデプロイしてcredentialヘルパーのことは忘れましょう — ほとんどの本番VPSで私が実際に使っている方法です。

Share: