既存のGitHubパーソナルアクセストークンを全て無効化した

## はじめに

[本番環境などでやらかしちゃった人 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yarakashi-production) の12/22(日)を担当させていただきます！

株式会社Relic所属エンジニアの、エイミ/amixedcolorと申します。

この記事は表題の通りやらかしちゃったことの注意喚起を兼ねて書いています！
社内でもポストモーテムを行いましたが、何かしらのサービスで強めの操作権限を持つ人は類似の事象に共通して遭遇しやすいと思い、改めて記事にしています。

## TL;DR;

起きたこと・暫定対応

- GitHubパーソナルアクセストークン（以降、PAT）には、2024/10/21時点で下記2つの種類がある
    - fine-grained（推奨）
    - classic
- fine-grained PATを使うためには、Organization側でPATの使用を許可する必要がある
- その際、その瞬間はfine-grained PATだけを使うからと、最小権限の原則に従いclassic PATを拒否するよう設定すると、 **それ以前に設定されていたそのOrganizationに関する全てのclassic PATが使えない状態になる**
- 元々筆者は全社で利用されるツールでの権限設定を任される部署にいたため、その設定が可能だった
- 設定後から4時間程度で気づけたため、本番環境に直接の影響は与えなかった
- 気づいた時点で設定を **classic PATも許可** に変更して暫定対応終了

気づきと恒久対応

- GitHubのトークンに関する設定は、過去に発行されたトークンに対しても影響を受ける
- 部署に配属された当初こそその強い権限に対する注意を大きく持っていたが、約半年経過しその強い権限で操作できうることへのリスク認識が甘くなってしまっていた
- 類似の事象にも注意できるために、恒久対応は「指差し呼称をする」ことに決定（他にもあるがここでは割愛）
    - 「〇〇ヨシ！」と言って、「待てよ本当にいいか…？」と思えるきっかけを作る
    - 「なぜダブルチェックや手順のレビューなどではないのか」については、そもそも「ダブルチェックや手順のレビューなどをする必要があるかもしれない」と思う必要があることから、「ダブルチェックや手順のレビューなどをする」とせずそのきっかけを作る

## ことの始まり

僕「さて、今日もAmplifyの調査を進めますか」

Amplify Gen2を活用できないかと、調査の命を任されていたエイミは、その日も調査をしていました。

僕「Amplify Gen2でRDSにセキュアな接続をしたいけど、どうもうまくいかないや…。サポートに問い合わせよう！」

数日後…

僕「何回かやりとりしつつ、なるほど理解したぞ！ふむふむ、CloudShell上でGit Cloneする必要があるんだな」

僕「認証情報を渡す必要があるけど、パーソナルアクセストークンを使うのが一番楽そうだ」

エイミはGitHubの公式ドキュメントを読みながら、パーソナルアクセストークン（以降、PAT）を使うことにしました。
その際に読んだドキュメントは下記。

- PATの作成を試みた
    - https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
- Organizationの設定を変更することを推奨されていた
    - https://docs.github.com/ja/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization

僕「ここで設定するのか、ふむふむ。2つ種類があるけど、推奨された方を使った方がいいよな。あと、今回使わない方の種類は、よりセキュリティを強くするために **拒否** しよう！」

エイミは、 `Organization > Settings > Personal access tokens > Settings > Tokens (classic)` にて、 `Restrict access via personal access tokens (classic)` を選択しました。
それがインシデントにつながるとも知らずに…。

## 1つの相談

エイミは、各プロジェクトからの相談も請け負う立場にいました。

プロジェクトA「なんかデプロイした時にGitHubの権限が足りないというエラーが出るんですよ」

エイミ「そうなんですね、うーんなんでですかね。とりあえずトークンの再発行を試してみましょうか」

トークンの期限切れを疑い、まずは再発行を行いました。

プロジェクトA「まだうまくいかないですね…」

エイミ「チームメンバーにも聞いてみます！ニコラス（仮名）さん、他に何を試せますかね？」

ニコラス「OAuthによる再認証を試してみるといいかもしれないね」

数分後…

プロジェクトA「うまくいきました！ありがとうございます！」

ここでは解決しました。後になって判明していますが、ここでは認証方法を変えたから成功しているわけで、トークンが使えたわけではないんですね。

## もう1つの相談

約1時間後…

プロジェクトB「なんかデプロイした時にGitHubの権限が足りないというエラーが出るんですよ」

エイミ「そうなんですね！（プロジェクトAの例を思い出しながら）この手順でできるのでやってみてください」

エイミはGitHubの一時的なエラーか何かが発生しているのだろうか…と初めは思っていました。
あれ…でも…まてよ…と。

エイミは思いました。「（もしかして…さっき設定したアレのせい…！？）」

エイミ「すみません、こちらで操作したことの設定ミスによるものかもしれないので、少々お待ちください」

エイミは先ほど **拒否** した設定項目を編集し、 **許可** するように変えました。

エイミ「お待たせしました！再度デプロイを試してみていただけますか？」

プロジェクトB「うまくいきました！ありがとうございます！」

## 気づいた設定ミス

エイミはついにミスに気づきました。まずはチーム内で共有し、翌日には既存のアクセストークンが確かに利用可能であることを確認、部署全体に対してもアナウンスを行いました。

ポストモーテムを行い、発生原因と根本原因を記しました。

```
# 発生原因

- Amplify調査をしていた
    - Amplify Gen2のセキュアなRDSの接続を検証中に、CloudShellでGit Cloneする必要があった
- GitHubの公式ドキュメントを読んだ
    - PATの作成を試みた
        - https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
    - Organizationの設定を変更することを推奨されていた
        - https://docs.github.com/ja/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization
- Organizationの設定を変更した（原因）
    - Relic Organization > Settings > Personal access tokens > Settings > Tokens (classic) にて、「Restrict access via personal access tokens (classic)」を選択
        - 既存の設定に影響があるとは考えられず、今回使用するfine-grained PATさえ許可できていれば良いと考えた
        - PAT(classic)は今回使用しないので、セキュアな運用を心がけようと制限した

## 根本原因を辿る

- OrganizationのSettingsを変更する際に影響の大きさを見誤った
    - 既存のアクセストークンに対しても設定が影響することを認識できなかった
    - 設定画面で「By default, personal access tokens (classic) can access...」という、「既存の設定では許可されていて、制限することが既存のトークンにも影響すること」を暗に示唆する記載があったが、気づけなかった
    - 公式ドキュメントに、既存のトークンにも影響する旨の記載がなかったため、そこまで危険な変更だと思わなかった

```

## もう再発しないために

ポストモーテムとして下記を記録し、部署の定例でも発表しました。

### この事象自体を今後発生させないために

`Organization > Settings > Personal access tokens > Settings > Tokens (classic)` にて、 `Allow access via personal access tokens (classic)` を選択する

### 類似の事象を発生しづらくするために

- GitHub Organizationの設定変更の影響は大きいことをチーム内で共有
- GitHubにおいて、設定は過去の状況にも波及することをチーム内で共有
- 対象を限らず、設定を変える時は指差し確認をする
    - ダブルチェックや手順のレビューなどは「実施することで防ぐことができる」が、「実施すると判断する」段階が必要
    - 指差し確認はそのきっかけになると考えた

### 発生しても被害を軽微にするために

- 少しでも不安があれば、事前の作業手順書作成もしくは、やった操作の記録を取る

## 特筆すべきポイント

今回のやらかしを通して学んだ、おそらく汎用的なことは下記でした。

- 「安全のために」と考えて権限を小さくしたことが裏目に出た
    - 良かれと思ってやっていることもインシデントにつながってしまうことがある
- 強い権限を持っているという認識が薄れてしまっていた
    - いわゆる「慣れ」は意識するだけでは避けられない
    - 慣れてしまう前提でどうリスクに気づかせるかを仕組み化する
- 対象を限らず、設定を変える時は指差し確認をする
    - 「〇〇ヨシ！」と指差ししながら言って、「いや、待てよ本当にいいか…？」と思えるきっかけを作る
    - 「ダブルチェックや手順のレビューなど」はよく解決策として考えられるが、そもそも「ダブルチェックや手順のレビューなどを実施すると判断する」段階が必要
    - 「そもそもリスクに気づかなかった」という今回の事例においての解決策は、リスクを知っていて行うダブルチェックや手順のレビューではなく、リスクに気づくための指差し呼称

## おわりに

今回は、設定から4時間後には気づくことができ、デプロイがうまくいかないとなっていたプロジェクトでもそれはStg環境などで、リリースがあるわけではなかったため、結果的な影響は致命的なものではありませんでした。

しかし、もし発覚が遅れていたり、その時リリースするプロジェクトがあったら、さらに大きな影響を出していたのは間違いない操作でした。

起こしてしまったことは変えられないので、反省し、次に活かしています。

今では指差し呼称は自分の中でかなり習慣化されてきました！

ここまでお読みいただいた方へ、ありがとうございます。
みなさんもぜひ、安全な指差し呼称ライフを！

それでは、またこんど！