GitHub ActionsでPATを絶対使いたくないマンです。GitHub Appのインストールアクセストークンも使いたくなかったのですが、PATより100倍マシなので最近はこれを使うようにしています。 今回は、GitHub Actionsにおけるアクセストークンを整理し、GitHub Appのインストールアクセストークンを使う方法を説明します。
PATの問題
GitHub ActionsからGitHub APIを叩くときに使うアクセストークンには、3つの選択肢があります。
- GITHUB_TOKEN
- アクションごとに自動生成されるアクセストークン
- PAT (Personal Access Token)
- ユーザー単位で手動生成する2種類のアクセストークン
Fine-grained personal access tokenPersonal access token (classic)1
- GitHub App Installation Access Token
- GitHub Appを使って適宜生成するアクセストークン
通常はGITHUB_TOKENを使うのがベストプラクティスですが、これには次の制約があります。
- 他のリポジトリにアクセスできない
- PRやPushに用いたとき、ワークフローがトリガーされない
- ブランチプロティションルールの除外ルールに設定できない
- Issueに
@Copilotをアサインできない2
上記制約はPATで回避できますが、PATには次のような問題があり扱いに困ります。個人リポジトリならともかく、組織リポジトリでPATを使うのは避けたいところです。
- トークン発行が個人単位3
- ブランチプロテクションの除外ルールが発行者を対象
- トークン発行者として処理が実行される4
- トークンの期限が長く漏洩時のリスクが高い
- トークンの対象リポジトリ・権限が発行/編集時に固定される
GitHub Appによる解決と使い分け
GitHub AppのインストールアクセストークンはPATの問題を解決します。ただし、CopilotのアサインにはPATが必要なのでそこは注意してください。
| PAT | GitHub App |
|---|---|
| トークン発行が個人単位 | トークン発行がGitHub App単位で個人に依存しない |
| ブランチプロテクションの除外ルールが発行者を対象 | ブランチプロテクションの除外ルールにGitHub Appを指定できる |
| トークン発行者として処理が実行される | GitHub Appとして処理が実行できる |
| トークンの期限が長く漏洩時のリスクが高い | トークンがアクションの実行事に発行、アクション終了で無効化される |
| トークンの対象リポジトリ・権限が発行/編集時に固定される | トークンの対象リポジトリ・権限をGitHub App、組織承認の2段階で管理できる |
GitHub Appの用意とアクセストークン発行処理は面倒ですが、PATを使うよりは遥かにマシです。以上を踏まえて、私はGitHub ActionsでGitHub APIを叩くときは次の基準で使い分けています。
- 他リポジトリにアクセスしたいなら
GitHub App - ブランチプロテクションルールを回避したいなら
GitHub App - IssueにCopilotをアサインしたいなら
PAT - 上記に該当しないケースは
GITHUB_TOKENGitHub Appを用意できない場合はPAT
フローチャートにすると以下のようになります。
クリックでmermaidを表示
flowchart TD
GITHUB_TOKEN["GITHUB_TOKEN"]
GITHUB_APP["GitHub App Installation Access Token"]
PAT["Personal Access Token (PAT)"]
START["GitHub操作を行う"]
A{GitHub Appを用意できる?}
START -->D{他リポジトリにアクセスする?}
D -- Yes --> A
D -- No --> E{ブランチプロテクションルールを回避する?}
E -- Yes --> A
E -- No --> F{IssueにCopilotをアサインする?}
F -- Yes --> PAT
F -- No --> GITHUB_TOKEN
A -- Yes --> GITHUB_APP
A -- No --> PAT

それでは、GitHub Appのインストールアクセストークンを使う方法を見てみましょう。
GitHub Appを使う
GitHub Appを使うには、以下の手順を踏みます。
- GitHub Appを用意する
- GitHub Appをインストールする
- GitHub Appの情報をSecretsに登録する
- GitHub Actionsでインストールアクセストークンを取得する
GitHub Appを用意する
GitHub Appを用意します。Organization単位で作成する場合は、Organization > Settings > Developer settings > GitHub Apps > New GitHub App から作成します。個人で作成する場合は、個人アカウントのSettings > Developer settings > GitHub Apps > New GitHub Appから作成します。
GitHub Appの名前、説明、Homepage URLなどを設定します。Webhookは不要なのでチェックを外します。
Homepage URLはアプリページに表示されるので、localhostやHP、GitHubプロフィールURLなどが安全でしょう。Where can this GitHub App be installed?は、外部に利用させたくないならOnly on this accountやOnly on this organizationにします。

重要なのがPermissionsです。ここでGitHub Appに与える権限を設定します。必要最低限の権限だけ与えつつ、Actionsで必要になる権限は付与しておく必要があります。たとえば、PRの情報を取得したいならPull requests: Read-onlyが必要ですが、PRの作成や更新をしたいならPull requests: Read and writeが必要です。また、git cloneしたいならContents: Read-only、git pushしたいならContents: Read and writeが必要です。

GitHub Appをインストールする
GitHub Appを対象のリポジトリや組織にインストールします。Organization単位でインストールする場合は、Organizationのオーナー権限が必要です。
インストールすると対象のリポジトリを選択できるので、ここで必要なリポジトリに絞り込むとよいでしょう。全部のリポジトリ、あるいはパブリックリポジトリ全部にしていると影響範囲を把握しづらくなります。

インストール後にGitHub Appの権限を変更した場合、組織のオーナーは変更を承認するか選択できます。
インストールしたアプリを削除もできます。

GitHub Appの情報をSecretsに登録する
GitHub AppのApp ID、Private Keyを、Organization SecretsやリポジトリSecretsに登録します。
以下はダミーのGitHub App情報5ですが、ここにあるApp IDを控えます。

Private KeyはGitHub App作成時点ではまだありません。GitHub App作成後、下にスクロールするとPrivate Keyがあるので、Generate a private keyボタンを押して秘密鍵を生成します。

Private Keyを生成すると自動的にダウンロードされます。秘密鍵の中身をSecretsに登録したらpemファイルは消しましょう。秘密鍵はすぐ消すに限ります。


これらを、GitHub Secretsに登録します。
ACTIONS_BOT_APPID: 上のAPP ID ACTIONS_BOT_PRIVATE_KEY: 上のPrivate Keyの中身
GitHub Actionsでインストールアクセストークンを取得する
GitHub ActionsのワークフローでGitHub Appのインストールアクセストークンを取得しましょう。幸い、GitHub公式のアクションactions/create-github-app-tokenがあります。以前はサードパーティ製アクションを使う必要がありましたが、公式アクションができたのでこれを使いましょう。
以下はサンプルワークフローです。GitHub Appのトークンを使ったか検証するため、ジョブにはpull requestの権限を与えず、GitHub Appのインストールアクセストークンを取得するときにpull-requestのread権限を与えています。PR一覧が取得できれば成功です。
actions/create-github-app-tokenで取得したトークンは、ステップアウトプットsteps.{id}.outputs.tokenで参照できます。例ではactions/create-github-app-tokenのidをapp-tokenにしているので、steps.app-token.outputs.tokenです。
name: github app token on: pull_request: branches: [main] push: branches: [main] workflow_dispatch: jobs: app-token: permissions: contents: read # no pull request permission runs-on: ubuntu-24.04 timeout-minutes: 3 steps: - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 id: app-token with: app-id: ${{ secrets.ACTIONS_BOT_APPID }} private-key: ${{ secrets.ACTIONS_BOT_PRIVATE_KEY }} permission-pull-requests: read # grant read access to pull requests - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: List open PRs run: gh pr list --state open --limit 5 env: GH_TOKEN: ${{ steps.app-token.outputs.token }} # GitHub App token permission to read pull requests GH_REPO: ${{ github.repository }}
ワークフローを実行すると、GitHub Appのインストールアクセストークンが発行され、ghコマンドでPR一覧を取得できます。

TIPS: create-GitHub-app-tokenのコツ
GitHub Appのインストールアクセストークンを取得するコツです。
- permissions-
<resource>で必要な権限だけ与える
この時取得できる権限は、GitHub Appへ与えられた権限に限られます。Appに与えられていない権限は取得できません。
# pushが必要ならpermission-contents: writeを与える - uses: actions/create-github-app-token@v2 id: app-token with: app-id: ${{ secrets.ACTIONS_BOT_APPID }} private-key: ${{ secrets.ACTIONS_BOT_PRIVATE_KEY }} permission-contents: write
- 他のリポジトリにアクセスする場合は
ownerとrepositoriesを指定する
# ownerとrepositoriesを指定して他リポジトリにアクセスする - uses: actions/create-github-app-token@v2 id: app-token with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.PRIVATE_KEY }} owner: ${{ github.repository_owner }} repositories: | repo1 repo2
まとめ
GitHub Appを用いると、ごく限定的なケースを除いてPATを排除できます。たとえマシンユーザーがあったとしても、PATよりはGitHub Appのほうが細かく管理できるので好ましいでしょう。
まずはGITHUB_TOKENでできるか検討して、どうしても無理な場合にGitHub Appを用意するのがおすすめです。
やってみると簡単です。ただ、GitHub App用のアクセストークンを取得するのに1ステップ増えるのは度々面倒に感じます。PATのリスクを軽減できている、と考えて我慢です。
参考
- actions/create-github-app-token | GitHub
- Making authenticated API requests with a GitHub App in a GitHub Actions workflow - GitHub Docs
- Managing your personal access tokens - GitHub Docs
- Use GITHUB_TOKEN for authentication in workflows - GitHub Docs
- Authenticating as a GitHub App installation - GitHub Docs



























