- GitHubにブラウザでログインしていても、ターミナルから使うGitHub CLIは別の入口として認証を求めます1。
人間の画面操作と、コマンドからの操作は分かれている。 - Tokenはパスワードそのものではなく、道具に渡すための権限付きの文字列です。
何をしてよいかをscopeで決めます。 - Fine-grained tokenとclassic tokenが並んでいるので迷いますが、今回の
gh auth loginではclassic tokenを使う流れになりました。 - コピーして貼るだけに見える操作の裏で、GitHubは「誰が、どの道具で、どこまで操作してよいか」を見ています。
1. GitHubにログインしていても、ターミナルは別の入口
最近、GitHubのリポジトリをLinux Mintのターミナルから扱おうとしていました。
ブラウザではGitHubにログイン済み。
リポジトリのページも見えています。
そこで、GitHub CLI(GitHub Command Line Interface:ギットハブ・コマンドライン・インターフェース)を入れました。
GitHubをブラウザではなく、コマンドで操作するための道具です2。
bash id="ezprer" sudo apt install gh gh repo clone chiilabo/chiineko-typing
ところが、gh repo cloneを実行すると、そこで止まりました。
GitHub CLIを使うには、まずgh auth loginを実行してください、と出ます。
「あれ、もうGitHubにはログインしているのでは」と思いました。
ここが少し引っかかるところです。
ブラウザでログインしているのは、人間がWeb画面を使うためのログインです。
一方、ターミナルでghコマンドを使うときは、GitHub CLIという別の道具がGitHubにアクセスします。
人間がクリックする入口。
コマンドがアクセスする入口。
同じGitHubでも、通る道が違う。
だから、ブラウザの右上に自分のアイコンが出ていても、ターミナルではまだ認証されていないことがあります。
ターミナル側から見ると、「あなたの代わりにこの道具が操作してよい、という証拠」が必要なのです。
2. Tokenはパスワードではなく、権限を持った文字列
gh auth loginを進めると、GitHub.comにログインするか、Gitの操作にはHTTPSを使うか、GitHubの認証情報を使うか、と聞かれました。
最後に出てきたのが、Tokenを貼り付ける画面。
ここで少し詰んだ気分になります。
GitHubの設定画面には、似た名前の項目がいくつも並んでいるからです。
Fine-grained personal access tokens。
Personal access tokens classic。
Authorized OAuth apps。
Authorized GitHub Apps。
SSH keys。
どれも「認証」っぽい。
どれも「許可」っぽい。
けれど、同じものではありません。
2.1. パスワードは人間の入口、Tokenは道具の入口
Personal Access Token(Personal Access Token:パーソナルアクセス トークン)は、個人アクセストークンと呼ばれます。
GitHubの機能を外部の道具から使うために発行する、長い文字列です3。
パスワードは、人間がログインするときの合言葉に近いものです。
それに対して、Tokenは道具に渡すための許可証に近い。
GitHub CLIは、GitHub API(Application Programming Interface:アプリケーション・プログラミング・インターフェース)を通じてGitHubとやり取りします。
APIは、ソフトウェア同士が機能を呼び出すための窓口です。
ブラウザの画面では、人間がボタンを押します。
CLIでは、コマンドがGitHubに「このリポジトリをcloneしたい」「この情報を読みたい」と頼みに行く。
そのときにTokenが使われます。
GitHubから見ると、「このTokenを持っている道具には、この範囲の操作を許可してよい」と判断できるわけです4。
パスワードをそのまま道具に渡すと、できることが広すぎます。
しかも、使い回すと取り返しがつきにくい。
Tokenなら、用途に合わせて作り、不要になったら消せます。
2.2. scopeは「どこまで触ってよいか」の指定
ターミナルには、必要なscopeとしてrepo、read:org、workflowが表示されていました。
スコープ(scope:スコープ)は、そのTokenにどの範囲の操作を許すかを指定するものです5。
repoはリポジトリへのアクセス、read:orgは所属組織の情報を読む権限、workflowはGitHub Actionsのワークフローに関係する権限です6。
細かい意味を全部覚えるよりも、「Tokenにできることの範囲を決めている」と見る方が、まずはわかりやすいと思います。
同じTokenでも、scopeが違えばできることが変わります。
リポジトリを読むだけのTokenと、設定を書き換えられるTokenでは、危なさが違う。
ここでTokenは、単なるログインの代わりではなくなります。
どの道具に、どこまで任せるのか。
その線引きを文字列にしたもの。
だから、Tokenを作る画面では権限のチェック欄が出てきます。
面倒ですが、ここが腕の見せ所でもあります。
全部にチェックを入れれば通りやすいかもしれませんが、道具に渡す権限が太りすぎます。
3. fine-grained と classic で迷うのは、Tokenが世代交代中だから
GitHubのCredentials画面には、Fine-grained personal access tokensとPersonal access tokens classicが並んでいました。どちらもpersonal access tokenです7。
そこがややこしい。
では、どちらを入れるのか。
今回のgh auth loginでは、画面に出ていた案内に合わせて、Personal access tokens classicを使うのが素直でした8。
Classicは古くからある形式です。
Fine-grainedは、より細かく制限できる形式。
名前だけ見るとFine-grainedの方が新しくて安全そうに見えます。
ただ、道具側がどちらを前提にしているかで、選び方は変わります。
今回のターミナルには、必要なscopeとしてrepo、read:org、workflowがそのまま表示されていました。
この表示はclassic tokenの権限指定と噛み合っています。
3.1. fine-grained は細かく制限できるToken
Fine-grained personal access tokenは、対象リポジトリや権限を細かく選べるTokenです。特定のリポジトリだけ、特定の操作だけ、という絞り方ができます9。
安全の考え方としては、とても自然です。
必要な場所だけに、必要な権限だけを渡す。
道具が触れる範囲を狭くできる。
ただ、細かく選べるぶん、設定も細かくなります。
どのリポジトリを選ぶのか。
どの権限が必要なのか。
どこまで許せばghが困らず動くのか。
ここを外すと、Tokenを貼ったのにコマンドが怒られます。
認証はできているのに、権限が足りない。
ログインできたのに、操作できない。
3.2. classic は古くからある広めのToken
Personal access tokens classicは、従来からあるTokenです。
scopeを選んで発行します。
今回の画面では、すでにclassic tokenが1つあることも見えていました。
ただし、既存のTokenの中身はあとから見られないことがあります。
Tokenは作成時に表示された文字列をコピーして使うものなので、保存していなければ新しく作り直すことになります。
この「一度しか見えない」という仕様も、最初は少し不親切に感じます。
でも、あとから誰かが設定画面を開いてTokenを盗み見できないようにしている、と考えると納得できます。
今回なら、新しくclassic tokenを作り、repo、read:org、workflowにチェックを入れる。
作成後に表示される長い文字列をコピーする。
ターミナルのPaste your authentication token:に貼り付ける。
やっていることは、ただのコピペです。
でも、そのコピペで「このパソコンのGitHub CLIに、指定した範囲の操作を許す」という関係が作られます。
4. コピーして貼るだけの裏側で、GitHubは誰が何をしてよいかを見ている
Tokenを貼り付けると、GitHub CLIはその認証情報を使ってGitHubにアクセスできるようになります。次にgh repo cloneを実行したとき、さっきのように止まらず進むはずです10。
ここで面白いのは、Tokenそのものが作業の主役ではないことです。
主役は、GitHub CLIがGitHubに「この操作をしたい」と頼みに行く流れです。
Tokenを作る。
Tokenにscopeを付ける。
TokenをCLIに渡す。
CLIがGitHubにアクセスする。
ブラウザでログインする感覚だけだと、ログインとは「自分が入ること」だと思っていました。
けれど、コマンドを使い始めると、ログインは「道具にどこまで任せるか」でもあります。
SSH key(Secure Shell key:セキュアシェル・キー)も似た場所に出てきます。
これは主にGitの通信で使われる鍵の仕組みです。Tokenと同じく認証に関わりますが、GitHub CLIの今回の入力欄に貼るものではありません11。
OAuth appやGitHub Appも、別のアプリにGitHubアカウントへのアクセスを許可する仕組みです12。
Credentials画面に並んでいるのは、GitHubが「どの道具に、どんな入口を開けているか」をまとめて見せているからです。
こうして見ると、GitHubの設定画面はただの管理画面ではなくなります。
過去に許可した道具、作ったToken、登録した鍵。
自分のアカウントに入る入口の一覧です。
コマンドが動くようになると、それだけでひとまず安心します。
けれど、そこで終わらずに「今、どの権限を、どの道具に渡したのか」と見ておくと、ターミナルの作業が少し違って見えます。
ただの長い文字列だと思っていたTokenが、GitHubと手元の道具の間にある約束に見えてくる。
新しいコマンドを覚えるより、その見え方が変わる瞬間の方が、あとで効いてくると思います。
- GitHub公式ドキュメントでは、コマンドラインからGitHubへ接続する方法としてHTTPSとSSHが説明されています。GitHub CLIでHTTPSを使う場合は、personal access tokenまたはブラウザ経由で認証できます。 – About authentication to GitHub – GitHub Docs
- GitHub公式ドキュメントでは、GitHub CLIは
ghとして提供され、GitHubをコマンドラインから操作する道具だと説明されています。gitはローカルやリモートのGitリポジトリを扱う道具で、ghとは担当が違います。 – GitHub CLI について – GitHub Docs - GitHub公式ドキュメントでは、personal access tokenはGitHub APIやコマンドラインでパスワードの代わりに使うものと説明されています。 – Managing your personal access tokens – GitHub Docs
- GitHub公式ドキュメントでは、Tokenは作成したユーザーが持つ権限の範囲で動き、さらにTokenに付与されたscopeやpermissionで制限されると説明されています。 – Managing your personal access tokens – GitHub Docs
- GitHub公式ドキュメントでは、scopeはOAuth tokenが必要とするアクセスの種類を指定するもので、ユーザー本人が持っていない権限を追加するものではないと説明されています。 – Scopes for OAuth apps – GitHub Docs
- GitHub公式ドキュメントでは、
repoは公開・非公開リポジトリへの広いアクセス、read:orgは組織メンバーシップなどの読み取り、workflowはGitHub Actionsのワークフローファイルの追加・更新に関するscopeとして説明されています。 – Scopes for OAuth apps – GitHub Docs - GitHub公式ドキュメントでは、personal access tokenにはfine-grained personal access tokenとpersonal access token classicの2種類があると説明されています。 – Managing your personal access tokens – GitHub Docs
- GitHub CLIの公式マニュアルでは、
--with-tokenでpersonal access token classicを標準入力から渡す方法が示されています。また、fine-grained personal access tokenは対象リソースの絞り込みによって挙動が分かりにくくなる場合があるため、GH_TOKENの利用が案内されています。 – gh auth login – GitHub CLI - GitHub公式ドキュメントでは、fine-grained personal access tokenは所有者、対象リポジトリ、権限を細かく制限できる一方で、classic tokenができるすべての作業を置き換えられるわけではないと説明されています。 – Managing your personal access tokens – GitHub Docs
- GitHub公式ドキュメントでは、GitHub CLIでHTTPSを選び、GitHub認証情報をGitにも使うと答えると、GitHub CLIがGit資格情報を保存すると説明されています。 – Caching your GitHub credentials in Git – GitHub Docs
- GitHub公式ドキュメントでは、SSH keyを使うと、毎回ユーザー名やpersonal access tokenを入力しなくてもGitHubに接続できると説明されています。 – About SSH – GitHub Docs
- GitHub公式ドキュメントでは、GitHub AppsはOAuth appsよりも細かい権限、対象リポジトリの制御、短命のTokenを使えるため、アプリの認証情報が漏れた場合の影響を抑えやすいと説明されています。 – GitHub Apps overview – GitHub Docs