ワークフローのYAMLにuses: actions/checkout@v4と書くとき、「v4」が指す先はいつまでも同じだと思っていないだろうか。実はそうとは限らない。v4はただの名札で、名札をつけ直せば、同じ@v4という表記のまま別のコードが動くようになる。GitHubが2026年10月14日、この名札のつけ直しに左右されない仕組みを公開した(GitHub Changelog)。名前は「ワークフロー依存関係ロックファイル」、位置づけはpublic previewだ。ワークフローの表記は変えずに、実行されるコードだけを特定の1つのコミットへ固定できるという。
タグが指す先はあとから変わる
GitHub Actionsのuses:に書く@v4や@mainは、Gitのタグやブランチの名前だ。名前はラベルであって、コードそのものではない。タグが指すコミットは、タグを付け直せば変わる。これはGitの仕様であり、不具合ではない。
この性質が実際に悪用された例がある。2025年3月、Action「tj-actions/changed-files」で何者かがリポジトリへの書き込み権限を使い、悪意のあるコードを仕込んだ。このActionは約23,000リポジトリが使っていた。
米国土安全保障省傘下のCISA(サイバーセキュリティ・インフラストラクチャセキュリティ庁)によると、影響期間は2025年3月12日から15日までだった(CISAアラート)。この間にワークフローを実行すると、実行ログへアクセスキーやGitHub個人アクセストークン、npmトークン、RSA秘密鍵などのシークレットが書き出された。CVE番号はCVE-2025-30066で、CISAは既知の悪用された脆弱性のカタログに追加している。
セキュリティ企業Snykの分析によると、この侵害では既存のバージョンタグが削除された(Snykのブログ)。そのタグは、ブランチから切り離された悪意のあるコミットへ向け直されたという。タグをそのまま信用していたワークフローは、ソースコードを一切変更していないのに、ある日から違うコードを実行することになった。この書き換えの具体的な手順はSnyk自身が攻撃を再現した検証に基づくもので、攻撃者が実際に行った操作そのものの記録ではない。それでも、タグが動かせるという性質自体は変わらない。
自分でコミットのSHAを直接書く「SHA直書きピン留め」は、以前から推奨されてきた対策だ。@v4の代わりに@a1b2c3...のような40桁の値を書けば、その1行は固定できる。
ただし、この1行で固定できるのは、ワークフローが直接呼ぶActionだけだ。呼び出したActionがさらに別のActionを呼ぶことがある。この、依存先の依存先までを指す関係を「推移的依存関係」と呼ぶ。再利用可能ワークフローが抱える依存関係も同様で、ワークフローファイルに1行書くだけでは固定できない。
ロックファイルは何を固定するのか
ここで理解が要るのは、ロックファイルが「ワークフローファイルの表記を書き換える仕組み」ではないという点だ。@v4という表記はそのまま残る。固定されるのは、その裏で実際に実行されるコミットのほうだ。表記と実行内容が別の場所に分かれている。
丸は、1番古いコミットから5番目(最新)までを順に並べた、説明用の仮の鎖だ。実在のコミットハッシュではない。上段のようにタグだけで参照していると、v4という名札が指す位置は、鎖の3番目(実線)から5番目(破線)へと動かせてしまう。下段のロックファイルでは、v4という表記自体は変わらないが、実行されるコミットは最初に記録した3番目(塗りつぶした丸)に固定され続ける。名札の表記を書き換える必要はない(GitHub Changelog)。
GitHub公式ドキュメントによると、ロックファイルの置き場所は.github/workflows/actions.lockだ。生成にはGitHub CLIの拡張機能gh actions-lockを使う。
ロックファイルが記録する項目は次のとおりだ。
| 項目 | 内容 |
|---|---|
ref | ワークフローが書いている参照(タグやブランチの名前) |
commit | その参照が解決された、実際に実行されるコミット |
owner_id / repo_id | 参照先リポジトリの数値ID。実行時に、名前の背後にあるリポジトリがロック時と同じかを確認する |
owner_idとrepo_idを記録しているのは、タグの付け替えだけでなく、リポジトリ名の乗っ取りのような別の手口まで見ているからだ。固定する対象も広い。ワークフローが直接呼ぶActionだけでなく、そのActionがさらに呼ぶ依存関係(推移的依存関係)、再利用可能ワークフローの依存関係にまで及ぶ。ここはSHA直書きのピン留めでは手が届かなかった範囲だ。
公式ドキュメントを読むまで、自分はこの機能を「SHA直書きへの書き換えを促す仕組み」だと思い込んでいた。実際には逆だった。ロックファイルを導入したリポジトリでは、ワークフローファイル内のSHA直書きピン留めはもう必要ないと明記されている。可読性(@v4のままにする)と固定(実行は別記録のコミットにする)を両立させる設計だった。
導入の手順とDependabotとの連携
導入は1つのリポジトリのワークフロー単位で、段階的に進められる。gh-actions-lock公式リポジトリのREADMEが示す手順は次のとおりだ。
gh extension install github/gh-actions-lockでGitHub CLIの拡張機能を入れる- リポジトリのチェックアウトで
gh actions-lockを実行する。.github/workflows/配下のワークフローをスキャンし、解決できる依存関係をコミットへ固定したactions.lockを生成・更新する - 生成された
actions.lockとワークフローの差分をレビューし、コミットする
一度オンボーディングしたワークフローは、使うすべての依存関係がロックファイルに載っている必要がある。エラーが1つでも残ると、どのワークフローのロックエントリも変更されない「全か無か」の仕組みになっている。タグが後から動いても現在のロックを信じていいのかは、gh actions-lock --verifyで確認できる。これは書き込みを行わない検証用のコマンドで、タグやメジャー版で固定されたコミットが、そのref自身の履歴の中に今も存在しているかまで確かめる。
Dependabotとの連携も用意されている。オンボーディング済みのワークフローでDependabotがActionのバージョン更新PRを作ると、同じPRの中でロックファイルのエントリも合わせて再生成される。追加の設定はいらない。
いま使う上で知っておくこと
この機能はpublic previewで、仕様は変わりうる。公式ドキュメントは、ロックファイルを採用しても「依存関係が安全であることは保証されない」と明記している。固定できるのは「どのコミットが実行されるか」までで、そのコミットの中身が安全かどうかは、ロックする前に自分でレビューする必要がある。
対応プランはGitHub Enterprise Cloud(データレジデンシー利用を含む)・Team・Freeの3つだ。GitHub Enterprise Server(GHES)は対象外になる。ローカルパスを使うActionもロックファイルへの登録対象外で、READMEはこれを「短期的な制約」と書いている。
組織やリポジトリの管理者がロックファイルの使用を要求できる「Require lockfile」ポリシーも、previewとして用意されている。ただし設定画面や具体的な適用条件はChangelogに名前が出ているだけだ。公式ドキュメントにはまだ記載がない。
まとめ
@v4のようなタグは、それ自体が動かせる名札だ。2025年には実際にその性質が悪用され、約23,000リポジトリが使うActionに影響が及んだ。2026年10月14日に公開されたロックファイルは、ワークフローの表記を変えずに、実行されるコードを1つのコミットへ固定する。固定の範囲は、直接の依存関係から推移的な依存関係・再利用可能ワークフローまで及ぶ。
導入はgh actions-lockでワークフロー単位から始められ、Dependabotの更新PRにもロックファイルの再生成が追従する。public previewのため仕様は変わりうる。ロックしてもコードの安全性そのものは保証されない点だけは、導入前のレビューとして覚えておく必要がある。
コメント
気づきや感想をどうぞ記事への補足や、読んで考えたことをお寄せください。個人情報や、他の人を傷つける内容の投稿はお控えください。
投稿にはGoogleログインが必要です。
Googleでログイン投稿にはGoogleアカウントの表示名が公開されます。メールアドレスは取得・公開しません。
コメントを読み込んでいます…