AI に gh auth token のRunを求められた|実行前に確認したいこと

AI エージェントを使って開発していると、ときどき自分ではよく分からないコマンドの実行を求められることがあります。

私も開発中、認証まわりの PowerShell コマンドを、意味を十分理解しないまま何度か Run してしまったことがありました。

その後、何を許可していたのか確認していく中で気になったのが、次のコマンドです。

gh auth status
$env:GITHUB_TOKEN = (gh auth token)

最初に見たときは、「GitHub を操作するために認証取得してるのかな~」ぐらいにしか思っておらず、普段から commit や push、PR 作成まで任せてることもあったので気にせず Run してました。

ただ、ちょっと気になって調べてみると、この2行はやっていること、目的、リスクがそれとは異なることに気づきました。

しかも私は、gh コマンドも知らなかったくせに、よく何も考えず Run してたなと思います。

今回は、

  • gh と GitHub CLI は何なのか
  • ブラウザの GitHub ログインとは何が違うのか
  • gh auth status と gh auth token は何が違うのか
  • $env:GITHUB_TOKEN = (gh auth token) を実行すると何が変わるのか
  • なぜ、意味が分からない状態なら Run の前に一度確認した方がいいと思ったのか
  • その後、自分の自動化ではどういう設計にしたのか

をまとめます。


そもそも gh って何?

今回 AI から提示されたコマンドには、

gh auth status
gh auth token

のように、先頭に gh が付いています。

この gh は、GitHub CLI という GitHub 公式ツールを操作するためのコマンドです。

GitHub CLI を使うと、普段ブラウザで GitHub を開いて行っている操作の一部を、PowerShell などのターミナルから実行できます。

例えば、

gh pr list

なら Pull Request の一覧を確認でき、

gh pr create

なら Pull Request を作成できます。

かなりざっくり言うと、

ブラウザ
↓
github.com を開く
↓
画面から GitHub を操作する

の代わりに、

PowerShell など
↓
gh コマンド
↓
GitHub を操作する

ことができるツールです。

git と gh は何が違う?

git add .
git commit -m "修正"
git push

のようなコマンドを使って、変更を記録したり、GitHub 上のリポジトリへ反映したりしますが、git は、Git という仕組みそのものを操作するコマンドです。

Git はファイルの変更履歴を管理する仕組みなので、git add、git commit、git branch、git status などは GitHub 専用のコマンドではありません。

git push や git pull では GitHub 上のリポジトリと通信することもありますが、これも Git の仕組みを使って remote repository とやり取りしています。

一方で gh は、GitHub 専用の CLI ツールです。

ここで違いが分かりやすいのが Pull Request です。

Git には Pull Request という機能そのものがないため、

git pr create
git pr list

のようなコマンドはありません。

ブランチを作って、

git push

で GitHub へ送るところまでは Git でできますが、そのブランチから Pull Request を作成するのは GitHub 側の機能です。

そこで GitHub CLI を使うと、

gh pr create

で Pull Request を作成し、

gh pr list

で Pull Request の一覧を取得できます。

かなりざっくり分けると、

git
= Git という仕組みを操作する

gh
= GitHub というサービス固有の機能を操作する

という違いです。


ブラウザのログインとGitHub CLIの認証は別

GitHub CLI を使う場合は、gh auth login を使って GitHub への認証を行います。

認証の途中でブラウザが開くこともあるので少し紛らわしいですが、ブラウザのログイン状態と GitHub CLI の認証情報は別です。

かなりざっくり分けると、

ブラウザの GitHub
= ブラウザ側のログイン状態で GitHub を使う

GitHub CLI
= GitHub CLI で利用できる認証情報を使って GitHub を操作する

という違いです。

ただし、AI が操作できるブラウザで GitHub にログイン済みなら、AI がそのブラウザを使って GitHub の画面を操作できる場合はあります。

一方で、そのブラウザが GitHub にログイン済みだからといって、GitHub CLI まで自動的に認証済みになるわけではありません。

ブラウザのログイン状態と、gh コマンドが使う認証情報は別です。

つまり、GitHub にアクセスするときには、

  • ログイン済みのブラウザセッションを使う
  • GitHub CLI が持つ認証情報を使う
  • GITHUB_TOKEN など、環境変数として渡された token を使う(GITHUB_TOKEN については後述)

といった認証方法があります。

同じ GitHub を操作していても、「どの認証情報を使ってアクセスしているか」は別、ということです。

→ GitHub CLI manual:gh auth login


gh auth status は GitHub CLI の認証状態を確認する

ここまでの違いが分かれば、

gh auth status

が何を確認しているのかも分かりやすいかと思います。

これは、GitHub CLI がどのアカウントで認証されていて、その認証情報が使える状態かを確認するためのコマンドです。

GitHub CLI
↓
GitHubへアクセスするための認証情報がある
↓
その認証が使える状態か確認する

ということです。

gh auth status をそのまま実行した場合は、token そのものは表示されません。なお、--show-token を付けると token を表示することもできます。

→ GitHub CLI manual:gh auth status


gh auth token は認証 token を取得する

一方で、

gh auth token

は、GitHub CLI の公式マニュアルでは、GitHub CLI が指定したアカウント・ホストの認証に使っている token を出力するコマンドと説明があります。

gh auth token を単体で実行すると、token そのものが標準出力へ出てしまいます。

token は認証情報なので、その値を記事やスクリーンショット、ログなどへ載せないことが望ましいです。

→ GitHub CLI manual:gh auth token


$env:GITHUB_TOKEN = (gh auth token) が何をしているのか

今回のメインです。

左側の、

$env:GITHUB_TOKEN = ...

は、PowerShell の環境変数 GITHUB_TOKEN に値を設定する書き方です。

環境変数は、プログラムから参照できる設定値を、実行中の環境に持たせておく仕組みです。

今回の $env:GITHUB_TOKEN = ... で設定される値は、基本的にはその PowerShell が動いている間だけ保持されます。

PowerShell を閉じれば、その PowerShell プロセスに設定していた GITHUB_TOKEN も消えます。

ただし、ここで消えるのは PowerShell 側に設定した GITHUB_TOKEN という環境変数自体です。

もともと GitHub CLI 側に保存されている認証情報まで消えるわけではないので、GitHub CLI の認証が残っていれば、後から再び gh auth token で token を取得できます。

一方、PowerShell を閉じるまでは GITHUB_TOKEN が残っていても、 そこに入っている token 自体が GitHub 側で失効したり、権限が変わるなどして認証情報が変わった場合は、使えなくなることがあります。

なので、見たまんまではありますが、

GitHub CLIが使っている認証tokenを取得
↓
PowerShell の GITHUB_TOKEN という環境変数へ入れる

ということをしています。

ただし、その PowerShell から別のプログラムを起動すると、そのプログラムにも環境変数が引き継がれることがあります。

ここが私がリスクを感じたポイントです。


GITHUB_TOKEN に入れると、別のプログラムから使える

PowerShell の GITHUB_TOKEN に入った token は、その後どう使われるのかについて。

例えば PowerShell から、

node run-production.mjs

という Node.js のプログラムを起動したとして、そのプログラムが、

process.env.GITHUB_TOKEN

を読むように作られていれば、PowerShell から引き継いだ GITHUB_TOKEN の値を利用できます。

つまり、

GitHub CLI が持っていた認証 token
↓
PowerShell の GITHUB_TOKEN へ設定
↓
そこから起動したプログラムへ引き継がれる
↓
そのプログラムが GITHUB_TOKEN を読む
↓
token を使って GitHub へアクセス

ということが可能になります。

ここでいう「別のプログラム」は、例えば Node.js のスクリプトや、GitHub API を利用する自作処理などです。

PowerShell 自体が勝手に GitHub を操作し始めるわけではありません。

GITHUB_TOKEN を読むように作られたプログラムが、その認証情報を使えるようになる、ということです。

→ Microsoft Learn:PowerShell の環境変数


それで何ができるようになるのか

では、その token を GITHUB_TOKEN に入れたら、AI は何ができるようになるのかですが、

$env:GITHUB_TOKEN = (gh auth token)

を実行しただけで、AI に GitHub 上の何でも自由に操作できる権限が付くわけではもちろんありません。

その GITHUB_TOKEN を読めるプログラムが、そこに入った認証情報を使えるようになる、ということです。

実際に何ができるかは、

  • token にどんな権限があるか
  • その token が、AI が操作可能な repository にアクセスできるか
  • どのプログラムが GITHUB_TOKEN を読めるか
  • そのプログラムがどんな GitHub 操作を実装しているか

によって変わります。

条件によっては、repository の情報を読んだり、Pull Request を作ったり、コメントを書いたり、GitHub API 経由で write したりすることもできます。

逆に、token 側に必要な権限がなかったり、プログラム側にその処理がなければ当然できません。


gh auth token を使ってはいけない、という話ではない

$env:GITHUB_TOKEN = (gh auth token)

が危険だから使ってはいけないという話ではありません。

今回だめだったなあと思ったのは、

AIに方法を提案された
↓
何をしているか分からない
↓
とりあえずRun

という使い方そのものもまあそうですが、今回のコマンドは GitHub の認証情報を別のプログラムから使える状態にする操作であり、認証や権限に関わる影響範囲の大きい処理だったという点でした。


認証情報がなければ止まるようにした

私が作っている自動化では、AI が生成した結果を自動的に検証したあと、必要に応じて GitHub 上へ変更を反映する処理があります。

その中で GitHub へアクセスする処理は、

const token = process.env.GITHUB_TOKEN;

if (!token) {
  throw new Error('GITHUB_TOKEN is required');
}

のように、実行環境に GITHUB_TOKEN が存在することを前提にしています。

存在しなければ停止させます。

AI 向けのルールとしては、

  • GITHUB_TOKEN が必要なのに存在しなければ Fail Closed(必要な条件を確認できないときに安全側に処理を止める考え方)
  • gh auth が利用できても GITHUB_TOKEN があるとはみなさない
  • 認証情報がない時に gh auth token でローカルの認証情報 を取り出して補わない

などの内容を追加しています。


完全自動化でも $env:GITHUB_TOKEN = (gh auth token) が必須とは限らない

完全自動化するなら、結局 AI に gh auth token を使わせないと認証情報を用意できないのでは?

という疑問を持つ方もいるかもしれませんが、認証情報を用意する方法は1つではありません。

例えば GitHub Actions を使って、AI を動かすジョブと、GitHub へ変更を反映するジョブを分けることもできます。

AI を動かすジョブ
└─ 必要な読み取り権限だけ

GitHub へ変更を反映するジョブ
└─ 必要な書き込み権限

GitHub Actions の GITHUB_TOKEN はジョブごとに権限を設定できるので、AI を動かす側には必要以上の権限を持たせず、実際に GitHub へ反映する処理だけに write 権限を持たせる構成にもできます。

この形なら、AI 自身がローカル PC の gh auth token から認証情報を取り出して、そのまま GitHub へ書き込める状態にしておく必要はありませんし、github.token を通して GITHUB_TOKEN を利用できたとしても、そのジョブに write 権限を与えていなければ、その token を使って GitHub へ変更を書き込むことはできません。

なお、ここでいう GitHub Actions の GITHUB_TOKEN は、前半で $env:GITHUB_TOKEN = (gh auth token) として設定した token とは別物です。GitHub Actions が job ごとに用意する token です。

→ GitHub Docs:Use GITHUB_TOKEN for authentication in workflows


まとめ

今回、AI に案内されたコマンドを、何をしているのかよく分からないまま Run していました。

しかも、それが GitHub の認証情報を別のプログラムから使えるようにする、認証や権限に関わる影響範囲の大きい操作でした。

このやり方はちょっと危ないなあと思い、その後は、必要な認証情報がなければいったん処理を止め、AI が別の認証情報を探してそのまま続行しないようにしました。

完全自動化についても、AI に強い権限をまとめて持たせるのではなく、必要な読み取り権限だけを付与した AI を動かす処理と、必要な書き込み権限を付与した GitHub への反映処理を分ける方向で考えています。

  • AI が出してきたコマンドを何でもそのまま Run するのではなく、内容を確認する、わからなければ調べる
  • 自動化そのものも、AI が考える処理と、実際に外部へ変更を反映する処理を分けられないか考える。

今回の件では、私はこの2つを意識するようになったというお話です。


参考

← ブログ一覧に戻る