Git 認証情報の保存について (Git Credential Manager for Mac and Linux)

---

GNOME Keyring や OAuth 2.0 Device Flow の実装、`eraseosxkeychain = true` をデフォルト設定にした `git-credential-manager-2.0.3` がリリース

* [git-credential-manager-2.0.3](https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/releases/tag/git-credential-manager-2.0.3) (2016/10/12)

---

Git で認証したあとに、しばらくたっても認証求められないなぁと思って調べてみた。
Mac OS X 使ってるなら、git osxkeychain を使って OS X のキーチェーンアクセスと連携すれ3ばいいだけなんじゃね？

* [7.14 Git のさまざまなツール - 認証情報の保存](https://git-scm.com/book/ja/v2/Git-のさまざまなツール-認証情報の保存)

>Mac を使っているなら、Git の “osxkeychain” モードが使えます。これを使うと、OS のキーチェーン（システムアカウントと紐づく）に認証情報がキャッシュされます。
>このモードでも認証情報がディスクに保存され、有効期限切れもありません。ただし先ほどとは違い、保存内容は暗号化（HTTPS 証明書や Safari の自動入力の暗号化と同じ仕組み）されます。

osxkeychain をそのまま使えばいいのかな？って思ってたけど、Visual Studio Team Service (以下 VTST) の Git リポジトリを利用する場合は、Git Credential Manager (以下 GCM) を使うと少し便利っぽい。

なので、[無制限の無償プライベート Git リポジトリ](https://www.visualstudio.com/version-control-vs)としてお世話になっているので、少し調べてみた。

GitHub でも使えるみたいな感じになってるけど・・・

## Git Credential Manager

Java FX で書かれた Credential 管理ツール。
Windows 版と Mac/Linux 版の実装があり、両者は異なるみたい。
Azure Active Directory を利用した multi-factor authentication with Visual Studio Team Services や GitHub での two-factor authentication をサポートし、VTST の Git アクセスを Alternate authentication credentials ではなく Microsoft Account で行うことができる。

* [Git Credential Manager for Mac and Linux](https://blogs.msdn.microsoft.com/visualstudioalm/2015/11/18/git-credential-manager-for-mac-and-linux/)
* [Announcing the Git Credential Manager for Windows 1.0](https://blogs.msdn.microsoft.com/visualstudioalm/2015/12/08/announcing-the-git-credential-manager-for-windows-1-0/)
* [Use Git Credential Managers to Authenticate to Visual Studio Team Services](https://www.visualstudio.com/en-us/get-started/code/set-up-credential-managers)
  * [Git Credential Manager](https://java.visualstudio.com/Downloads/gitcredentialmanager/Index)
* [GCM documentation on the VSTS Java site](https://blogs.msdn.microsoft.com/visualstudioalm/2015/11/18/git-credential-manager-for-mac-and-linux/)

GCM は、git credential helper となり OAuth 2.0 を使ってアクセスし、vso.code_write 権限(VSTS 上の Git リポジトリへの read/write 許可)を持った VTST Personal Access Token (PAT) を動的に作成してくれる。

![スクリーンショット 2016-04-09 8.06.47.png](https://qiita-image-store.s3.amazonaws.com/0/65800/6f647589-83d4-1f7a-92b6-e8ae610ecb2b.png "スクリーンショット 2016-04-09 8.06.47.png")


GCM で認証すると VTST 側に Personal Access Token を自動的に作成してくれる。

ぼっち利用だとあまり恩恵がないようなきがするけど、Azure Active Directory とか使ってチームでの利用なら恩恵あるんじゃないかな？
もちろん使わなくても大丈夫です。

あと、Alternate authentication credentials ではなく Microsoft Account でアクセスできるのも良いのかもしれない。


### ダウンロード

---

- https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/releases/

### 必要なもの

---

Java FX が必要なのでJDK が必要

    * Mac OS X 10.9.5 - 10.10: Oracle Java 7 Update 6 以降
    * Mac OS X 10.11 or later: Oracle Java 8

~/.gitconfig に `helper = osxkeychain` が無いことを確認しておく。あれば削除でいいのかな？ 

```bash
[credential]
        helper = osxkeychain
```

### インストール

---

ファイルをダウンロードしてマニュアルインストールです。Homebrew からもインストールできるのでお好きなほうで。

インストールの詳細については、下記も参考に。

* [Installation Instructions](https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/blob/master/Install.md)

ダウンロードした `git-credential-manager-1.6.0.jar` を ~/git-credential-manager/ ディレクトリ(なければ作成)に配置。

```bash
 $ mkdir ~/git-credential-manager
 $ cd ~/git-credential-manager/

 $ curl -L -O https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/releases/download/git-credential-manager-2.0.3/git-credential-manager-2.0.3.jar

 $ java -jar ~/git-credential-manager/git-credential-manager-2.0.3.jar install
```

インストールはこれで完了

### **設定**

---

インストールを完了させたら、~/.gitconfig を見てみる。

~/.gitconfig に `[credential]` が追加され、helper に設定された `git-credential-manager-2.0.3.jar` が呼ばれるんじゃないかなーとかいうのがなんとなくわかる。

、`git config --global credential.eraseosxkeychain true` を実行する。

また、git (Apple Git) では osxkeychain が強制的に利用されるので、cridential 情報がメモリ中に残り再利用されてしまう。
そのため、GCM の効果が抑制されてしまい、これを回避するために OS X Keychain から提供される credential 情報を削除してから GCM を呼び出す Workaround が提供されていたが、2.0.0 ではこの対策がデフォルトで有効になっている。

ここまでの作業で ~/.gitconfig に下記の `[credential]` が追加されることになる。

```bash
$ cat ~/.gitconfig
[credential]
    helper = !/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/bin/java -Ddebug=false -Djava.net.useSystemProxies=true -jar /Users/satokaz/git-credential-manager/git-credential-manager-2.0.3.jar
```

ちなみに、いくつか使い方があるようなので、晒しておきます。

```bash
$  java -Ddebug=false -Djava.net.useSystemProxies=true -jar ~/git-credential-manager/git-credential-manager-2.0.3.jar
usage: git credential <command> [<args>]

   authority          Defines the type of authentication to be used.
                      Supports Auto, Basic, AAD, MSA, and Integrated.
                      Default is Auto.

      `git config --global credential.microsoft.visualstudio.com.authority AAD`

   eraseosxkeychain   Enables a workaround when running on Mac OS X
                      and using a version of Git which includes the osxkeychain
                      credential helper, hardcoded before all other helpers).
                      The problem is osxkeychain may return expired or
                      revoked credentials, aborting the Git operation.
                      The workaround is to preemptively erase from osxkeychain
                      any Git credentials that can be refreshed or re-acquired
                      by this credential helper.
                      Defaults to TRUE. Ignored by Basic authority.
                      Does nothing if osxkeychain on Mac OS X isn't detected.

      `git config --global credential.microsoft.visualstudio.com.eraseosxkeychain false`

   interactive        Specifies if user can be prompted for credentials or not.
                      Supports Auto, Always, or Never. Defaults to Auto.
                      Only used by AAD and MSA authority.

      `git config --global credential.microsoft.visualstudio.com.interactive never`

   validate           Causes validation of credentials before supplying them
                      to Git. Invalid credentials get a refresh attempt
                      before failing. Incurs some minor overhead.
                      Defaults to TRUE. Ignored by Basic authority.

      `git config --global credential.microsoft.visualstudio.com.validate false`

   writelog           Enables trace logging of all activities. Logs are written to
                      the .git/ folder at the root of the repository.
                      Defaults to FALSE.

      `git config --global credential.writelog true`

Sample Configuration:
   [credential "microsoft.visualstudio.com"]
       authority = AAD
   [credential "visualstudio.com"]
       authority = MSA
   [credential]
       helper = manager
```

### **GCM を発動させてみる**

---

VTST 上に作成した Git リポジトリへ git コマンドでアクセスしてみる。
たとえば、git clone とか。

実行すると、Microsoft アカウントを要求するウィンドウが表示されるので VTST を利用する Microsoft アカウントでサインインすれば git でのアクセスができるようになる。

以降は、特に認証を再要求されることなく利用できるようになるが、VTST 上に作成された Personal Access Token には期限が設定されているので、これが expire されれば再認証が発生するのかな？

![スクリーンショット 2016-04-05 15.34.13.png](https://qiita-image-store.s3.amazonaws.com/0/65800/893e9f7a-64a7-607b-2aa0-b999d9144703.png "スクリーンショット 2016-04-05 15.34.13.png")

### **VSTS の Git リポジトリでの利用**

---

keychain で見ると、下記のような情報が登録される。

アカウントは Miscrosoft アカウントではなく、Personal Access Token となりパスワードには Token が入る。

![スクリーンショット 2016-04-09 18.31.02.png](https://qiita-image-store.s3.amazonaws.com/0/65800/4d5a1f55-0d3d-cb9c-6c63-60b051bd8896.png "スクリーンショット 2016-04-09 18.31.02.png")

Visual Studio Code とは、ほぼ関係ないのだけど、Visual Studio Code も Git 使っているし、デフォルトはずっと git fetch してるので、GCM が設定されると、いきなりサインインのウィンドウが開いたりする。

![スクリーンショット 2016-04-09 18.30.24.png](https://qiita-image-store.s3.amazonaws.com/0/65800/47cffaf2-ed91-943c-f44f-50fc9f40fa51.png "スクリーンショット 2016-04-09 18.30.24.png")



### **VSTS 以外の Git リポジトリでの利用**

---

VTST 用というか Microsoft べったりツールのような印象になってしまっているが、その他の Git サービスでも利用可能。
ただ、挙動としては VTST 利用時のようなサインインの画面などはなく、通常の Git アクセス時の認証と同じ挙動になる。
なので、感覚的には `git-credential-osxkeychain` を使っているのと変わらない感じ。

GCM 経由で keychain に store される情報については、`gcm4ml` という prefix がついたエントリになる。
GitHub 含む VTST 以外の Git リポジトリへの接続については、git-credential-store と同じような挙動で username と password を store しての利用となる。

インターネットパスワードも登録され、こちらは `git-credential-osxkeychain` からのアクセスが許可されているので、実はここっちを使っているんじゃないか疑惑もあったりするけど、まぁいっか。


![スクリーンショット 2016-04-09 15.30.22.png](https://qiita-image-store.s3.amazonaws.com/0/65800/11eac17e-7312-5f4a-fa94-9f92fc44d9f9.png "スクリーンショット 2016-04-09 15.30.22.png")


### **Proxy が必要な環境での利用**

---

GCM を使う場合は、Proxy に気をつけて。
git の中から Java program を呼び出すので、git と Java それぞれが proxy を経由してアクセスできないと詰む。

こんな Operation timed out が出る。

```bash
$ git clone http://satokaz.visualstudio.com/DefaultCollection/testrepo2
Cloning into 'testrepo2'...
Fatal: java.lang.Error encountered.  Details:
java.net.ConnectException: Operation timed out
fatal: credential helper '!/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/bin/java -Ddebug=false -Djava.net.useSystemProxies=true -jar /Users/satokaz/test/git-credential-manager-1.6.0.jar' told us to quit
```

一応、[Add support for Git's http.proxy configuration #30](https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/issues/30) として Issue が上がっているが、なんかゆっくり気味。

GCM の Proxy 設定は、[How to configure the proxy server](https://github.com/Microsoft/Git-Credential-Manager-for-Mac-and-Linux/blob/master/Install.md#how-to-configure-the-proxy-server) を参考に。


## **まとめ**

VTST を使っていて、Azure Active Directory とかで multi-factor authentication with Visual Studio Team Services やりたいとかだと良いと思う。
git-credential-osxkeychain でもいいと思う。。。

Azure も使っていないし、Azure Active Directory も使ってないけど、VTST を使っているので Alternate authentication credentials を使わなくても良くなるのが一番よいかな。

![スクリーンショット 2016-04-09 19.11.33.png](https://qiita-image-store.s3.amazonaws.com/0/65800/04008f97-9338-4339-3c62-53588d6b1bbb.png "スクリーンショット 2016-04-09 19.11.33.png")

ただ、Alternate authentication credentials を切ると GCM を使えないクライアントからはアクセスできなくなるわけで・・・
Solaris とか Solaris とか Solaris から git アクセスできない。(おまけ参照

## credential 管理の参考情報

* [Caching your GitHub password in Git](https://help.github.com/articles/caching-your-github-password-in-git/)
* [Updating credentials from the OSX Keychain](https://help.github.com/articles/updating-credentials-from-the-osx-keychain/)

## おまけ

Git Credential Manager は、JavaFX を使ってる。

なので、Solaris では動かない。くそっくそっ

```bash
$ java -jar git-credential-manager-1.6.0.jar install
Installation failed due to the following unmet requirements:
The JavaFx user agent provider has the following unmet requirements:
 - JavaFX or OpenJFX runtime JAR.
 - A desktop environment.
The Git Credential Manager for Mac and Linux is only supported on, well, Mac OS X and Linux. The operating system detected is SunOS, which is not supported.

If you think we are excluding many users with one or more of these requirements, please let us know.
```