gh は通常、PAT (Personal Access Token) をリクエストとともに送信します。 GitHub APIの一部のエンドポイントは、認証なしでアクセスできます。 しかし、APIを頻繁に利用するようになると、レート制限の問題を防ぎ、可能な限りのエンドポイントにアクセスするために PAT が必要になります。
この記事では、PAT を保存して gh が (ほとんどの場合、自動的に) それを見つけられるようにする方法について説明します。ghがこのために使用する関数は、gh_token()
です。
PATの管理に関するその他のリソース
usethis::gh_token_help()
と usethis::git_sitrep()
は、以下のことを確認するのに役立ちます。 PATが発見可能であるかどうか,適切なスコープを持っているかどうかを調べることができます.usethis::create_github_token()
は、PATが発見可能かどうか、適切なスコープを持っているかどうかを調べるのに役立ちます。 新しいPATgitcreds::gitcreds_set()
は、PAT を Git の credential ストアに明示的に入れるためのものです。 クレデンシャルストアgh::gh()では、
.tokenという引数で PAT を指定したり、
.api_url` という引数で “github.com” 以外のホストを指定することができます。 (企業や大学によっては、独自にGitHub Enterpriseのインスタンスを運用しているところもあります。)
しかし、常にPATやホストを提供するのは煩わしいですし、PATがRコードに明示的に表示されるのは安全ではありません。 ユーザーがPATやAPIのURLを直接指定できるようにすることは重要ですが、それが必要になることはほとんどないはずです。 gh::gh()
は、より安全で、より面倒でない方法で目的のものを表現できるように設計されています。
ユーザーが .api_url
と .token
を提供しなかった場合、どのようにしてそれらを決定するのですか?
.api_url
のデフォルトは環境変数 GITHUB_API_URL
の値です。 環境変数の値をデフォルトとし、それが設定されていない場合は、"https://api.github.com"
にフォールバックします。 これはPATを気にする前に常に行われます。gh_token(.api_url)
の呼び出しによって得られます。つまり、トークン はホストに基づいて検索されます。gh は gitcreds パッケージを使って Git のクレデンシャルストアと連携するようになりました。
gh は URL を指定して gitcreds::gitcreds_get()
を呼び出し、一致する PAT を探そうとします。 gitcreds::gitcreds_get()は、セッションの環境変数をチェックし、次にローカルのGitクレデンシャル・ストアをチェックします。 そのため、コマンドラインのGitなどで以前にPATを使用したことがある場合には、ghがそのPATを取得して再利用することができます。 特定の URL に対して何が見つかったかを確認したい場合には、自分で直接
gitcreds::gitcreds_get()` を呼び出すことができます。
If you see something like this:
#> <gitcreds>
#> protocol: https
#> host : github.com
#> username: PersonalAccessToken
#> password: <-- hidden -->
ということは、gitcreds は Git のクレデンシャルストアから PAT を取得できるということです。 実際のPATを見るには、gitcreds_get()$password
を呼び出します。
一致するPATが見つからない場合は、gitcreds::gitcreds_get()
のエラーになります。
Gitをインストールしていない場合や、Gitをインストールしてもクレデンシャルストアが動作しない場合は、PATを環境変数で指定することができます。 github.com」の場合は、「GITHUB_PAT_GITHUB_COM」または「GITHUB_PAT」という変数を設定します。 GitHub のホストが異なる場合は、API の URL を指定して gitcreds::gitcreds_cache_envvar()
をコールすると、設定する必要のある環境変数がわかります。 たとえば、以下のようになります。:
インタラクティブな開発に使用するマシンでは、以下を推奨します。
あなたのPATを公式の credential ストアに保存してください。
PAT(s)をプレーンテキストで .Renviron
などに保存してはいけません**。 これまでは、実用的な理由からこの方法が一般的で推奨されていました。 しかし、gitcreds/gh が進化した現在では、私たち全員がよりよいセキュリティ対策をとることができるようになりました。
1Password や LastPass のような汎用的なパスワードマネージャを使っている場合は、 PAT もそこに保存したいと思うかもしれません。 なぜでしょうか?意図的であろうとなかろうと、OSレベルの credential ストアからPATが「忘れられた」場合には、 プロンプトが表示されたときに再度PATを提供する必要があります。
他にPATの記録がない場合は、このようなことが起こるたびに新しいPATを取得しなければなりません。 これは、世界の終わりではありません。 しかし、https://github.com/settings/tokensから失われたPATを削除するようにしないと、 どのPATが使用されているのかわからないという混乱した状況に陥ることになります。
CI/CDプラットフォームのようなヘッドレスシステムでは、セキュアな環境変数を介して必要なPATを提供します。 通常の環境変数は、APIホストのような機密性の低い設定に使用できます。 すべての環境変数をログファイルにダンプするような愚かなことをして、PATを公開してはいけません。
なお、GitHub Actionsでは、個人のアクセストークンがGITHUB_TOKEN
というシークレットとしてワークフローで自動的に利用可能になっています。 これが、Rコミュニティの多くのワークフローにこのスニペットが含まれている理由です。:
これにより、自動PATが環境変数GITHUB_PAT
として利用できるようになります。 そのPATが適切なパーミッションを持っていない場合は、パーミッションを持つPATを明示的に用意する必要があります(詳細は上記リンクを参照)。
必要なPATがない場合、gh::gh()
はトークンのないリクエストを送信します。 (内部的には、PAT が空文字列 ""
であることが判明した場合には Authorization
ヘッダが省略されます)
PAT関連の失敗はどのようなものか?
PATが送信されず、エンドポイントが認証を必要としない場合、リクエストはおそらく成功します。 少なくとも、レートの制限にぶつかるまでは。 エンドポイントが認証を必要とする場合は、HTTPエラーが発生します。:
GitHub API error (401): 401 Unauthorized
Message: Requires authentication
環境変数の中にPATが最初に発見された場合、それは額面通りに受け取られます。 ここで最も一般的な方法は、.Renviron
によるPATの指定と、GitHub ActionsのようなCI/CDプラットフォームのシークレットとしてのPATです。 PATが無効な場合、影響を受ける最初のリクエストはおそらく次のように失敗します。:
GitHub API error (401): 401 Unauthorized
Message: Bad credentials
これは、無効なPATが .token
を介して直接提供された場合にも起こります。
有効なPATであっても、特定のリクエストに対するスコープが不十分であれば、下流工程でエラーになる可能性があります。