シークレットと安全 — 鍵・最小権限・他人のアクション・fork PR
📖 このページのゴール:自動化に 鍵(APIキーやトークン) を安全に渡す方法と、やりすぎない権限(最小権限)、他人の部品を信じるときの注意、そして fork(外部の人のコピー)からのPRの危なさ が分かるようになる。 ← 目次・はじめにへもどる
自動化が育ってくると、ワークフローが「外の世界」とつながり始めます。デプロイ先にログインする・APIを叩く・通知を送る——どれにも 鍵(パスワードのようなもの)が要ります。ここを雑にやると、鍵が漏れて他人に悪用されるという、いちばん怖い事故が起きます。
このページのキーワードは 🗝 金庫。鍵は コードに直接書かず、GitHubの金庫に預けて、必要なときだけ取り出す——それだけ守れば、まず大丈夫です。
① シークレット(secrets)=鍵は金庫に預ける 🟢
シークレット(secret=秘密の値)とは、APIキー・トークン・パスワードなど 人に見られたら困る文字列 のこと。
絶対にやってはいけないのが、これを コードにそのまま書く こと(「ベタ書き」と言います)。GitHubはコードの履歴を全部残すので、一度書いたら消したつもりでも履歴に残り続けます。
そこで GitHub は 金庫(Settings) を用意しています。
鍵そのもの ───預ける──▶ 🗝 GitHubの金庫(Settings)に保存
│
ワークフローから $ で取り出して使う
│
実行ログには ●●●● でマスクされる
金庫への入れ方(イメージ):リポジトリの Settings → Secrets and variables → Actions で、名前(例 NPM_TOKEN)と値を登録するだけ。値は登録後に見えなくなるので安心です。
使うときは、YAMLの中で $ と書きます。
steps:
- name: デプロイする
run: ./deploy.sh
env:
DEPLOY_TOKEN: $
1行ずつ読むと:
name:… この手順の名前(人が読む用)。run: ./deploy.sh… デプロイ用のコマンドを実行。env:… この手順に 環境変数(コマンドに渡す設定値) を渡す宣言。DEPLOY_TOKEN: $… 金庫から鍵を取り出してDEPLOY_TOKENという名前で渡す。鍵そのものはYAMLに出てこない。
金庫は 3つの単位で持てます(広い順)。
| 金庫の単位 | どこに効く | 使いどころ |
|---|---|---|
| Organization(組織) | 組織内の複数リポジトリで共有 | 全社で使う共通の鍵 |
| Repository(リポジトリ) | そのリポジトリだけ | いちばん普通。多くはこれ |
| Environment(環境) | production などの環境ごと |
本番の鍵は本番だけに絞る/承認を挟める |
🔧 Environment(環境) を使うと、「本番にデプロイする前に人の承認を必須にする」「本番の鍵は本番ジョブからしか触れない」といった、もう一段安全な運用ができます。最初は気にしなくてOK。
② GITHUB_TOKEN と最小権限 — 渡しすぎない 🟢
実は、ワークフローには 自分で登録しなくても自動でもらえる鍵 が1つあります。それが GITHUB_TOKEN(ギットハブ・トークン)。
- 一時トークン(その実行の間だけ有効。終わると無効になる使い捨て)。
- これで 自分のリポジトリを操作できる(コメントを書く・ラベルを付ける・リリースを作る等)。
$で参照できる。
便利ですが、既定のままだと権限が広すぎることがあります。「読むだけで十分なのに、書き込みもできてしまう」状態は危ない。そこで permissions:(許可)で必要な権限だけに絞る——これを 最小権限(さいしょうけんげん) と呼びます。
permissions:
contents: read # ソースを読むだけ
pull-requests: write # PRにコメントを書くのは許可
1行ずつ読むと:
permissions:… このGITHUB_TOKENに 何を許すか をここで宣言。contents: read… コード(中身)は 読むだけ。書き換えは不可。pull-requests: write… PRへの 書き込み(コメント等)だけ 許可。- ここに 書いていない権限は与えられない(=必要な分だけ渡す)。
| 考え方 | たとえ | 効果 |
|---|---|---|
| 既定の広い権限 | 家じゅうの鍵束をまるごと渡す | 便利だが、漏れたら全部やられる |
| 最小権限 | その部屋の鍵 1本だけ 渡す | 漏れても被害が小さい |
🟢 コツ:まず
permissions: {}(全部なし)から始め、エラーになったぶんだけ足していくと、自然に最小権限になります。
③ 他人のアクションは「信頼」が要る — SHAで固定(pin) 🔧
ワークフローは 他人が公開した部品(アクション) を uses: で借りて組み立てます(レゴの部品 🧩)。とても便利ですが、借りた部品の中身は、相手がいつでも変えられることに注意。
uses: somebody/action@v1 のように v1 という“ふわっとした名前”で借りると、ある日 v1 の中身が こっそり差し替えられて、あなたの金庫の鍵を盗むコードに化ける——という事故があり得ます。
防ぐコツが SHA で固定(pin=ピン留め)。SHA とは、ある時点の中身を指す 動かない番号(指紋のようなもの)。これで固定すると、中身が勝手に変わらないことを保証できます。
| 書き方 | 例 | 安全さ |
|---|---|---|
| タグ(ふわっと) | actions/checkout@v4 |
中身が後で変わりうる |
| SHAで固定(pin) | actions/checkout@<長い40桁のSHA> |
その時点の中身に固定。おすすめ |
🔧 公式の
actions/...(GitHub純正)は比較的安心とされますが、外部の人のアクションほど SHA 固定の価値が高いです。Dependabot(前ページ参照)に アクションの更新もPRで提案させると、固定しつつ安全に上げられます。
④ fork からのPRに鍵を渡さない — pull_request_target の罠 🟢
ここが いちばん事故りやすいところ。落ち着いて読んでください。
オープンソースでは、知らない人があなたのリポジトリをコピー(fork)して、PRを送ってきます。そのPRには 相手が書いたコードが入っています。もしこれを あなたの金庫の鍵つきで実行してしまうと——他人のコードがあなたの鍵を読み取って盗めることになります。
GitHubはこれを防ぐため、fork からのPR(pull_request トリガー)には、既定でシークレットを渡さないようになっています。これは安全のための既定なので、無理に外さないこと。
| トリガー | 何が起きる | 安全度 |
|---|---|---|
pull_request |
fork のPRには 鍵が渡らない(既定) | 🟢 安全 |
pull_request_target |
元リポジトリ側の権限・鍵が使えることがある | ⚠️ 危険。安易に使わない |
⚠️ pull_request_target は、「fork のPRでもラベル付けなどをしたい」ときに使える特別なトリガーですが、鍵が使える状態で他人のコードに触れる組み合わせになりがちで、鍵漏れの定番事故です。仕組みを完全に理解するまで使わない——初心者は「こういう危ないものがある」とだけ覚えておけば十分です。
🟢 覚え方:fork のPRは「よその人が書いた紙」。中身を信用しきれないので、金庫の鍵は渡さない。これが既定で、それが正しい。
⑤ ログに鍵を出さない — マスクされても油断しない 🔧
GitHub は、シークレットの値が 実行ログに出そうになったら自動で ●●●● に伏せてくれます(マスク)。とはいえ 万能ではありません。
- 鍵を 加工して出す(一部だけ・base64化など)と、マスクをすり抜けることがある。
echo "$TOKEN"のような わざわざ表示するコードは書かない。- デバッグでうっかり出してしまったら、その鍵はもう漏れたものとして即・無効化(ローテーション)する。
🔧 「マスクされるから大丈夫」ではなく、そもそもログに出さないのが正解。鍵は 使うだけ・見せない。
🔗 姉妹教材とつながっています
このページの考え方は、姉妹教材の 「鍵を守る」「最小権限」 とまったく地続きです。
- 🗝 鍵はコードに書かず金庫(シークレット)へ … どんな道具でも共通の鉄則。
- 🛡 最小権限 … 渡す権限は 必要な分だけ。漏れたときの被害を小さく。
- デプロイ先(Vercel/サーバー/サーバーレス)の安全は、姉妹編 コンピューティングの選択肢 とあわせて読むと、点が線になります。
🟢 ひとことで言うと
鍵は コードに書かず金庫(シークレット)に預け $ で取り出す。GITHUB_TOKEN は permissions: で最小権限に絞り、他人のアクションは SHA で固定。fork のPRに鍵は渡さないのが既定で、pull_request_target は危ないので安易に使わない——「鍵は預ける・権限は絞る・他人は固定する・よその紙は信じすぎない」。