🐧

Securefix Action で別リポジトリ、別ブランチに commit と PR 作成

に公開

GitHub Actions で Client/Server Model によってセキュアにコードを修正する Action である Securefix Action を開発しています。

https://zenn.dev/shunsuke_suzuki/articles/securefix-action

先日リリースした v0.2.0 に含まれる非常に重要な機能を紹介します。

  • 修正対象に hidden ファイルが含まれていると失敗する不具合を修正しました
  • 修正対象のファイルを指定できるようになりました
    • デフォルトでは変更された全ファイルが対象ですが、対象を絞ることができるようになりました
  • commit の push 先の repository, branch を指定できるようになりました
    • server 側で許可した repository, branch にしか push できないため、 security を担保することができます
      • 不用意に許可すると secure ではなくなってしまうので、注意が必要です
  • pull request を作成できるようになりました
    • server 側で許可した repository, branch, 及び base branch にしか作成できません
  • ghcp を JavaScript で置き換えることで高速化、 API call 数の削減

従来 Securefix Action では Client Action を実行した branch の修正のみに対応していました。
しかし、別のリポジトリやブランチに push したいケースはままあります。

  • GitHub Actions で PR を作成したい
    • tfaction の scaffold PR や follow up PR
  • GitHub Pages の更新
    • default branch が修正されたら gh-pages branch も更新
    • 別の repsository に push したいケースもある
  • あるリポジトリのコードが修正されたら別のリポジトリのコードも自動で修正したい

しかし、こういったケースに対応するために任意の workflow が任意の repository や branch に push できるようにしてしまったら、それはいくらでも悪用できてしまい、 Securefix Action の意味がなくなってしまいます。
そこで Server 側で client repository や branch 及び push 先の repository や branch を制限しつつ許可するようにしました。

例えば、 server 側で以下のような設定をします。

  • suzuki-shunsuke/tfaction-example の main branch から scaffold-working-directory-*/** または follow-up-*/** branch への push を許可
    • main branch への PR 作成も許可
  • suzuki-shunsuke/tfaction の main branch から suzuki-shunsuke/tfaction-docs の gh-pages branch への push を許可
entries:
  - client:
      repositories:
        - suzuki-shunsuke/tfaction-example
      branches:
        - main
    push:
      repositories:
        - suzuki-shunsuke/tfaction-example
      branches:
        - "scaffold-working-directory-*/**" # Glob
        - "follow-up-*/**" # Glob
    pull_request:
      base_branches:
        - main
  - client:
      repositories:
        - suzuki-shunsuke/tfaction
      branches:
        - main
    push:
      repositories:
        - suzuki-shunsuke/tfaction-docs
      branches:
        - gh-pages

この設定で明示的に許可されていないリクエストは全部拒否します。
push 先の branch 指定には glob が使えますが、それ以外は完全一致です。
client, push の条件にマッチする entry が一つもなければリクエストは拒否されます。

なお、これは push 先を変更する場合に必要な設定であり、変更しない場合は特に設定で明示的に許可する必要はありません。

次に Client 側でパラメータを指定します。

- uses: csm-actions/securefix-action@latest
  with:
    app_id: ${{ vars.APP_ID }}
    app_private_key: ${{ secrets.APP_PRIVATE_KEY }}
    server_repository: securefix-demo-server
    # push 先を変える場合は repository と branch を指定
    repository: suzuki-shunsuke/tfaction-example
    branch: scaffold-working-directory-foo
    # PR を作る場合は title と base branch が必須
    pull_request_title: Scaffold foo
    pull_request_base_branch: main
    # 以下は任意
    pull_request_body: Pull Request Description
    pull_request_draft: true
    pull_request_labels: |
      document
      enhancement
    pull_request_reviewers: |
      suzuki-shunsuke
    pull_request_team_reviewers: |
      sre
    pull_request_assignees: |
      suzuki-shunsuke
    pull_request_comment: Hello, @suzuki-shunsuke

Pull Request を作らない場合は pull_request_* は不要です。
また、 push 先を変えない場合は従来通り repositorybranch も不要です。

pull_request_comment を指定すると PR を作ったあとに作成した PR にコメントをすることができます。
PR 作成後にメンション付きのコメントをして通知を飛ばすのに便利です。

どういった repository, branch なら許可してよいか

先述の通り、 push 先を変更する場合は設定で許可する必要がありますが、許可する際にはセキュリティ的に注意が必要です。
基本的に push を要求する client 側の repository, branch は、変更時に codeowner の pull request review が必須になっているような信頼性の高い branch (多くの場合は default brach) であるべきです。
また、 validate-pr-review-action を活用して pull request review の bypass を防ぐのも有効です。

https://zenn.dev/shunsuke_suzuki/articles/validate-pr-review-action

tfaction も Securefix Action に対応

自分は GitHub Actions で高度な Terraform Workflow を実現するための OSS である tfaction を開発しています。

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

tfaction では様々なコードの生成や修正、 PR の生成に対応しています。
tfaction v1.18.0 よりこれらの commit や PR の生成に Securefix Action を使えるようになりました
これにより、 contents:write 権限を持った GitHub access token 及び GitHub App を feature branch から自由に使えるようにする必要がなくなり、セキュリティを高めることができます。

CI でセキュアにコードを修正するためのツールが揃ってきた

今回のリリースにより、 GitHub Actions で contents:write が必要な多くのケースをカバーできたと思います。
GitHub Actions でセキュアに update branch したいばあいは csm-actions/update-branch-action が使えますし、 Machine User で secure に auto approve したい場合は csm-actions/approve-pr-action が使えます。
他人のレビューなしで PR をマージするのを防ぐには validate-pr-review-action が使えます。
validate-pr-review-action の input trusted_apps に Securefix Action の Server 側の App を追加することで、他の App の悪用を防ぎつつ CI でセキュアにコードの修正や PR の作成を行えます。
これらのツールが揃ったことにより、 GitHub Actions でセキュアにコードの修正・生成を行えるようになりました。

Discussion