GitHub Organizationに作成したプライベートリポジトリにSSHでアクセスできなくて悩んでいたのである。HTTPS(2FAあり)ではcloneできるけど、SSHではcloneできない。Could not read from remote repositoryとなる。
問題を切り分けるために、GitHubの自分のアカウントにてプライベートリポジトリを作成してみたのだが、やはりSSHではcloneできない。HTTPSではcloneできる。Organization固有の問題では無いようだ。
ついでにパブリックリポジトリならSSHでもcloneできる。という訳で、GitHubへの公開鍵の登録や、Gitクライアントでの秘密鍵の利用についても、特段の問題は無いはず。
ところで私の環境ではGitクライアントとしてGit for Windowsを使用していて、PuTTY付属のPlinkでSSH通信を行い、Pageantを利用して複数の鍵を管理しているのだが、PageantにGitHubアクセス用の秘密鍵1つだけを登録した状態ならSSHでプライベートリポジトリをcloneできるのだ。しかし複数の秘密鍵が登録されている状態では、プライベートリポジトリだけcloneできなくなる。
さらに条件を絞り込んだところ、PageantにGitHubアクセス用の秘密鍵が複数登録されている時に発生することが分かった。GitHubのアカウントA用の秘密鍵とアカウントB用の秘密鍵が登録されている、みたいな状況だ。GitHubのアカウントA用の秘密鍵と、GitHubではないホスト用の秘密鍵、みたいな組み合わせでは発生しない。
PuTTYないし付属のツール群でSSHで通信する際、Pageantに複数の秘密鍵が登録されている場合には、SSH接続時に何らかの順番で秘密鍵を試してみて、成功したらその鍵で通信する、ということを行っている。
おそらく、例えばアカウントBのプライベートリポジトリにアクセスしようとした際に、「アカウントA → アカウントB」の順に秘密鍵を試す、みたいな現象が起きているのだろう。どちらの秘密鍵もGitHubに登録された正規のものなので、アカウントAの秘密鍵の時点でSSHでの通信は確立する。しかしGitHub側の設定では、アカウントAはアカウントBのプライベートリポジトリへのアクセス権限を持たない。だからGitHubのアクセス制限でNGとなってしまう。cloneの失敗は接続後の出来事で、SSH接続自体は成功しているために、残りの鍵で接続が試行されることはない。
症状から考えるに、LinuxやmacOSなどで素のOpenSSHを使っている環境ならば、.ssh/config
を使って秘密鍵を切り替えてアクセスできるようにする案件だと思われる。IdentitiesOnly yes
を忘れると妙なことになるアレである。
問題は、それをGit for Windows + Plink + Pageantの環境でどう実現するか、なのだが……。PlinkやPageantの設定でどうにかなるのか、それともPlinkを捨ててOpenSSHに移行するのか? 仮にOpenSSHに切り替えるとして、Git for Windowsではどのバイナリが良いのか(同梱のものもあれば、Windows付属のものもあるし……)? またOpenSSHへの移行に際してPageantからssh-agent(1)への切り替えも必要となるのか? 色々と悩ましい。