GitHubは2026年9月10日、GitHub Actionsのキャッシュ権限をワークフローまたはジョブ単位で制限できるcache-modeを全プランで一般提供しました。

新しい設定値はreadwritewrite-onlynoneの4種類です。信頼度の低いPull Requestでは読み取り専用にし、成果物を作る信頼済みジョブだけに書き込みを許可できます。

狙いは速度ではなく、CI/CDのキャッシュを経由したサプライチェーン攻撃の範囲を狭めることです。既存ワークフローは安全な既定値で動き続けますが、明示設定により意図をレビュー可能にできます。

SUPPLY CHAIN SECURITY

CIキャッシュにも最小権限を適用する

read復元のみ
write復元+保存
write-only保存のみ
none完全無効

背景:キャッシュは「速くする箱」であると同時に入力でもある

GitHub Actionsのキャッシュには、依存パッケージ、コンパイル結果、ツールの中間ファイルなどが保存されます。後続の実行は同じキーの内容を復元するため、ビルド時間と通信量を減らせます。

一方、信頼度の低いジョブが共有キャッシュへ書き込めると、改変したバイナリや依存物を保存し、後から実行される信頼済みジョブへ読み込ませる余地が生まれます。これがキャッシュ汚染(cache poisoning)です。秘密情報を持つリリース処理やデプロイ処理が汚染済み成果物を使えば、影響はPull Requestの検証範囲を超えます。

cache-modeは、キャッシュサービス側で復元と保存の権限を分離します。YAML上の慣習ではなく、サービスにより強制される点が重要です。

4つのモードの使い分け

モード復元保存推奨場面
read不可外部Pull Request、検証専用ジョブ
write保護ブランチへのpush、信頼済みビルド
write-only不可既存キャッシュを信用せず新規生成するジョブ
none不可不可秘密情報を扱う署名・公開・高リスク処理

ジョブ単位の指定はワークフロー単位を上書きします。再利用ワークフローへも権限上限が引き継がれ、呼び出された側は呼び出し元より強いキャッシュ権限を受け取れません。

既定値と注意すべきイベント

GitHubの公式発表では、pull_request_targetのような低信頼イベントはreadpushのような信頼済みイベントはwriteが既定です。設定を追加していない既存ワークフローも、この安全な既定値を利用します。

ただし、明示したcache-modeは既定値を上書きします。低信頼イベントへwriteまたはwrite-onlyを与えると、GitHub Actionsは警告アノテーションを表示します。警告が出る設定を正当化できない場合は、権限を戻すべきです。

設定例

次はワークフロー全体を読み取り専用にし、信頼済みのpushジョブだけ書き込み可能にする考え方です。実際の構文は利用中のGitHub Actions仕様を確認してください。

name: test-and-build

cache-mode: read

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

  trusted-build:
    if: github.event_name == 'push'
    cache-mode: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

機密度の高い署名ジョブでは、速度より分離を優先してnoneを検討します。依存物を必ず新規取得し、検証済み成果物だけをArtifact Attestationsなどの来歴情報とともに渡す設計が向きます。

導入手順

1|棚卸し

キャッシュを復元・保存する全ジョブと再利用ワークフローを列挙。

2|信頼境界

外部PR、bot、fork、push、releaseを分類。

3|最小化

原則read。保存が必要なジョブだけwriteへ。

4|監視

警告、ヒット率、実行時間、失敗率を比較。

最初に組織内の共通ワークフローへ設定すると、多数のリポジトリへ一貫した上限を配布できます。ただし、呼び出し元のイベントと権限を再利用ワークフロー側だけで推測しないことが重要です。

キャッシュ汚染対策を一段強くする

cache-modeだけでサプライチェーン攻撃を防げるわけではありません。次の対策と組み合わせます。

  • ActionsをコミットSHAで固定し、タグの差し替えリスクを減らす。
  • pull_request_targetでPull Request側のコードを実行しない。
  • GITHUB_TOKENとOIDCクラウド権限をジョブ単位で最小化する。
  • 保護Environmentでデプロイ承認を要求する。
  • 依存ロックファイルとチェックサムを検証する。
  • 生成物にArtifact Attestationsを付与し、出所を検証する。

GitHubは同じ週に、Pull Requestが新しいSecret Scanningアラートを導入した場合、マージをブロックするrulesetも公開プレビューとして追加しました。キャッシュ権限は成果物経路、Secret Scanningは資格情報経路を守るため、両方を使うと防御範囲が広がります。

開発者・企業への影響

開発者にとっては、Pull Requestのテスト速度を維持しながら、共有キャッシュへの書き込みだけを止められます。従来の「キャッシュを使う/使わない」という二択より移行しやすい設計です。

企業では、監査時に「どのイベントがキャッシュを書けるか」をYAMLで確認できます。特に、OSSのfork、外部委託、依存更新botを受け入れるリポジトリで有効です。

編集上の推論として、今後のCI権限はトークンだけでなく、キャッシュ、成果物、ログ、モデル、ランナーなど共有状態ごとの能力として分割されていくと考えられます。

リスクと限界

  1. readでも、すでに汚染されたキャッシュを読む危険は残る。
  2. キャッシュキーが粗いと、異なるブランチや用途の成果物が共有される。
  3. セルフホストランナーの作業ディレクトリやDockerレイヤーは別の共有状態である。
  4. noneを増やすと通信量とビルド時間が増えるため、実測が必要。
  5. 低信頼イベントで明示的にwriteを設定すると安全な既定値を弱める。

今後注目すべき点

導入後は、キャッシュヒット率、ジョブ時間、保存回数、イベント種別ごとの警告を追跡します。組織rulesetと同様に、キャッシュ権限を組織全体で強制・監査する機能がどこまで拡張されるかも注目です。

まず外部Pull Requestをread、署名・公開をnoneへ固定し、信頼済みmainビルドだけにwriteを与える構成から始めると安全です。

参照元

最終確認日:2026年9月14日

Previous Post Next Post