🐧

GitHub Actions の Workflow の改変を防ぐ

2022/09/24に公開

GitHub Actions の Workflow や Workflow 用のスクリプトの変更を防いでセキュリティを改善するための OSS を開発しているので紹介します。

https://gha-trigger.github.io/

背景

GitHub Actions は非常に便利ですが、 Workflow を書き換えて任意のコマンドを実行できるという、セキュリティ的なリスクがあります。

例えば GitHub Actions で Terraform を実行して AWS や GCP の IaC を実現している場合、 Workflow を書き換えて terraform destroy を実行して インフラを破壊するといったことが考えられます。
GitHub App が使われている場合、 Workflow を書き換えて GitHub App で悪意のある Pull Request を approve したり、はたまた GitHub App で Pull Request を作成し、その Pull Request に悪意のある変更を加えた上で approve し、マージしてしまうと言ったことも考えられます。他にも様々なリスクがあるでしょう。

GitHub が提供する機能 (OIDC, CODEOWNERS, branch protection rule, etc) を使うことでこれらの脅威に対してある程度の対策が出来ますが、
それでも Workflow を変更して任意のコマンドが実行できてしまうというのは、対象のリポジトリで扱っている secret や組織のセキュリティに対する要求レベルによっては許容し難いでしょう。

今回の OSS が対象としているのは、そういったセキュリティの要求レベルが比較的高いリポジトリです。

Workflow の変更を禁止するために GitHub Actions ではなく AWS CodeBuild や Google Cloud Build のようなサービスを活用するというのも一つの手です。

例えば Mercari では Google Cloud Build を活用し、 Workflow を変更できないような仕組みを構築しています。

https://engineering.mercari.com/en/blog/entry/20220121-securing-terraform-monorepo-ci/

しかし、 GitHub Actions には他の CI Platform にはない強力な機能があるため、出来れば GitHub Actions が使いたいところです。

そこで GitHub Actions を使いつつ Workflow の変更を禁止するための仕組みを OSS として開発しています。

仕組み

gha-trigger drawio

リポジトリを 2 つ用意します。

  • Main Repo: CI をしたいコードを管理
    • 開発者は基本こちらに PR を投げる
    • GitHub Actions は無効化
  • CI Repo: GitHub Actions を実行するリポジトリ
    • CI を管理する一部の人だけが Write 権限を持ち、それ以外の人は Read 権限のみ持つ

GitHub App を作成し Main Repo にインストールすることで、 pull_request や push などの event が発生すると gha-trigger に webhook が送られるようにします。
gha-trigger では webhook の validation, filtering などを行い、 CI Repo の GitHub Actions を GitHub API で実行します。
GitHub Actions の event としては workflow_dispatch が使われ、 Webhook の Payload などが input として渡されます。
CI Repo の CI では CI Repo と Main Repo を checkout し、 CI を実行します。
CI Repo から Main Repo の commit status を更新したりし、 Main Repo から CI の結果を参照できるようにします。

ここで重要なのは、 Workflow や Workflow で使うスクリプトを Main Repo とは別のリポジトリで管理し、限られた人しか変更できないようにすることで、 Workflow やスクリプトが改変されるリスクを減らしているということです。

Workflow を rerun, cancel したい場合

開発者は CI Repo の Write 権限を持たないため、 Workflow を直接 rerun, cancel 出来ません。
そこで特定のフォーマットで PR にコメントをすることで、 gha-trigger が指定された Workflow, Job を rerun, cancel します。

image

特定の Workflow を手動で実行したい場合

特定の Workflow を手動で実行したい場合、手動で実行したい Workflow を管理・実行するようのリポジトリを用意します。 Manual Workflow Repo と呼ぶことにします。
このリポジトリでは開発者が手動で Workflow を実行できるように Write 権限を付与する必要があるため、 Secret の扱いには注意が必要です。

自分が想定している用途としては Main Repo に PR を scaffold するなどの用途です。
tfaction で提供しているような機能ですね。

https://suzuki-shunsuke.github.io/tfaction/docs/feature/scaffold-working-dir

その場合、 Main Repo の feature branch に commit を push できるだけの権限だけに制限すれば安心でしょう。 PR を open まですると PR を作った人が自分で approve して merge 出来てしまったりするので、 feature branch を作成するだけに留めておくと良いでしょう。

GitHub Actions の提供

gha-trigger で実行した Workflow では通常の Workflow の処理に加え、幾つかの定型的な処理が必要になります。
例えば commit status を更新したり、 Main Repo にアクセスするために Access Token を発行したりするといったことです。

そういった処理を簡略化するための Action を提供しています。
詳細はドキュメントを読んでください。

https://gha-trigger.github.io/github-actions

How to use

GitHub Repository と GitHub App を作成し、 gha-trigger をデプロイする必要があります。
デプロイ先としては現状 AWS Lambda のみをサポートしていますが、将来的には Google Cloud Function などのサポートも検討しています。 Getting Started も参照してください。

さいごに

以上、 gha-trigger の概要を紹介しました。
詳細は公式ドキュメントを参照してください。

https://gha-trigger.github.io/

Discussion