GitHub Gistとは:コードの断片を共有する、公開範囲の注意点

公開 書いた人 大林 諒

外注エンジニアBから、スクリプトの断片がGistのURLで送られてくることがあります。Gistは、コードの断片などを手軽に共有できるGitHubの機能です。手軽な代わりに、名前から受ける印象と公開範囲がずれているところがあります。「Secret」と書いてあっても非公開ではありません。サンプル料理教室の例で、何を置いてよくて何を置いてはいけないかを順に書きます。

この記事の内容
  1. 先に答えると
  2. Gistとリポジトリの違い
  3. Secret gistは非公開ではない
  4. 置いてはいけないもの
  5. Gistを作る手順
  6. 編集、Fork、Star、埋め込み
  7. クローンして手元で直す
  8. ghで作る
  9. 使いどころと、使わない場面
  10. 外注エンジニアBに断片を見せる流れ
  11. 間違えて置いたときの順番
  12. できないことと、その代わり
  13. よく詰まるところ
  14. 次に読む

先に答えると

Gistは、コードの断片や手順の控えを置く小さな置き場です。中身はGitのリポジトリなので、編集の履歴が残り、クローンもできます。公開範囲は public と secret の2つだけです。

  • Secret gistは非公開ではない。URLを知っていれば誰でも見られる
  • secret は一覧と検索に出ないだけで、見られる人を絞る機能はない
  • 鍵、パスワード、顧客情報は secret でも置かない
  • public にしたものは secret に戻せない
  • 間違えて置いたら、消す前に鍵を無効にする

Gistとリポジトリの違い

リポジトリは、ファイルと変更履歴の置き場です。Gistもその1つで、公式は「すべてのGistはGitのリポジトリ」と説明しています。違うのは、手軽に共有するための作りになっていることです。

比べるところGistリポジトリ
向いているもの断片、短いスクリプト、手順の控えホームページや仕組み一式
置き場所gist.github.com の自分の一覧個人かOrganizationの下
公開範囲public、secretPublic、Private
見られる人を絞るできないPrivateなら招待した人だけ
履歴残る。「Revisions」で見る残る
クローンできるできる
Issue、プルリクエスト使う前提の作りではないある

大きな違いは、見られる人を絞る行です。サンプル料理教室の website や reservation-mail は非公開リポジトリに入っていて、招待した人しか見られません。Gistに同じ守り方はありません。

Secret gistは非公開ではない

ここがこの記事でいちばん大事なところです。GitHubの公式の説明は次のとおりです。

  • secret は「Discover」(公開されたGistの一覧)に出ない
  • secret は検索にも出ない。ログインした作者本人の検索を除く
  • 「Secret gists aren’t private.」と明記されている
  • URLを友人に送れば、その人は見られる
  • 知らない人がURLを見つけた場合も、その人は見られる

公式は続けて、コードを人目から離しておきたいならPrivateのリポジトリを作るよう案内しています。

つまり secret は「鍵のかかった部屋」ではなく、「地図に載っていない部屋」です。鍵はかかっていません。場所を知っていれば、ログインしていなくても入れる前提で考えます。

URLは思ったより広がります。メールの転送、チャットへの貼り付け、ブラウザの履歴、スクリーンショット。外注エンジニアBに送った1本のURLがどこまで届くかは、送った側では管理できません。

公開範囲一覧と検索URLを知っている人招待で絞る
public出る見られるできない
secret出ない見られるできない
Privateのリポジトリ(比較)出ない権限がなければ見られないできる
publicは看板つき、secretは看板なしで扉が開き、Privateは鍵つきという公開範囲の違い
publicは看板つき、secretは看板なしで扉が開き、Privateは鍵つきという公開範囲の違い

置いてはいけないもの

secret であっても、次のものは置きません。

  • APIキー、パスワード、トークン(.env の中身)
  • 受講者の名前、電話番号、メールアドレス
  • 予約の一覧、問い合わせの本文
  • 契約書、請求書、社内の資料
  • サーバーの接続先と、ログインに使う情報

見落としやすいのは、スクリプトの中に書いたままの値です。send_mail.py の断片をBに見せるとき、中にメールの送信用のパスワードが書いてあれば、それごと載ります。送る前に、値を xxxxxxxx に置き換えます。

なお公式によると、GitHubはGitHub.comの secret のGistも、提携先の鍵が載っていないかを自動で調べ、見つかれば提携先に知らせます。これは漏れたあとに気づく仕組みで、置いてよいという意味ではありません。

Gistを作る手順

GitHubにログインしているものとします。

  1. gist.github.com を開く
  2. 右上の「+」を押す
  3. 「Gist description」に 予約確認メールの送信の断片 と入れる
  4. 「Filename including extension」に send_mail_sample.py と入れる
  5. 下の欄に中身を入れる。パソコンからテキストファイルをドラッグして入れてもいい
  6. 「Create secret Gist」を押す

公開したいときは、6のボタンの横の矢印を押して「Create public gist」を選び、そのボタンを押します。

間違えて public にするのを防ぐため、作ったあとの動きを覚えておきます。公式の説明では、一度作ったGistを public から secret には変えられません。secret を public に変えることはできます。つまり一方通行です。public で作ってしまったら、設定を変えて戻すことはできず、消して作り直すことになります。

新しいGistで説明とファイル名と中身を入れ、Create secret Gistで作る流れ
新しいGistで説明とファイル名と中身を入れ、Create secret Gistで作る流れ

編集、Fork、Star、埋め込み

機能何ができるか場所
編集の履歴過去の版と差分を見るGistの上の「Revisions」
Fork他の人のGistを自分の分として写すGistの画面
Starあとで探すために印をつける右上の「Star」
埋め込みブログなどにGistを表示する「Embed」のURLの横のアイコン

Forkは作者でなくてもできます。Starをつけたものは https://gist.github.com/ユーザー名/starred で一覧できます。

特定のファイルだけを埋め込むなら、埋め込みのURLの後ろに ?file=ファイル名 をつけます。料理教室のホームページで使う機能ではありませんが、技術ブログを見ているとよく目にします。

見落としやすいのは履歴です。鍵を書いたことに気づいて編集で消しても、「Revisions」に古い版が残ります。

クローンして手元で直す

GistはGitのリポジトリなので、クローンしてコミットして戻せます。URLは「Embed」のメニューの「Clone via HTTPS」か「Clone via SSH」で取ります。

本物のGistには接続せず、手元に作った練習用のリポジトリを相手に同じ流れを動かしました。

$ git clone gist.git mygist
Cloning into 'mygist'...
done.
$ ls mygist
send_mail_sample.py

直してコミットし、戻します。

$ git add send_mail_sample.py
$ git commit -m "文面を修正"
[main bf760fd] 文面を修正
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
   76ad555..bf760fd  main -> main
$ git log --oneline
bf760fd 文面を修正
76ad555 最初の版

枝名の main は練習用のリポジトリの結果です。本物のGistの枝名は公式に書かれていません。送るときは git push だけで足ります。

古い版の中身は、新しい版を送ったあとでも読めます。

$ git show HEAD~1:send_mail_sample.py
print("予約確認メールの送信テスト")

編集で消しても消えない、という話はこの動きのことです。

ghで作る

GitHub CLI(gh)は、GitHubの操作をコマンドでやる道具です。次は gh gist create --help などで確かめた書き方で、実行はしていません。本物のGistが作られるからです。

gh gist create send_mail_sample.py -d "予約確認メールの送信の断片"

ヘルプには「By default, gists are secret」とあります。何もつけないと secret です。公開するときだけ --public をつけます。

書き方何をするか
gh gist create ファイル名secret で作る
gh gist create --public ファイル名public で作る
gh gist create -d "説明" ファイル名説明をつけて作る
gh gist list自分のGistの一覧
gh gist view ID中身を見る
gh gist clone ID手元にクローンする
gh gist edit ID編集する
gh gist delete ID消す

AIに頼むときも同じです。gh gist create は外から見える場所にファイルを置く操作です。gh gist create --public や、.env を含むファイルの指定を許可しないようにします。何が載るかを読んでから許可します。

使いどころと、使わない場面

向いているのは、見られても困らない短いものです。

場面Gistで足りるか置く先
Bに値を消したスクリプトの断片を見せる足りるGist(secret)
Gitの手順の控えを自分用に残す足りるGist(secret)
技術ブログにサンプルを載せる足りるGist(public)
社内の手順書、会社の資料向かないGoogleドキュメント、社内の共有ドライブ
受講者の一覧、予約データ向かない予約システム、権限のある共有ドライブ
予約メールのスクリプト一式向かない非公開リポジトリ reservation-mail
Bと一緒に直し続けるコード向かない非公開リポジトリ

実際に運用していると、最初は断片だったものが育って、気づけば本番の設定まで入っていることがあります。Bとのやり取りが2回目に入ったら、リポジトリに移す頃合いです。

見せる相手が決まっていて、中身に社内の事情が少しでも入るなら、非公開リポジトリにしてBを招待するか、値を消してからGistにするかのどちらかにします。迷ったら非公開リポジトリです。

鍵や個人情報、URLの広がりを順に確かめて、Gist・非公開リポジトリ・置かないを選ぶ流れ
鍵や個人情報、URLの広がりを順に確かめて、Gist・非公開リポジトリ・置かないを選ぶ流れ

外注エンジニアBに断片を見せる流れ

予約確認メールが届かない件で、Bに send_mail.py の一部を見てもらう場面です。

手元のファイルには、送信用のパスワードが直接書いてあったとします。そのまま貼らず、見せる部分だけ抜き出して、値を置き換えます。

次は置き換える前の行です。これはGistに置きません。

SMTP_PASSWORD = "本物のパスワード"

次が置き換えたあとの行です。Bには動きが分かれば足りるので、値はいりません。

SMTP_PASSWORD = "xxxxxxxx"

渡す前に確かめるのは3つです。

  • パスワード、キー、トークンの値が残っていない
  • 受講者の名前とメールアドレスが、例の値に変わっている
  • 社内のサーバー名や管理画面のURLが残っていない

確かめたら secret で作り、URLをBに送ります。Bとの話が終わったら、そのGistは消します。残しておく理由がないものを残さないほうが、あとで探す手間も、見られる心配も減ります。

受け取る側になったときの注意もあります。Gistは作った人があとから書き換えられます。外部の人から渡されたスクリプトは、動かす前に中身を読み、「Revisions」で見た時点の版と変わっていないかを確かめます。読めない内容なら、詳しい人に見てもらってから動かします。

間違えて置いたときの順番

鍵を載せてしまったら、消すことより先に鍵を止めます。

  1. 鍵を発行した管理画面で、その鍵を無効にする
  2. 新しい鍵を作る
  3. Gistを消す
  4. 外注エンジニアBなど、URLを渡した相手に手元の控えを消してもらう
  5. 不審な使われ方がないか、発行元の利用履歴を見る

消すだけでは足りない理由は3つです。編集で消しても「Revisions」に残ります。Gistそのものを消しても、すでにクローンした人の手元には残ります。public だったなら、誰かが写していないとは言えません。だから鍵は「もう漏れたもの」として扱い、使えない状態にするところから始めます。消す作業は、そのあとの片づけです。

詳しい順番は「APIキーやパスワードをGitHubにpushしてしまったときの対応」に書きました。Gistでも考え方は同じで、まず止める、次に消す、です。そもそも載せないための話は「.gitignoreの書き方と、リポジトリに入れてはいけないファイル」にあります。ただし .gitignore は手元のGitの設定なので、Gistの作成画面に貼り付けたものや、gh gist create に直接渡したファイルは止めてくれません。

顧客情報を載せた場合は、受講者への連絡が要るかを代表が判断します。

できないことと、その代わり

できないことその代わり
Gistを見られる人を絞る非公開リポジトリにして招待する
public を secret に戻す消して secret で作り直す。その前に公開された前提で対処する
編集で過去の版を消すGistごと消す。鍵は先に無効にする
配った先の控えを消す相手に頼む。鍵は無効にしておく

よく詰まるところ

症状原因直し方
secret なのに知らない人に見られたURLを知っていれば見られる中身に合わせて鍵を止める。今後は非公開リポジトリに置く
public を secret に変える項目がない公式の仕様で変えられない消して作り直す
編集で消した値が残っている「Revisions」に履歴がある鍵を無効にしてからGistごと消す
検索しても自分の secret が出ないログインしていない作者としてログインして探す
gh gist create で何も起きない読み込むファイルの指定がない、- で入力待ちファイル名を指定する
古いGistを探せない一覧が増えたgist.github.com の自分の一覧かStarから探す

次に読む

公開と非公開の考え方は「GitHubとは:できることと、公開・非公開の考え方」に、コマンドの全体は「GitHub CLIの使い方:ghでできることと、gitとの違い」に書きました。鍵を載せてしまった場合は「APIキーやパスワードをGitHubにpushしてしまったときの対応」、入れてはいけないファイルの話は「.gitignoreの書き方と、リポジトリに入れてはいけないファイル」です。

あわせて読む