Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】GitHub Actions Lockfile Guide: How actions.lock Works

2026年11月05日に「Dev.to」が公開したITニュース「GitHub Actions Lockfile Guide: How actions.lock Works」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

GitHub Actionsのロックファイル「actions.lock」が一般提供された。ワークフローが使うアクションとその依存関係を、レビュー済みの特定コミットに固定する。タグ変更などによる予期せぬコード動作やサプライチェーン攻撃を防ぎ、CI/CDのセキュリティを強化する。手動でのピンニングが不要となる。

ITニュース解説

GitHub Actionsは、ソフトウェア開発における継続的インテグレーション(CI)や継続的デリバリー(CD)といった、コードのテストやデプロイなどの自動化を実現するための強力なツールである。しかし、これまではその利便性の裏で、セキュリティ上の潜在的な課題を抱えていた。

その課題とは、GitHub Actionsのワークフロー内で使用される「アクション」と呼ばれる再利用可能なコード部品のバージョン指定方法に起因する。通常、アクションのバージョンはuses: actions/checkout@v4のように「v4」といったタグで指定されることが多い。このタグは、特定のコミット(実際のコードの内容)を指しているのだが、そのタグが指すコミットは後から変更される可能性があるという問題があった。つまり、開発者がプルリクエストをレビューして安全性を確認した時点では問題のないコードをタグが指していたとしても、その後、アクションの所有者や、アカウントを乗っ取った悪意のある第三者が、タグが指すコミットを別の(悪意のある)コードに差し替えることができてしまう。このような変更は、新たなプルリクエストやレビューなしに自動的にワークフローに取り込まれてしまうため、ワークフローが次回実行された際に、意図しない悪意のあるコードが実行されるリスクがあった。これは「サプライチェーン攻撃」(外部から取り込む部品が悪意のあるものにすり替わること)の一種とみなされ、実際に過去に複数のGitHub Actions関連のセキュリティインシデントが発生した事例も報告されている。この問題に対処するため、これまでGitHubは手動でアクションのバージョンを特定のコミットSHA(コードのハッシュ値)で直接固定する方法を推奨してきた。しかし、数多くのワークフローや、さらにアクションが内部で利用する別のアクション(推移的な依存関係)まで含めて手動でコミットSHAを管理するのは非常に手間がかかり、現実的ではないという課題があった。

このセキュリティ上の課題と運用の困難さを解決するために導入されたのが、GitHub Actionsワークフローのロックファイル(.github/workflows/actions.lock)である。このロックファイルの主な目的は、ワークフローで使用されるすべてのアクションとその推移的な依存関係を、開発者がレビューし承認した時点の具体的なコミットSHAに固定することだ。これにより、たとえタグが後から変更されたとしても、ワークフローの実行時にはロックファイルに記録されたコミットSHAのコードが確実に使用されるため、意図しないコードの実行を防ぎ、サプライチェーン攻撃のリスクを大幅に低減できるようになる。

ロックファイルはリポジトリごとに1つ作成され、機械によって自動生成されるファイルであるため、手動で内容を編集すべきではない。ロックファイルには、各アクションの元となったリファレンス(タグやブランチ)、そのリファレンスが指していた正確なコミットSHA、そしてソースリポジトリの固有のオーナーIDとリポジトリIDが記録される。ワークフローが実行される際、GitHub ActionsはこれらのIDを使って、名前が示すリポジトリがロックファイルに記録されたものと同一であることを確認する。一度ワークフローがロックファイルの対象となると、そのワークフローが使用するすべてのアクションはロックファイルに記載されていなければならず、ロックされたコミットのコードが実行される。ただし、再利用可能なワークフロー(jobs.<id>.uses構文で呼び出されるもの)はロックファイルの対象外である点には注意が必要だ。これらのワークフローは引き続き手動でフルコミットSHAを指定する必要がある。また、再利用可能なワークフロー自体の依存関係は、それを呼び出す側のリポジトリではなく、そのワークフローが定義されているリポジトリのロックファイルで管理される。ロックファイルはアクションのコード実行のみを制御し、入力パラメータ、シークレット、またはランナーイメージの設定は対象外である。さらに、同じリポジトリ内のアクションを参照する場合、uses: ./pathの形式はロックできず、uses: $/pathの形式にすることでロック可能となる。

ロックファイルを導入するには、まずGitHub CLIのgh-actions-lock拡張機能をインストールする必要がある。コマンドラインでgh extension install github/gh-actions-lockを実行すればよい。インストール後、リポジトリのルートディレクトリでgh actions-lockコマンドを引数なしで実行すると、.github/workflows/下のすべてのワークフローがスキャンされ、解決可能なアクションがコミットSHAに固定され、ロックファイルが生成される。特定のワークフローのみを対象とする場合は、gh actions-lock .github/workflows/ci.ymlのようにパスを指定する。初めてロックファイルを生成する際は、生成されるロックファイルだけでなく、ワークフローファイル自体に加わる差分も確認することが重要である。ツールはuses: octo-org/deploy-action@v3のような記述をocto-org/deploy-action@v3.1.0のように、より具体的なバージョンに書き換えることがあるためだ。これは、指すコミットSHAは変えずに参照をより明確にするものだが、元の記述を維持したい場合は--no-narrowオプションを使用できる。また、ローカルアクション(uses: ./pathで参照されるもの)がある場合、デフォルトではエラーとなる。これを解決するには、--migrate-local-actionsオプションで参照形式を$/に書き換えるか、--ignore-local-actionsオプションで警告に格下げして無視するかの選択肢がある。GitHubは--migrate-local-actionsを推奨している。なお、現在のところ、GitHub Enterprise Server環境ではこの機能はサポートされていない。

ロックファイルは、すべてのワークフローを一度に導入する必要はなく、リスクの高いワークフローから段階的に導入していくことが可能である。導入後、重要な運用上の注意点として、「Allowed Actions」ポリシーの更新が挙げられる。このポリシーは、ワークフローで利用できるアクションを制限するものだが、ロックファイルが導入されたワークフローに対しては、タグではなくロックされたコミットSHAでチェックが行われるようになるため、ポリシーの内容をワイルドカードやフルコミットSHAに変更する必要がある。新しいワークフローを追加したり、既存のワークフローでアクションの依存関係を変更したりした場合は、定期的にgh actions-lockツールを再実行してロックファイルを最新の状態に保つ必要がある。

アクションのバージョンアップなどで、参照しているタグやブランチが新しいコミットを指すようになった場合、ロックファイルは古いコミットを維持したまま「ref-moved」という警告を出す。この場合、上流の変更内容を確認した上で、gh actions-lock --relockを実行することでロックを更新できる。ただし、過去のコミットが履歴から消えるような履歴の書き換え(強制プッシュなど)があった場合は、--relockでは解決できず、gh actions-lock --accept-movedを使って手動で新しいコミットを受け入れる必要がある。GitHubは--accept-movedを自動化ツールで使用しないよう注意を促している。日常的な更新作業は、Dependabotが支援する。Dependabotがアクションのバージョン更新プルリクエストを作成する際、自動的にロックファイルのエントリも同時に更新してくれるため、ワークフローファイルとロックファイルが乖離する心配がない。ただし、Dependabotはロックファイルがまだないワークフローを新しくオンボードすることはしない。ロックファイルの変更は、他の依存関係の変更と同様に、ワークフローに影響を与える新しいコードの導入を意味するため、その差分は慎重にレビューすべきである。特に、オーナーIDやリポジトリIDの変更は、参照先のリポジトリが変わった可能性を示すため、詳細な調査が求められる。

ロックファイルが適切に機能し、セキュリティ上のメリットを最大限に引き出すためには、その内容が常に検証される必要がある。CI/CDパイプラインにおいて、プルリクエストのたびにgh actions-lock --verifyコマンドを実行し、これを必須チェックとすることが推奨されている。このコマンドは、マージ前にロックファイルの正当性を確認し、ジョブの開始時にも再度検証を行うことで、二重の安全策を提供する。また、開発者がコードをコミットする前にローカルで基本的なチェックを行いたい場合は、gh actions-lock --verify-localをプリコミットフックとして利用できる。これはネットワークアクセスなしで動作し、すべての参照がロックファイルに存在することを確認するが、その内容の信頼性までは検証しないため、CIでの検証と組み合わせるのが理想的である。さらに、GitHub Enterprise Cloudでは、組織やリポジトリの管理者向けに「Require lockfile」というポリシーが用意されており、これを利用することで、ロックファイルの利用を強制できる。このポリシーは、ロックファイルがないワークフローの実行をブロックする。

しかし、ロックファイルは万能ではない。ロックは依存関係の「固定」であり、その「安全性」を保証するものではない。つまり、ロックファイルは、レビュー時に安全と判断したコードがその後も実行され続けることを保証するが、そのコード自体が最初から安全であったかどうかは判断しない。そのため、依存関係をロックする前に、その内容を十分にレビューすることが重要である。また、前述したように、再利用可能なワークフローはロック対象外であること、コンテナイメージはロックされないこと(ただし、SHA256ダイジェストの利用は推奨されている)、そして古いコミットへのロールバックは検出されないことなど、いくつかの制限がある。これらの点を理解し、GITHUB_TOKENの権限を制限したり、ワークフロー変更のレビューを必須にしたりするといった、他のセキュリティ対策と組み合わせて利用することが重要である。

これまで手動でアクションをコミットSHAに固定してきた場合、それは決して誤ったアプローチではなかった。しかし、ロックファイルは、推移的な依存関係もカバーし、ワークフローのYAMLファイルをより読みやすく保ち、ソースリポジトリの識別情報も記録するといった点で、手動SHA固定よりも優れた選択肢となる。そのため、ロックファイルを導入したワークフローでは、ワークフローファイル内の手動SHA固定は不要となる。ただし、ロックファイルがカバーしない再利用可能なワークフローの呼び出しでは、引き続き手動でのフルコミットSHA指定が必要となる。これからGitHub Actionsを使い始めるチームは、最初からロックファイルの導入を検討すべきである。既存のプロジェクトで手動SHA固定が広範囲に適用されている場合は、ロックファイルの導入と並行して徐々に移行を進め、各ワークフローがロックファイルの対象となった時点で手動での固定を削除することができる。

関連コンテンツ

関連IT用語