
有効期限なしだったGitHub CLIのトークンが、数時間で失効して自動更新される方式を選べるようになりました
どうも!オペ部の西村祐二です!
GitHub CLI(gh)に gh auth login でログインすると、これまでは有効期限のないOAuthトークンが保存されていました。手軽な反面、漏れたトークンは手動で取り消すまで使えてしまいます。
2026年10月21日(米国時間)公開のGitHub CLI 2.103.0で、新しい認証方式がPublic Previewとして加わりました。数時間で失効するアクセストークンを、gh が自動で更新する仕組みです。この記事では、有効にする方法を紹介したうえで、gh auth token を使うスクリプト、環境変数で渡すトークン、HTTPSのgit操作、gh auth refresh への影響を整理します。
手元で確かめたのは、macOS(arm64)上のGitHub CLI 2.103.1の公式バイナリでのヘルプ表示、設定の読み書き、ログイン開始時の表示までです。デバイスフローの認可までは進めていないため、期限付きトークンでのログイン後の挙動と自動更新は試していません。ログイン後の挙動は、リリースノート、GitHub Docs、PR、v2.103.1のソースコードに基づいて書いています。
数時間で失効し、gh が自動更新するトークン
期限付きトークンを選ぶと、gh は短命のアクセストークンと、交換のたびに入れ替わるリフレッシュトークンをセットで保存します。アクセストークンが必要になったとき、期限切れや期限間近であれば gh がリフレッシュトークンを使って新しいアクセストークンを取得します。利用者が再ログインする必要はありません。
GitHub Docsは、トークンが漏れても数時間で使えなくなる点を利点として挙げています。
主な仕様は次の通りです。
| 項目 | 内容 |
|---|---|
| 必要なバージョン | GitHub CLI 2.103.0以降(2026年10月24日時点の最新は2.103.2) |
| 提供状態 | Public Preview(GitHub Changelog) |
| 対応ホスト | github.com、GHE.com(データ所在地を選べるGitHub Enterprise Cloud)。GitHub Enterprise Serverは3.23以降 |
| 未対応ホストの場合 | 通常の非期限トークンが発行される |
| 既定の動作 | 無効(オプトイン)。既存のログインや手動で渡したトークンは変わらない |
トークンの有効期間について、GitHub CLIのドキュメントは「数時間」とだけ書いています。OAuth Appにおける期限付きアクセストークンの仕様では、アクセストークンは8時間、リフレッシュトークンは未使用のまま6か月で失効するとされています。gh のトークンにも同じ期間が適用されるかは、CLIのドキュメントには書かれておらず、今回は確認していません。
GitHub Changelog(2026年10月21日)には、将来のリリースで新規ログインの既定を期限付きにする予定だとも書かれています(時期は未定)。
gh と git・スクリプトのトークンの流れ
次の図は自作した概念図で、公式の構成図ではありません。gh はGitHubからアクセストークンとリフレッシュトークンを取得し、資格情報ストアに保存します。gh のコマンド、git(gh を資格情報ヘルパーにした場合)、gh auth token を呼ぶスクリプトは、いずれも gh を通してトークンを受け取ります。期限が近いときは、受け渡しの前に gh が新しいトークンへ交換します。

gh 以外の場所にトークンの値を保存すると、この更新の流れから外れます。後述する注意点の多くは、この点に由来します。
--expiring と expiring_credentials で有効にする
GitHub CLI 2.103.0以降が必要なので、先にバージョンを確認しておきます。スクリプトや拡張機能を使っている場合は、後述の「切り替える前に確認したいこと」を先に読むと、失効後に止まるスクリプトを切り替え前に洗い出せます。
gh --version
1回のログインだけで使う場合は --expiring を付けます。
gh auth login --expiring
以後のログインで毎回使う場合は、expiring_credentials 設定を有効にします。
gh config set expiring_credentials enabled
GH_CONFIG_DIR で設定の置き場所を普段とは別の空のディレクトリに向け、GitHub CLI 2.103.1の公式バイナリで expiring_credentials の挙動を確かめました。既定値は disabled で、enabled / disabled 以外の値は受け付けません。有効にするコマンドは、成功時には何も表示しません。
$ gh config get expiring_credentials
disabled
$ gh config set expiring_credentials yes
failed to set "expiring_credentials" to "yes": valid values are 'enabled', 'disabled'
$ gh config set expiring_credentials enabled
$ gh config get expiring_credentials
enabled
設定を有効にした状態で、特定のログインだけ非期限トークンにしたい場合は --expiring=false を付けます。gh auth login --help によれば、明示したフラグが設定より優先されます。
--expiring は「期限付きを希望する」指定で、発行を保証するものではありません。ヘルプには、対応ホストはフラグなしでも期限付きトークンを発行しうるとも書かれています。
ログイン開始時の表示も、端末に接続しない(非TTYの)状態で実行して確かめました。--expiring の有無で、ワンタイムコードの表示と認可ページ(https://github.com/login/device)は変わりませんでした。
$ gh auth login --web --expiring -h github.com -p https
! One-time code (XXXX-XXXX) copied to clipboard
Open this URL to continue in your web browser: https://github.com/login/device
なお、2.103.1では、--expiring を付けず設定も有効にしていない、github.com などへの対話的なログインで、期限付きトークンを案内する1行のヒントが表示されるようになりました(PR #14798)。PRによれば、stderrの出力先が端末のときだけ表示されるため、上の非TTYでの実行では表示されていません。
期限と更新の状態を確認する
gh auth status で、トークンが自動更新の対象かどうかと、アクセストークンの期限を確認できます。v2.103.1のstatus.goを見ると、期限付きトークンの場合は次のような行を出力する実装になっています。
- Expiring token that gh refreshes automatically
- Token expires: <日時> (<残り時間>)
- Refresh token expires: <日時> (<残り時間>)
gh auth status と gh auth token は、期限切れや期限間近のトークンを自動で更新してから結果を返します。更新させずに今の状態だけを見たい場合は、どちらも --no-refresh を付けます。
同じソースによれば、リフレッシュトークン自体が拒否されると、保存していた期限付きの資格情報は削除され、gh auth status では gh auth login -h <ホスト> での再ログインが案内されます。
切り替える前に確認したいこと
gh auth token の値を保存しているスクリプト
影響が大きいのは、gh auth token の出力を変数やファイルに保存して使い回すスクリプトや拡張機能です。保存した値は数時間で失効するため、リリースノートでは、トークンが必要になるたびに gh auth token を実行し直すよう案内しています。GitHub Changelogも、トークンが長く有効であることを前提にしたワークフローがある場合は、まだオプトインしないよう勧めています。
# 期限付きトークンでは、使う直前に毎回取得する
curl -H "Authorization: Bearer $(gh auth token)" https://api.github.com/user
環境変数で渡したトークンは更新されない
リリースノートによれば、GitHub Actionsのように GH_TOKEN や GITHUB_TOKEN で渡したトークンは、gh が更新しません。
HTTPSのgitは gh を資格情報ヘルパーにする
HTTPSでgitを使う場合は、gh をgitの資格情報ヘルパーにしておくと、gh が期限付きトークンを更新して渡します。
gh auth setup-git
GitHub Docsによれば、期限付きトークンでログインしたとき、gh がヘルパーになっていなければ設定するかを尋ねます。
別の資格情報ヘルパーをすでに使っている場合の扱いは、v2.103.1のgit_credential.goで確認しました。そのヘルパーは期限付きトークンを更新できず、期限切れのトークンを渡し続けてしまうため、gh は自身をヘルパーにするよう求めます。--expiring や設定で期限付きを希望したログインでは、「gh をヘルパーにする(推奨)」「設定せずに続ける」「ログインを中止する」の3択が表示されます。gh を選ぶと、別のヘルパーがあっても gh がそのホストのヘルパーとして設定されます。
希望していないのに期限付きトークンが発行された場合は、代わりに gh をヘルパーにするかを確認されます。断ると、gh はトークンを既存のヘルパーへ保存しません。ヘルパーに保存済みの、そのホストの資格情報を削除し、gh auth setup-git --hostname <ホスト> の実行を案内する警告を出します。
gh auth login --help では、あわせてgit 2.46以降が推奨されています。gitが2.46以降なら、gh はgitに渡すトークンに「キャッシュしない」印(ephemeral)を付けます。これにより、git-credential-cache のようなキャッシュ用ヘルパーが期限切れのトークンを保持しなくなります。v2.103.1のhelper.goでは、gitが古い場合、gh はトークンを渡したうえで、gitの更新を勧める警告をstderrに出す実装になっています。
gh auth refresh でスコープを変えるとき
gh auth refresh --scopes でスコープを追加するときの扱いは、ドキュメントとCLIのヘルプで説明が分かれています。
- GitHub Docs: 期限付きトークンを使っている場合は
--expiringを付けるか設定を有効にする。付けないと非期限トークンに置き換わることがある gh auth refresh --help(2.103.0 / 2.103.1): フラグを付けなければ、現在のトークンの種類(期限付きか非期限か)を引き継ぐ
v2.103.1のrefresh.goもヘルプと同じく、フラグがなければ現在のトークンの種類を引き継ぐ実装でした。いずれにしても、ドキュメントの案内どおり --expiring を明示しておくと、どちらの説明でも期限付きトークンが保たれます。
gh auth refresh --scopes read:project --expiring
有効にするかどうかの判断
| 使い方 | 判断 |
|---|---|
手元の端末で対話的に gh を使う |
有効にする候補。gh auth setup-git 済みでgitが2.46以降なら、公式の説明上は日常の操作で追加の手順はない |
gh auth token の値を保存して使うスクリプトや拡張機能がある |
先に、使うたびに gh auth token を実行する形へ直してから有効にする |
| GitHub Actionsなど、環境変数でトークンを渡す自動化 | 自動更新の対象外。設定は変えずに従来の方法を使う |
| GitHub Enterprise Server 3.22以前 | 期限付きトークンは発行されず、オプトインしても非期限トークンになる |
Public Previewの段階なので、まず一部の端末で gh auth login --expiring を試します。使っているスクリプトや拡張機能がトークンの失効後も動くことを確かめてから、expiring_credentials を有効にします。
まとめ
GitHub CLI 2.103.0以降では、数時間で失効するアクセストークンを gh が自動更新する認証に切り替えられます。切り替えは gh auth login --expiring か gh config set expiring_credentials enabled で行います。漏れたトークンが使える期間を短くできます。
切り替える前に確認しておきたいのは、トークンを使うたびに gh auth token を実行しているか、HTTPSのgitで gh を資格情報ヘルパーにしているか、gitが2.46以降か、の3点です。リリースノートとGitHub Docsの案内どおりなら、これらがそろっていれば、失効したトークンでスクリプトや git push が認証エラーになるのを防げます(失効後の挙動は今回試していません)。スコープを変えるときは、gh auth refresh にも --expiring を付けておくのが確実です。
Public Previewのうちは、一部の端末で gh auth login --expiring を試し、スクリプトや拡張機能が失効後も動くことを確かめてから expiring_credentials を有効にするのがおすすめです。
誰かの参考になれば幸いです。
参考リンク:
- GitHub CLI 2.103.0 リリースノート
- GitHub CLI 2.103.1 リリースノート
- GitHub Changelog: GitHub CLI: Opt in to expiring, auto-refreshing OAuth tokens
- GitHub Docs: Authenticating with GitHub CLI
- GitHub Docs: Authorizing OAuth apps - Expiring access tokens
- cli/cli PR #14452: short-lived login, refresh, and git credential path
- cli/cli PR #14798: hint at --expiring when no preference is set






