🐧

GitHub Actions の secrets の公開範囲と permissions を最小限にする

2023/02/12に公開

GitHub Actions のセキュリティ上のプラクティスと、プラクティスを守れているかチェックするツールを紹介します。

ここで紹介するプラクティスは以下の 2 つです。

  • permissions は job 毎に明示的に設定し、デフォルトの権限を使用したり workflow 単位で権限を付与するのは避ける
  • secrets は step 毎に設定し、 workflow や job の環境変数として設定するのは避ける

ごく基本的なものですが、守れていない Workflow が数多く存在するはずです。

多くの Workflow は third party または内製の action や CLI ツールに依存しており、それらが改竄されて悪意のあるコードが Workflow で実行される可能性は常に存在します。その可能性を 0 にすることは不可能と言っても過言ではないので、改竄されて悪意のあるコードが実行されてしまったとしても、 permissions や secrets を適切に設定し、リスクを最小限にすることが重要です。

GitHub Actions で使える access token ${{github.token}} にはデフォルトで権限が付与されていますが、必要以上に多くの権限が付与されているため、明示的に必要最小限の permissions を指定するべきです。
全ての job で必要な permissions をまとめて workflow に設定するのも、各 job に不必要な権限を付与することになるので避けるべきです。
permissions では read-allwrite-all を指定することも可能ですが、必要以上に多くの権限が付与されるため使用を避けるべきです。

ちなみに、最近新規の repository に関してはデフォルトの権限が Read Only に変更されました。

https://github.blog/changelog/2023-02-02-github-actions-updating-the-default-github_token-permissions-to-read-only/

これはとても良い話だと思いますが、既存の repository に関しては write 権限がついたままですし、 Read 権限ですら不要なものも多いですので、やはり明示的に permissions を指定するべきということに変わりはないと思います。

権限が全く必要ない場合、 {} を指定すると何も権限が付与されなくなります。

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

You can use the following syntax to disable permissions for all of the available scopes:

permissions: {}

また、 secrets を workflow や job に環境変数として設定するのも、その secrets が不要な step でも secrets が参照できてしまい、 secrets が流出・悪用されるリスクが高まるため、避けるべきです。

プラクティスが守られているかツールでチェックする

上記のプラクティスが守られているかどうか目視でチェックしたりレビューでいちいち指摘するのも大変です。機械的にチェックできるものについてはツールによって自動化するべきなので、簡単なツールを作りました。

https://github.com/suzuki-shunsuke/ghalint

使い方などは README を読んでください。

Workflow ファイルが更新された際に GitHub Actions で ghalint を実行するようにすることで、プラクティスが守られてるか常にチェックすることが出来ます。

一応言っておくと、このツールは以下のことまではチェックしてくれません(できたら最高ですが、難しいでしょう)。

  • 設定された permissions が本当に必要かどうか
  • 依存している reusable workflow や action に問題がないか

Discussion