GitHub Actions ワークフローから不要な `id-token: write` 権限を削除し、oncall-triage を `gh.sh` ラッパーへ移行

anthropics/claude-code

不要になった id-token: write 権限を3つのワークフローから削除し、oncall-triage ワークフローの実装を GitHub MCP サーバー経由から gh.sh ラッパースクリプト経由へ移行した。権限の最小化とプロンプト管理の整理を同時に行うクリーンアップPRである。

背景

id-token: write 権限は #18206 で OIDC 認証のために追加されたが、#18209github_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: gh CLI のラッパー(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/ ディレクトリへと移行する方向性を示している。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
74e98926

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)という「総論→各論→結論」の3部構成が明確に適用されており、非常に分かりやすい構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```yaml:path/to/file.yml)およびGitHubのPR番号リンク([#123](URL))が、ガイドラインに沿って正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

GitHub Actions、OIDC、YAML設定などに関する専門用語を前提としており、対象読者であるエンジニアに適した技術レベルと表現で書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションの構成が適切であり、各段落はトピックセンテンスで始まり、1段落1トピックの原則が守られています。段落の長さも適切で、可読性が高いです。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

ほとんどのコード引用はDiffと一致していますが、「変更前(MCP サーバーセットアップ)」のコードブロックで、Diffに存在する `"run"` 引数が欠落しています。ただし、技術的な理解を大きく妨げるものではありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`id-token: write`, `OIDC`, `GitHub MCP Server`などの技術用語が、PRの文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「`github_token` を渡すとOIDCフローがバイパスされる」という権限削除の理由や、MCPサーバーから`gh.sh`ラッパーへの移行による構造変化の説明は、技術的に正確かつ論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(権限が不要になった経緯、プロンプトの外部ファイル化、トリアージロジックなど)は、PRのDescriptionやDiff内のコードによって裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#28756)、参照されている過去のPR番号(#18206, #18209)など、記事内の数値や固有名詞はすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRのタイトル「Remove unused id-token permission and migrate oncall-triage to gh.sh wrapper」の内容を正確に反映しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事内容はPR情報とDiffに限定されており、バージョンサポート状況やリリース日程など、PRに記載のない外部知識の追記はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「追加された」「不要になった」といった過去の経緯に関する時間表現は、PRの情報と一致しており、正確です。