Git認証情報について

参考: Git - 認証情報の保存

認証方法は大まかに以下の2種類に大別される。

  • SSH プロトコル
    • 秘密鍵、公開鍵を用いた認証を行う
    • パスフレーズなしの鍵生成(パスワード入力をスキップ)が可能
  • HTTP プロトコル
    • 接続のたびにユーザー名/パスワードを用いた認証を行う
    • 都度入力が必要となる(大変 → 後述の Credential Helper の活用)

どちらが使われるかは、リモートリポジトリのURLによって決定する

# HTTPSの場合
origin https://github.com/user/repo...

# SSHの場合
origin git@github.com:user/repo...

Git Credential-Helper

  • HTTPプロトコルにおける認証情報(ユーザー名・パスワード)のユーザーによる反復入力を省くために呼び出す外部プログラム

  • Git プロセスが、別で存在する credential helper のプログラムに対して get(取得), store(保存)、erase(削除)を行う

┌─────────────┐     get/store/erase      ┌──────────────────┐
│     Git     │ ◄──────────────────────► │ credential helper│
│             │    stdin/stdout          │  (外部プログラム) │
└─────────────┘                          └──────────────────┘

Git Credential Helper の種類

  • デフォルト

    • なにもキャッシュされない
    • 接続するたび、ユーザー名とパスワードを尋ねられる
  • Git に同梱されているもの

    • store
      • 認証情報がテキストファイルでディスクに保存される
      • 有効期限はない
      • (デメリット) パスワードが暗号化なしのテキストファイルでホームディレクトリに保存される
    • cache
      • 認証情報が一定の間だけメモリーに記憶される
      • パスワードはディスクには保存されない
      • 15分経つとメモリーから除去される
  • OS固有のもの

    • (MAC)osxkeychain
      • OS のキーチェーン(システムアカウントと紐づく)に認証情報がキャッシュされる
      • 認証情報がディスクに保存され、有効期限切れもない
      • 保存内容は暗号化(HTTPS 証明書や Safari の自動入力の暗号化と同じ仕組み)される
    • (Windows)wincred
      • 上記に似たもの
  • クロスプラットフォーム

    • manager

コマンド

credential helper の設定確認

# 現在の credential helper 設定を確認
git config --show-origin --get-all credential.helper

# システム/グローバル/ローカルの設定を個別に確認
git config --system --list | grep credential
git config --global --list | grep credential

credential helper の設定変更

// 追加
git config --global credential.helper cache

// 確認
git config --show-origin --get-all credential.helper
file:/Users/test-user/.gitconfig  cache

// 削除
git config --global --unset credential.helper cache

認証情報の取得

認証情報ヘルパーの仕組みを操作する基本となるコマンドは git credential

認証情報ヘルパーとしてどのプログラム(cache, osxkeychain, など)がどう呼び出されるか、はcredential.helperという設定によって制御される

例:

% git config --list | grep credential
credential.helper=osxkeychain

// 設定値: osxkeychain
// 挙動: git-credential-osxkeychain を実行する

つまり、Git Credential Helper の種類に記載の一連のヘルパーには、git-credential-cachegit-credential-store といった名前がつくということ

git credential fill

  • protocol, host を指定し、保存された認証情報があるか確認する
    • あれば内容を取得
    • なければ入力
// 存在する場合: 保存された内容が返ってくる
$ git credential fill
protocol=https 
host=mygithost
(空行を入力)

protocol=https 
host=mygithost
username=bob
password=s3cre7

// 存在しない場合: ユーザーがユーザー名とパスワードを入力する
$ git credential fill 
protocol=https
host=unknownhost

Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7

credential helper を指定し取得

osxkeychain の場合:

// 対話的に
git credential-osxkeychain get

// protocol, host をパイプで渡す
// 例: 
echo -e "protocol=https\nhost=mygithost\n" | git credential-osxkeychain get

CodeCommit 用に保存された内容を確認

// protocol: https

// host: git-codecommit.ap-northeast-1.amazonaws.com
//// 東京リージョンの CodeCommit ホスト

echo -e "protocol=https\nhost=git-codecommit.ap-northeast-1.amazonaws.com\n" | git credential fill

protocol=https
host=git-codecommit.ap-northeast-1.amazonaws.com
username=codecommit-git-credentials-user-at-<アカウントID>
password=...

設定方法

# 無効化(ヘルパーを使わない)
git config --global --unset credential.helper

# store モード(プレーンテキスト保存)
git config --global credential.helper store

# cache モード(メモリに一時保存、デフォルト15分)
git config --global credential.helper cache

# macOS キーチェーン
git config --global credential.helper osxkeychain

# Windows 資格情報マネージャー
git config --global credential.helper wincred

# Git Credential Manager
git config --global credential.helper manager

# AWS CodeCommit
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

以下の場所に保存される

  • Local: .git/config
  • Global: ~/.gitconfig

優先度

なんらかのcredential 設定が見つかった時点で、ユーザー名とパスワードの取得を試みる。 両方を取得すると、それ以降のヘルパーは試行されない

つまり、なんらかの問題でそのcredential.helperが問題のあるユーザー・パスワードを返却する場合、403エラー等で失敗し続けることになる。

なので、この場合は、優先度高めのLocal等の設定ファイルでヘルパーリストを空にリセットし、その後指定したいヘルパーを設定すると回避できる

参考: https://git-scm.com/docs/gitcredentials

If credential.helper is configured to the empty string, this resets the helper list to empty (so you may override a helper set by a lower-priority config file by configuring the empty-string helper, followed by whatever set of helpers you would like).
  • 例: codecommitのcredential.helperをLocalに設定しているのに、なぜかmacのosxkeychainが評価され403となる
  • 対応: 以下を実行
git config --local credential.helper ""
git config --local --add credential.helper '!aws codecommit credential-helper $@'