EmotionTechテックブログ

株式会社エモーションテックのProduct Teamのメンバーが、日々の取り組みや技術的なことを発信していくブログです。

GitHub Actions の permission 設定ミスで突然デプロイできなくなった話

はじめに

こんにちはあるいはこんばんは。フロントエンドエンジニアの id:kasaharu です。

エモーションテックでは GitHub Actions のワークフローを使ってフロントエンドのデプロイフローを組んでいます。 少し前にワークフローの permission の設定ミスにより突然デプロイができなくなったことがあったので、今回はそのとき起こったことについて書きます。

これは エモーションテック Advent Calendar 2024 23 日目の記事です。

前提

今回の問題について話す前に、まず対象リポジトリとワークフローについて前提を揃えようと思います。

  • 今回登場するワークフローはコミットごとにビルドするためのワークフローとデプロイ用のワークフローの 2 つである
    • 話を簡単にするため以下、build.yml と deploy.yml と呼ぶ
  • npm package を使用したアプリケーションを管理するリポジトリであり、各ワークフローでは actions/cache を使って node_modules 配下をキャッシュしている
  • npm package の中には GitHub Packages を使って社内限定で公開している private package がある
  • ワークフロー内で GitHub Packages レジストリの認証を受けるために GITHUB_TOKEN を使っている

デプロイができなくなった原因

ある日 deploy.yml を動かすと次のエラーが発生し、デプロイができなくなってしまいました。エラーの発生箇所は npm package をインストールする step でした。

npm error 403 403 Forbidden - GET {{ ここには社内公開の private package の名前が入る }} - Permission installation not allowed to Read organization package

エラーメッセージの内容は private package をインストールするための read 権限がないというありふれたものでした。 deploy.yml の permission を確認してみると以下の様になっており、確かに packages に対しての権限はセットされていませんでした。

permissions:
  id-token: write
  contents: read

しかし、この permission が設定されたのは 2 年近く前であり、インストールする npm package の中に private package が含まれるようになったのは 10 ヶ月以上も前でした。 また、エラー発生の一週間前までは毎週問題なく deploy.yml は動いていました。いったいどこに問題があったのでしょうか?

なぜ今まで動いていたのか

まずは、問題なくワークフローが動いていたときのログと失敗したときのログを比較しました。 その結果、前の週までは npm package をインストールする step で cache がヒットしていて、失敗したときは cache がヒットしていないことがわかりました。 cache を使っていれば成功することがわかったので、次はこの cache がいつ作成されたのかを調査しました。

cache は別のワークフローである build.yml によって作られていました。build.yml にも当然 npm package をインストールする step があります。 しかし、build.yml には permission の指定がありませんでした。

permission の指定がない場合 GITHUB_TOKEN のアクセス許可はどうなっているのでしょうか? GITHUB_TOKEN のアクセス許可 - GitHub Docs を見ると、デフォルト設定では packages への read 権限がついていることがわかります。

GITHUB_TOKEN のアクセス許可の変更 - GitHub Docs を見ると permissions キーを使ったワークフローの GITHUB_TOKEN のアクセス許可は指定したものに上書きされます。明示的に書いていないスコープはすべて none になります(差分更新ではない)。

以上を踏まえた結果、今までのデプロイは次の通りたまたま動いていたことがわかりました。

  1. permission 指定をしていない build.yml でデフォルトのアクセス許可を持った GITHUB_TOKEN を使って npm package をインストール
  2. private npm package が cache される
  3. permission 指定したことで packages スコープの read 権限がない deploy.yml で npm package をインストールするも cache が使用され、アクセス許可がないことに気づかず完了する

今回の学び

今回の件を通して、以下の学びがありました。

  • GITHUB_TOKEN にはデフォルトのアクセス許可が定義されている
  • permissions キーを使って GITHUB_TOKEN のアクセス許可を変更した場合、指定されていないスコープの権限は none になる

さいごに

いかがでしたか? CI / CD のワークフローは毎日点検するものでもないため、不具合の発覚に時間差が生まれることも少なくありません。 弊社ではこういった問題が起きたときに、その問題とわかったことをチームに共有する文化があります。小さな気づきもチームに共有することで大きな知識になります。

エモーションテックでは顧客体験、従業員体験の改善をサポートし、世の中の体験を変えるプロダクトを開発しています。プロダクトに興味のある方、Angular を使ったアプリケーション開発をしたい方、ぜひ採用ページからご応募をお願いいたします。

hrmos.co