🔧

[GHA] AppToken は contents:write スコープだけだと workflow files を commit できない

2024/02/15に公開

解決例

Token 生成時に "workflows": "write" スコープを追加すると .github/workflows/*.(yml|yaml) もアクション内で編集して commit できるようになります。

      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
        with:
          app_id: ${{ secrets.gh_app_id }}
          private_key: ${{ secrets.gh_app_private_key }}
          permissions: >-
            {
              "contents": "write",
              "workflows": "write"
            }
          repositories: >-
            [
              "${{ github.event.repository.name }}"
            ]

どういうことか?

tibdex/github-app-token action では GitHub App のインストール時に事前に許可された権限のうち、さらに with.permissions に指定した権限のスコープでトークンが発行されます。これを参照してアクション内部で GitHub App 主体の API 操作を利用できます。

ワークフロー以外のファイルを編集してコミットするだけであれば、Contents スコープの Read and write が許可されていれば GHA 内でファイルの編集からコミットまでを達成できます。

Repository contents, commits, branches, downloads, releases, and merges.

ただし、このスコープのみだと GitHub Actions workflow files を commit できません。エラーが発生します。ワークフロー関連のファイルを編集するなら別途権限が必要になるためです。

私は Contents スコープのみで nllint によって .github/workflows/ 配下のファイルを対象とした編集・コミットをプライベートリポジトリで実施しようとしてエラーを起こしました。

たしかに Org の GitHub App Settings にある Permissions & evnets の Repository permissions を見ると、Workflows という GitHub Action wokflow files を編集するための独立した権限が存在します。

Update GitHub Action workflow files.

ややこしいのは、GitHub Actions ワークフロー自体の権限スコープには workflows が存在しないことです。そのため GitHub Actions ワークフロー自体の権限 $GITHUB_TOKEN を使用する場合にはこの問題は発生しません[1]。ただし、GitHub App Token には Workflows スコープがあります。なので tibdex/github-app-token では指定できますし、このユースケースでは指定しなくてはいけません。この部分がキモで、tibdex/github-app-token アクションの permissions に "workflows": "write" が通用すると思わない方もいるのではないか、と思ったのがこの記事を書いた背景です(私がそうでした)。

おわりに

トークン生成時に permissions 引数を入れなければ GitHub App の Org で許可されたすべての権限を持つトークンが発行されます。ただしこれは避けて fine-grained な最小権限でのトークン生成をするべきでしょう。そのためには contentsworkflows の二つの権限を理解しておく必要があるというお話でした。

脚注
  1. ではなぜ GitHub Acitons ワークフロー自体のトークンを使わないかというと、GitHub Actions ワークフロー主体の Commit は後続のワークフローがそのイベントに反応して動いてくれないためです。このため GitHub App のトークンを使いたくなる場面が多々あります。 ↩︎

Discussion