GitHub Actions ワークフローから不要な `id-token: write` 権限を削除し、oncall-triage を `gh.sh` ラッパーへ移行
不要になった id-token: write 権限を3つのワークフローから削除し、oncall-triage ワークフローの実装を GitHub MCP サーバー経由から gh.sh ラッパースクリプト経由へ移行した。権限の最小化とプロンプト管理の整理を同時に行うクリーンアップPRである。
背景
id-token: write 権限は #18206 で OIDC 認証のために追加されたが、#18209 で github_token 入力が追加されたことで不要になった。github_token を明示的に渡す方式では OIDC フローを経由しないため、id-token: write は実質的に死んだ権限として残り続けていた。
この経緯は、セキュリティ上の問題というよりも「使われていない権限が宣言されたままになる」コードの腐敗を示している。ワークフローに宣言された権限は最小権限の原則に照らして定期的に見直す必要があり、本PRはその整理にあたる。
技術的な変更
id-token: write 権限の削除
対象は3つのワークフローで、いずれも permissions ブロックから1行を削除するだけの変更である。
変更対象ファイル:
.github/workflows/claude-dedupe-issues.yml.github/workflows/claude-issue-triage.yml.github/workflows/oncall-triage.yml
各ワークフローの変更は以下のような1行削除のみであり、動作への影響はない:
permissions:
contents: read
issues: write
- id-token: write
oncall-triage ワークフローの MCP サーバー撤廃
oncall-triage.yml では権限削除に加え、GitHub MCP サーバー(ghcr.io/github/github-mcp-server)を用いた Docker ベースのセットアップが丸ごと削除された。変更前は Setup GitHub MCP Server ステップで mcp-servers.json を動的生成してコンテナを起動していたが、変更後はその84行分が消え、GH_REPO 環境変数の追加と /oncall-triage-ci コマンドへの参照に置き換えられた。
変更前(MCP サーバーセットアップ):
- name: Setup GitHub MCP Server
run: |
mkdir -p /tmp/mcp-config
cat > /tmp/mcp-config/mcp-servers.json << 'EOF'
{
"mcpServers": {
"github": {
"command": "docker",
"args": ["-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server:sha-7aced2b"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ secrets.GITHUB_TOKEN }}"
}
}
}
}
EOF
- name: Run Claude Code for Oncall Triage
uses: anthropics/claude-code-action@v1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: |
You're an oncall triage assistant...
Repository: ${{ github.repository }}
...(長大なプロンプト)...
変更後:
- name: Run Claude Code for Oncall Triage
uses: anthropics/claude-code-action@v1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "*"
プロンプトはワークフロー内のインラインテキストから消え、新設された .claude/commands/oncall-triage-ci.md に抽出されている。
/oncall-triage-ci コマンドの追加
新設された .claude/commands/oncall-triage-ci.md は、フロントマターで利用可能ツールを宣言し、トリアージ手順を記述するコマンドファイルである。
---
allowed-tools: Bash(./scripts/gh.sh:*), Bash(./scripts/edit-issue-labels.sh:*), TodoWrite
description: Triage GitHub issues for oncall attention (CI workflow version)
---
許可ツールは以下の3つに限定されている:
-
./scripts/gh.sh:ghCLI のラッパー(issue 一覧・詳細取得・検索) -
./scripts/edit-issue-labels.sh: issue へのラベル追加 -
TodoWrite: 進行中のタスクリスト管理
トリアージロジックは、過去3日間に更新された issue を対象に「バグラベルまたはバグ記述」「50エンゲージメント以上」「コア機能を真にブロックするか否か」の3条件で oncall ラベルを付与するものである。コメント投稿は明示的に禁止されており、ラベル操作のみが許可された操作となっている。
設計判断
GitHub MCP サーバーではなく gh.sh ラッパーを採用する方針 が本PRで示された。MCP サーバー方式は Docker の起動・コンテナ管理・JSON 設定ファイルの動的生成など多くの間接層を必要とするが、gh.sh ラッパーはリポジトリに存在するシェルスクリプトを直接呼び出すだけで動作する。
allowed-tools をコマンドファイルのフロントマターで宣言する方式は、ワークフロー YAML にプロンプトと権限を混在させていた旧構造と対照的に、許可スコープをコマンド単位で明示的に管理できる。これはプロンプトファイルをバージョン管理しながらツール許可範囲も一元化できる設計であり、今後のコマンド追加・変更がワークフロー YAML に触れずに完結する。
また、GH_REPO を環境変数として渡す方式を採ったことで、プロンプト内に ${{ github.repository }} をインライン展開する必要がなくなっている。コマンドファイルは $ARGUMENTS 経由でパラメータを受け取る汎用的な設計となっており、CI ワークフロー以外の文脈でも再利用可能な形になっている。
まとめ
本PRは、過去のPR連鎖で生じた権限の残留を整理しつつ、インラインプロンプト+MCP サーバーという複雑な構成を gh.sh ラッパー+コマンドファイルという軽量な構成へ置き換えた変更である。ツール許可のコマンドファイル化という判断は、Claude Code を使った CI 自動化の管理単位をワークフロー YAML から .claude/commands/ ディレクトリへと移行する方向性を示している。